Browse Source

Merge branch 'dev' into add-typescript-for-jsm

Nathan Bierema 6 years ago
parent
commit
0eac0744b7

+ 3 - 3
build/three.js

@@ -20215,7 +20215,7 @@
 
 					console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
 
-					return useOffscreenCanvas ? canvas.transferToImageBitmap() : canvas;
+					return canvas;
 
 				} else {
 
@@ -34668,7 +34668,7 @@
 
 		},
 
-		parse: function ( json, onLoad ) {
+		parse: function ( json ) {
 
 			var animations = [];
 
@@ -34680,7 +34680,7 @@
 
 			}
 
-			onLoad( animations );
+			return animations;
 
 		},
 

+ 109 - 109
build/three.min.js

@@ -9,21 +9,21 @@ Array.isArray(e)?b[c][d]=e.slice():b[c][d]=e}}return b}function xa(a){for(var b=
 c){var d=b.array,e=b.dynamic?35048:35044,h=a.createBuffer();a.bindBuffer(c,h);a.bufferData(c,d,e);b.onUploadCallback();c=5126;d instanceof Float32Array?c=5126:d instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):d instanceof Uint16Array?c=5123:d instanceof Int16Array?c=5122:d instanceof Uint32Array?c=5125:d instanceof Int32Array?c=5124:d instanceof Int8Array?c=5120:d instanceof Uint8Array&&(c=5121);return{buffer:h,type:c,bytesPerElement:d.BYTES_PER_ELEMENT,
 version:b.version}}var c=new WeakMap;return{get:function(a){a.isInterleavedBufferAttribute&&(a=a.data);return c.get(a)},remove:function(b){b.isInterleavedBufferAttribute&&(b=b.data);var d=c.get(b);d&&(a.deleteBuffer(d.buffer),c.delete(b))},update:function(d,e){d.isInterleavedBufferAttribute&&(d=d.data);var f=c.get(d);if(void 0===f)c.set(d,b(d,e));else if(f.version<d.version){var g=d,h=g.array,k=g.updateRange;a.bindBuffer(e,f.buffer);!1===g.dynamic?a.bufferData(e,h,35044):-1===k.count?a.bufferSubData(e,
 0,h):0===k.count?console.error("THREE.WebGLObjects.updateBuffer: dynamic THREE.BufferAttribute marked as needsUpdate but updateRange.count is 0, ensure you are using set methods or updating manually."):(a.bufferSubData(e,k.offset*h.BYTES_PER_ELEMENT,h.subarray(k.offset,k.offset+k.count)),k.count=-1);f.version=d.version}}}}function Nb(a,b,c,d,e,f){this.a=a;this.b=b;this.c=c;this.normal=d&&d.isVector3?d:new n;this.vertexNormals=Array.isArray(d)?d:[];this.color=e&&e.isColor?e:new K;this.vertexColors=
-Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function ob(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||ob.DefaultOrder}function be(){this.mask=1}function E(){Object.defineProperty(this,"id",{value:Wf++});this.uuid=H.generateUUID();this.name="";this.type="Object3D";this.parent=null;this.children=[];this.up=E.DefaultUp.clone();var a=new n,b=new ob,c=new aa,d=new n(1,1,1);b.onChange(function(){c.setFromEuler(b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});
-Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:a},rotation:{configurable:!0,enumerable:!0,value:b},quaternion:{configurable:!0,enumerable:!0,value:c},scale:{configurable:!0,enumerable:!0,value:d},modelViewMatrix:{value:new J},normalMatrix:{value:new pa}});this.matrix=new J;this.matrixWorld=new J;this.matrixAutoUpdate=E.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.layers=new be;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=
+Array.isArray(e)?e:[];this.materialIndex=void 0!==f?f:0}function ob(a,b,c,d){this._x=a||0;this._y=b||0;this._z=c||0;this._order=d||ob.DefaultOrder}function be(){this.mask=1}function F(){Object.defineProperty(this,"id",{value:Wf++});this.uuid=H.generateUUID();this.name="";this.type="Object3D";this.parent=null;this.children=[];this.up=F.DefaultUp.clone();var a=new n,b=new ob,c=new aa,d=new n(1,1,1);b.onChange(function(){c.setFromEuler(b,!1)});c.onChange(function(){b.setFromQuaternion(c,void 0,!1)});
+Object.defineProperties(this,{position:{configurable:!0,enumerable:!0,value:a},rotation:{configurable:!0,enumerable:!0,value:b},quaternion:{configurable:!0,enumerable:!0,value:c},scale:{configurable:!0,enumerable:!0,value:d},modelViewMatrix:{value:new J},normalMatrix:{value:new pa}});this.matrix=new J;this.matrixWorld=new J;this.matrixAutoUpdate=F.DefaultMatrixAutoUpdate;this.matrixWorldNeedsUpdate=!1;this.layers=new be;this.visible=!0;this.receiveShadow=this.castShadow=!1;this.frustumCulled=!0;this.renderOrder=
 0;this.userData={}}function G(){Object.defineProperty(this,"id",{value:Xf+=2});this.uuid=H.generateUUID();this.name="";this.type="Geometry";this.vertices=[];this.colors=[];this.faces=[];this.faceVertexUvs=[[]];this.morphTargets=[];this.morphNormals=[];this.skinWeights=[];this.skinIndices=[];this.lineDistances=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=this.lineDistancesNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.uvsNeedUpdate=this.verticesNeedUpdate=this.elementsNeedUpdate=
 !1}function P(a,b,c){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.name="";this.array=a;this.itemSize=b;this.count=void 0!==a?a.length/b:0;this.normalized=!0===c;this.dynamic=!1;this.updateRange={offset:0,count:-1};this.version=0}function vc(a,b,c){P.call(this,new Int8Array(a),b,c)}function wc(a,b,c){P.call(this,new Uint8Array(a),b,c)}function xc(a,b,c){P.call(this,new Uint8ClampedArray(a),b,c)}function yc(a,b,c){P.call(this,new Int16Array(a),
-b,c)}function pb(a,b,c){P.call(this,new Uint16Array(a),b,c)}function zc(a,b,c){P.call(this,new Int32Array(a),b,c)}function qb(a,b,c){P.call(this,new Uint32Array(a),b,c)}function F(a,b,c){P.call(this,new Float32Array(a),b,c)}function Ac(a,b,c){P.call(this,new Float64Array(a),b,c)}function Se(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=
+b,c)}function pb(a,b,c){P.call(this,new Uint16Array(a),b,c)}function zc(a,b,c){P.call(this,new Int32Array(a),b,c)}function qb(a,b,c){P.call(this,new Uint32Array(a),b,c)}function E(a,b,c){P.call(this,new Float32Array(a),b,c)}function Ac(a,b,c){P.call(this,new Float64Array(a),b,c)}function Se(){this.vertices=[];this.normals=[];this.colors=[];this.uvs=[];this.uvs2=[];this.groups=[];this.morphTargets={};this.skinWeights=[];this.skinIndices=[];this.boundingSphere=this.boundingBox=null;this.groupsNeedUpdate=
 this.uvsNeedUpdate=this.colorsNeedUpdate=this.normalsNeedUpdate=this.verticesNeedUpdate=!1}function Te(a){if(0===a.length)return-Infinity;for(var b=a[0],c=1,d=a.length;c<d;++c)a[c]>b&&(b=a[c]);return b}function D(){Object.defineProperty(this,"id",{value:Yf+=2});this.uuid=H.generateUUID();this.name="";this.type="BufferGeometry";this.index=null;this.attributes={};this.morphAttributes={};this.groups=[];this.boundingSphere=this.boundingBox=null;this.drawRange={start:0,count:Infinity};this.userData={}}
-function Ob(a,b,c,d,e,f){G.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new rb(a,b,c,d,e,f));this.mergeVertices()}function rb(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,fa,A,B){var r=f/fa,u=g/A,w=f/2,x=g/2,z=l/2;g=fa+1;var C=A+1,y=f=0,Q,Fa,ta=new n;for(Fa=0;Fa<C;Fa++){var F=Fa*u-x;for(Q=0;Q<g;Q++)ta[a]=(Q*r-w)*d,ta[b]=F*e,ta[c]=z,m.push(ta.x,ta.y,ta.z),ta[a]=0,ta[b]=0,ta[c]=0<l?1:-1,q.push(ta.x,
+function Ob(a,b,c,d,e,f){G.call(this);this.type="BoxGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};this.fromBufferGeometry(new rb(a,b,c,d,e,f));this.mergeVertices()}function rb(a,b,c,d,e,f){function g(a,b,c,d,e,f,g,l,fa,A,B){var r=f/fa,u=g/A,w=f/2,x=g/2,z=l/2;g=fa+1;var C=A+1,y=f=0,Q,Fa,ta=new n;for(Fa=0;Fa<C;Fa++){var E=Fa*u-x;for(Q=0;Q<g;Q++)ta[a]=(Q*r-w)*d,ta[b]=E*e,ta[c]=z,m.push(ta.x,ta.y,ta.z),ta[a]=0,ta[b]=0,ta[c]=0<l?1:-1,q.push(ta.x,
 ta.y,ta.z),p.push(Q/fa),p.push(1-Fa/A),f+=1}for(Fa=0;Fa<A;Fa++)for(Q=0;Q<fa;Q++)a=v+Q+g*(Fa+1),b=v+(Q+1)+g*(Fa+1),c=v+(Q+1)+g*Fa,k.push(v+Q+g*Fa,a,c),k.push(a,b,c),y+=6;h.addGroup(t,y,B);t+=y;v+=f}D.call(this);this.type="BoxBufferGeometry";this.parameters={width:a,height:b,depth:c,widthSegments:d,heightSegments:e,depthSegments:f};var h=this;a=a||1;b=b||1;c=c||1;d=Math.floor(d)||1;e=Math.floor(e)||1;f=Math.floor(f)||1;var k=[],m=[],q=[],p=[],v=0,t=0;g("z","y","x",-1,-1,c,b,a,f,e,0);g("z","y","x",1,
--1,c,b,-a,f,e,1);g("x","z","y",1,1,a,c,b,d,f,2);g("x","z","y",1,-1,a,c,-b,d,f,3);g("x","y","z",1,-1,a,b,c,d,e,4);g("x","y","z",-1,-1,a,b,-c,d,e,5);this.setIndex(k);this.addAttribute("position",new F(m,3));this.addAttribute("normal",new F(q,3));this.addAttribute("uv",new F(p,2))}function Cc(a,b,c,d){G.call(this);this.type="PlaneGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new sb(a,b,c,d));this.mergeVertices()}function sb(a,b,c,d){D.call(this);
-this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};a=a||1;b=b||1;var e=a/2,f=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var g=c+1,h=d+1,k=a/c,m=b/d,q=[],p=[],v=[],t=[];for(a=0;a<h;a++){var l=a*m-f;for(b=0;b<g;b++)p.push(b*k-e,-l,0),v.push(0,0,1),t.push(b/c),t.push(1-a/d)}for(a=0;a<d;a++)for(b=0;b<c;b++)e=b+g*(a+1),f=b+1+g*(a+1),h=b+1+g*a,q.push(b+g*a,e,h),q.push(e,f,h);this.setIndex(q);this.addAttribute("position",new F(p,3));this.addAttribute("normal",
-new F(v,3));this.addAttribute("uv",new F(t,2))}function M(){Object.defineProperty(this,"id",{value:Zf++});this.uuid=H.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.clippingPlanes=
+-1,c,b,-a,f,e,1);g("x","z","y",1,1,a,c,b,d,f,2);g("x","z","y",1,-1,a,c,-b,d,f,3);g("x","y","z",1,-1,a,b,c,d,e,4);g("x","y","z",-1,-1,a,b,-c,d,e,5);this.setIndex(k);this.addAttribute("position",new E(m,3));this.addAttribute("normal",new E(q,3));this.addAttribute("uv",new E(p,2))}function Cc(a,b,c,d){G.call(this);this.type="PlaneGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};this.fromBufferGeometry(new sb(a,b,c,d));this.mergeVertices()}function sb(a,b,c,d){D.call(this);
+this.type="PlaneBufferGeometry";this.parameters={width:a,height:b,widthSegments:c,heightSegments:d};a=a||1;b=b||1;var e=a/2,f=b/2;c=Math.floor(c)||1;d=Math.floor(d)||1;var g=c+1,h=d+1,k=a/c,m=b/d,q=[],p=[],v=[],t=[];for(a=0;a<h;a++){var l=a*m-f;for(b=0;b<g;b++)p.push(b*k-e,-l,0),v.push(0,0,1),t.push(b/c),t.push(1-a/d)}for(a=0;a<d;a++)for(b=0;b<c;b++)e=b+g*(a+1),f=b+1+g*(a+1),h=b+1+g*a,q.push(b+g*a,e,h),q.push(e,f,h);this.setIndex(q);this.addAttribute("position",new E(p,3));this.addAttribute("normal",
+new E(v,3));this.addAttribute("uv",new E(t,2))}function M(){Object.defineProperty(this,"id",{value:Zf++});this.uuid=H.generateUUID();this.name="";this.type="Material";this.lights=this.fog=!0;this.blending=1;this.side=0;this.vertexTangents=this.flatShading=!1;this.vertexColors=0;this.opacity=1;this.transparent=!1;this.blendSrc=204;this.blendDst=205;this.blendEquation=100;this.blendEquationAlpha=this.blendDstAlpha=this.blendSrcAlpha=null;this.depthFunc=3;this.depthWrite=this.depthTest=!0;this.clippingPlanes=
 null;this.clipShadows=this.clipIntersection=!1;this.shadowSide=null;this.colorWrite=!0;this.precision=null;this.polygonOffset=!1;this.polygonOffsetUnits=this.polygonOffsetFactor=0;this.dithering=!1;this.alphaTest=0;this.premultipliedAlpha=!1;this.visible=!0;this.userData={};this.needsUpdate=!0}function Ca(a){M.call(this);this.type="ShaderMaterial";this.defines={};this.uniforms={};this.vertexShader="void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";this.fragmentShader=
 "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";this.linewidth=1;this.wireframe=!1;this.wireframeLinewidth=1;this.morphNormals=this.morphTargets=this.skinning=this.clipping=this.lights=this.fog=!1;this.extensions={derivatives:!1,fragDepth:!1,drawBuffers:!1,shaderTextureLOD:!1};this.defaultAttributeValues={color:[1,1,1],uv:[0,0],uv2:[0,0]};this.index0AttributeName=void 0;this.uniformsNeedUpdate=!1;void 0!==a&&(void 0!==a.attributes&&console.error("THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead."),
 this.setValues(a))}function tb(a,b){this.origin=void 0!==a?a:new n;this.direction=void 0!==b?b:new n}function ua(a,b,c){this.a=void 0!==a?a:new n;this.b=void 0!==b?b:new n;this.c=void 0!==c?c:new n}function ya(a){M.call(this);this.type="MeshBasicMaterial";this.color=new K(16777215);this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=
-1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function va(a,b){E.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new ya({color:16777215*Math.random()});this.drawMode=0;this.updateMorphTargets()}function $f(a,b,c,d){function e(a,c){b.buffers.color.setClear(a.r,a.g,a.b,c,d)}var f=new K(0),g=0,h,k,m=null,q=0;return{getClearColor:function(){return f},setClearColor:function(a,b){f.set(a);g=
+1;this.wireframeLinejoin=this.wireframeLinecap="round";this.lights=this.morphTargets=this.skinning=!1;this.setValues(a)}function va(a,b){F.call(this);this.type="Mesh";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new ya({color:16777215*Math.random()});this.drawMode=0;this.updateMorphTargets()}function $f(a,b,c,d){function e(a,c){b.buffers.color.setClear(a.r,a.g,a.b,c,d)}var f=new K(0),g=0,h,k,m=null,q=0;return{getClearColor:function(){return f},setClearColor:function(a,b){f.set(a);g=
 void 0!==b?b:1;e(f,g)},getClearAlpha:function(){return g},setClearAlpha:function(a){g=a;e(f,g)},render:function(b,d,t,l){d=d.background;t=a.vr;(t=t.getSession&&t.getSession())&&"additive"===t.environmentBlendMode&&(d=null);null===d?(e(f,g),m=null,q=0):d&&d.isColor&&(e(d,1),l=!0,m=null,q=0);(a.autoClear||l)&&a.clear(a.autoClearColor,a.autoClearDepth,a.autoClearStencil);if(d&&(d.isCubeTexture||d.isWebGLRenderTargetCube)){void 0===k&&(k=new va(new rb(1,1,1),new Ca({type:"BackgroundCubeMaterial",uniforms:Mb(Ta.cube.uniforms),
 vertexShader:Ta.cube.vertexShader,fragmentShader:Ta.cube.fragmentShader,side:1,depthTest:!1,depthWrite:!1,fog:!1})),k.geometry.removeAttribute("normal"),k.geometry.removeAttribute("uv"),k.onBeforeRender=function(a,b,c){this.matrixWorld.copyPosition(c.matrixWorld)},Object.defineProperty(k.material,"map",{get:function(){return this.uniforms.tCube.value}}),c.update(k));l=d.isWebGLRenderTargetCube?d.texture:d;k.material.uniforms.tCube.value=l;k.material.uniforms.tFlip.value=d.isWebGLRenderTargetCube?
 1:-1;if(m!==d||q!==l.version)k.material.needsUpdate=!0,m=d,q=l.version;b.unshift(k,k.geometry,k.material,0,0,null)}else if(d&&d.isTexture){void 0===h&&(h=new va(new sb(2,2),new Ca({type:"BackgroundMaterial",uniforms:Mb(Ta.background.uniforms),vertexShader:Ta.background.vertexShader,fragmentShader:Ta.background.fragmentShader,side:0,depthTest:!1,depthWrite:!1,fog:!1})),h.geometry.removeAttribute("normal"),Object.defineProperty(h.material,"map",{get:function(){return this.uniforms.t2D.value}}),c.update(h));
@@ -101,20 +101,20 @@ new n(0,0,-1),new n(0,1,0),new n(0,-1,0)],w=[new n(0,1,0),new n(0,1,0),new n(0,1
 a.getRenderTarget(),v=a.state;v.setBlending(0);v.buffers.color.setClear(1,1,1,1);v.buffers.depth.setTest(!0);v.setScissorTest(!1);for(var l,t=0,r=b.length;t<r;t++){var n=b[t];l=n.shadow;var x=n&&n.isPointLight;if(void 0===l)console.warn("THREE.WebGLShadowMap:",n,"has no shadow.");else{var y=l.camera;h.copy(l.mapSize);h.min(k);if(x){var C=h.x,A=h.y;z[0].set(2*C,A,C,A);z[1].set(0,A,C,A);z[2].set(3*C,A,C,A);z[3].set(C,A,C,A);z[4].set(3*C,0,C,A);z[5].set(C,0,C,A);h.x*=4;h.y*=2}null===l.map&&(l.map=new Ra(h.x,
 h.y,{minFilter:1003,magFilter:1003,format:1023}),l.map.texture.name=n.name+".shadowMap",y.updateProjectionMatrix());l.isSpotLightShadow&&l.update(n);C=l.map;A=l.matrix;q.setFromMatrixPosition(n.matrixWorld);y.position.copy(q);x?(l=6,A.makeTranslation(-q.x,-q.y,-q.z)):(l=1,m.setFromMatrixPosition(n.target.matrixWorld),y.lookAt(m),y.updateMatrixWorld(),A.set(.5,0,0,.5,0,.5,0,.5,0,0,.5,.5,0,0,0,1),A.multiply(y.projectionMatrix),A.multiply(y.matrixWorldInverse));a.setRenderTarget(C);a.clear();for(n=0;n<
 l;n++)x&&(m.copy(y.position),m.add(u[n]),y.up.copy(w[n]),y.lookAt(m),y.updateMatrixWorld(),v.viewport(z[n])),g.multiplyMatrices(y.projectionMatrix,y.matrixWorldInverse),f.setFromMatrix(g),e(c,d,y,x)}}Q.needsUpdate=!1;a.setRenderTarget(p)}}}function ah(a,b,c,d){function e(b,c,d){var e=new Uint8Array(4),f=a.createTexture();a.bindTexture(b,f);a.texParameteri(b,10241,9728);a.texParameteri(b,10240,9728);for(b=0;b<d;b++)a.texImage2D(c+b,0,6408,1,1,0,6408,5121,e);return f}function f(c,e){z[c]=1;0===x[c]&&
-(a.enableVertexAttribArray(c),x[c]=1);C[c]!==e&&((d.isWebGL2?a:b.get("ANGLE_instanced_arrays"))[d.isWebGL2?"vertexAttribDivisor":"vertexAttribDivisorANGLE"](c,e),C[c]=e)}function g(b){!0!==y[b]&&(a.enable(b),y[b]=!0)}function h(b){!1!==y[b]&&(a.disable(b),y[b]=!1)}function k(b,d,e,f,k,m,q,p){if(0===b)A&&(h(3042),A=!1);else if(A||(g(3042),A=!0),5!==b){if(b!==B||p!==ee){if(100!==F||100!==wd)a.blendEquation(32774),wd=F=100;if(p)switch(b){case 1:a.blendFuncSeparate(1,771,1,771);break;case 2:a.blendFunc(1,
-1);break;case 3:a.blendFuncSeparate(0,0,769,771);break;case 4:a.blendFuncSeparate(0,768,0,770);break;default:console.error("THREE.WebGLState: Invalid blending: ",b)}else switch(b){case 1:a.blendFuncSeparate(770,771,1,771);break;case 2:a.blendFunc(770,1);break;case 3:a.blendFunc(0,769);break;case 4:a.blendFunc(0,768);break;default:console.error("THREE.WebGLState: Invalid blending: ",b)}de=ce=X=Bc=null;B=b;ee=p}}else{k=k||d;m=m||e;q=q||f;if(d!==F||k!==wd)a.blendEquationSeparate(c.convert(d),c.convert(k)),
-F=d,wd=k;if(e!==Bc||f!==X||m!==ce||q!==de)a.blendFuncSeparate(c.convert(e),c.convert(f),c.convert(m),c.convert(q)),Bc=e,X=f,ce=m,de=q;B=b;ee=null}}function m(b){E!==b&&(b?a.frontFace(2304):a.frontFace(2305),E=b)}function q(b){0!==b?(g(2884),b!==D&&(1===b?a.cullFace(1029):2===b?a.cullFace(1028):a.cullFace(1032))):h(2884);D=b}function p(b,c,d){if(b){if(g(32823),I!==c||K!==d)a.polygonOffset(c,d),I=c,K=d}else h(32823)}function v(b){void 0===b&&(b=33984+L-1);G!==b&&(a.activeTexture(b),G=b)}var l=new function(){var b=
+(a.enableVertexAttribArray(c),x[c]=1);C[c]!==e&&((d.isWebGL2?a:b.get("ANGLE_instanced_arrays"))[d.isWebGL2?"vertexAttribDivisor":"vertexAttribDivisorANGLE"](c,e),C[c]=e)}function g(b){!0!==y[b]&&(a.enable(b),y[b]=!0)}function h(b){!1!==y[b]&&(a.disable(b),y[b]=!1)}function k(b,d,e,f,k,m,q,p){if(0===b)A&&(h(3042),A=!1);else if(A||(g(3042),A=!0),5!==b){if(b!==B||p!==ee){if(100!==E||100!==wd)a.blendEquation(32774),wd=E=100;if(p)switch(b){case 1:a.blendFuncSeparate(1,771,1,771);break;case 2:a.blendFunc(1,
+1);break;case 3:a.blendFuncSeparate(0,0,769,771);break;case 4:a.blendFuncSeparate(0,768,0,770);break;default:console.error("THREE.WebGLState: Invalid blending: ",b)}else switch(b){case 1:a.blendFuncSeparate(770,771,1,771);break;case 2:a.blendFunc(770,1);break;case 3:a.blendFunc(0,769);break;case 4:a.blendFunc(0,768);break;default:console.error("THREE.WebGLState: Invalid blending: ",b)}de=ce=X=Bc=null;B=b;ee=p}}else{k=k||d;m=m||e;q=q||f;if(d!==E||k!==wd)a.blendEquationSeparate(c.convert(d),c.convert(k)),
+E=d,wd=k;if(e!==Bc||f!==X||m!==ce||q!==de)a.blendFuncSeparate(c.convert(e),c.convert(f),c.convert(m),c.convert(q)),Bc=e,X=f,ce=m,de=q;B=b;ee=null}}function m(b){F!==b&&(b?a.frontFace(2304):a.frontFace(2305),F=b)}function q(b){0!==b?(g(2884),b!==D&&(1===b?a.cullFace(1029):2===b?a.cullFace(1028):a.cullFace(1032))):h(2884);D=b}function p(b,c,d){if(b){if(g(32823),I!==c||K!==d)a.polygonOffset(c,d),I=c,K=d}else h(32823)}function v(b){void 0===b&&(b=33984+L-1);G!==b&&(a.activeTexture(b),G=b)}var l=new function(){var b=
 !1,c=new ba,d=null,e=new ba(0,0,0,0);return{setMask:function(c){d===c||b||(a.colorMask(c,c,c,c),d=c)},setLocked:function(a){b=a},setClear:function(b,d,f,g,h){!0===h&&(b*=g,d*=g,f*=g);c.set(b,d,f,g);!1===e.equals(c)&&(a.clearColor(b,d,f,g),e.copy(c))},reset:function(){b=!1;d=null;e.set(-1,0,0,0)}}},r=new function(){var b=!1,c=null,d=null,e=null;return{setTest:function(a){a?g(2929):h(2929)},setMask:function(d){c===d||b||(a.depthMask(d),c=d)},setFunc:function(b){if(d!==b){if(b)switch(b){case 0:a.depthFunc(512);
 break;case 1:a.depthFunc(519);break;case 2:a.depthFunc(513);break;case 3:a.depthFunc(515);break;case 4:a.depthFunc(514);break;case 5:a.depthFunc(518);break;case 6:a.depthFunc(516);break;case 7:a.depthFunc(517);break;default:a.depthFunc(515)}else a.depthFunc(515);d=b}},setLocked:function(a){b=a},setClear:function(b){e!==b&&(a.clearDepth(b),e=b)},reset:function(){b=!1;e=d=c=null}}},u=new function(){var b=!1,c=null,d=null,e=null,f=null,k=null,m=null,q=null,p=null;return{setTest:function(a){a?g(2960):
-h(2960)},setMask:function(d){c===d||b||(a.stencilMask(d),c=d)},setFunc:function(b,c,g){if(d!==b||e!==c||f!==g)a.stencilFunc(b,c,g),d=b,e=c,f=g},setOp:function(b,c,d){if(k!==b||m!==c||q!==d)a.stencilOp(b,c,d),k=b,m=c,q=d},setLocked:function(a){b=a},setClear:function(b){p!==b&&(a.clearStencil(b),p=b)},reset:function(){b=!1;p=q=m=k=f=e=d=c=null}}},n=a.getParameter(34921),z=new Uint8Array(n),x=new Uint8Array(n),C=new Uint8Array(n),y={},Q=null,fa=null,A=null,B=null,F=null,Bc=null,X=null,wd=null,ce=null,
-de=null,ee=!1,E=null,D=null,ta=null,I=null,K=null,L=a.getParameter(35661),J=!1;n=0;n=a.getParameter(7938);-1!==n.indexOf("WebGL")?(n=parseFloat(/^WebGL ([0-9])/.exec(n)[1]),J=1<=n):-1!==n.indexOf("OpenGL ES")&&(n=parseFloat(/^OpenGL ES ([0-9])/.exec(n)[1]),J=2<=n);var G=null,H={},M=new ba,N=new ba,T={};T[3553]=e(3553,3553,1);T[34067]=e(34067,34069,6);l.setClear(0,0,0,1);r.setClear(1);u.setClear(0);g(2929);r.setFunc(3);m(!1);q(1);g(2884);k(0);return{buffers:{color:l,depth:r,stencil:u},initAttributes:function(){for(var a=
+h(2960)},setMask:function(d){c===d||b||(a.stencilMask(d),c=d)},setFunc:function(b,c,g){if(d!==b||e!==c||f!==g)a.stencilFunc(b,c,g),d=b,e=c,f=g},setOp:function(b,c,d){if(k!==b||m!==c||q!==d)a.stencilOp(b,c,d),k=b,m=c,q=d},setLocked:function(a){b=a},setClear:function(b){p!==b&&(a.clearStencil(b),p=b)},reset:function(){b=!1;p=q=m=k=f=e=d=c=null}}},n=a.getParameter(34921),z=new Uint8Array(n),x=new Uint8Array(n),C=new Uint8Array(n),y={},Q=null,fa=null,A=null,B=null,E=null,Bc=null,X=null,wd=null,ce=null,
+de=null,ee=!1,F=null,D=null,ta=null,I=null,K=null,L=a.getParameter(35661),J=!1;n=0;n=a.getParameter(7938);-1!==n.indexOf("WebGL")?(n=parseFloat(/^WebGL ([0-9])/.exec(n)[1]),J=1<=n):-1!==n.indexOf("OpenGL ES")&&(n=parseFloat(/^OpenGL ES ([0-9])/.exec(n)[1]),J=2<=n);var G=null,H={},M=new ba,N=new ba,T={};T[3553]=e(3553,3553,1);T[34067]=e(34067,34069,6);l.setClear(0,0,0,1);r.setClear(1);u.setClear(0);g(2929);r.setFunc(3);m(!1);q(1);g(2884);k(0);return{buffers:{color:l,depth:r,stencil:u},initAttributes:function(){for(var a=
 0,b=z.length;a<b;a++)z[a]=0},enableAttribute:function(a){f(a,0)},enableAttributeAndDivisor:f,disableUnusedAttributes:function(){for(var b=0,c=x.length;b!==c;++b)x[b]!==z[b]&&(a.disableVertexAttribArray(b),x[b]=0)},enable:g,disable:h,getCompressedTextureFormats:function(){if(null===Q&&(Q=[],b.get("WEBGL_compressed_texture_pvrtc")||b.get("WEBGL_compressed_texture_s3tc")||b.get("WEBGL_compressed_texture_etc1")||b.get("WEBGL_compressed_texture_astc")))for(var c=a.getParameter(34467),d=0;d<c.length;d++)Q.push(c[d]);
 return Q},useProgram:function(b){return fa!==b?(a.useProgram(b),fa=b,!0):!1},setBlending:k,setMaterial:function(a,b){2===a.side?h(2884):g(2884);var c=1===a.side;b&&(c=!c);m(c);1===a.blending&&!1===a.transparent?k(0):k(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha,a.premultipliedAlpha);r.setFunc(a.depthFunc);r.setTest(a.depthTest);r.setMask(a.depthWrite);l.setMask(a.colorWrite);p(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)},setFlipSided:m,
 setCullFace:q,setLineWidth:function(b){b!==ta&&(J&&a.lineWidth(b),ta=b)},setPolygonOffset:p,setScissorTest:function(a){a?g(3089):h(3089)},activeTexture:v,bindTexture:function(b,c){null===G&&v();var d=H[G];void 0===d&&(d={type:void 0,texture:void 0},H[G]=d);if(d.type!==b||d.texture!==c)a.bindTexture(b,c||T[b]),d.type=b,d.texture=c},compressedTexImage2D:function(){try{a.compressedTexImage2D.apply(a,arguments)}catch(ea){console.error("THREE.WebGLState:",ea)}},texImage2D:function(){try{a.texImage2D.apply(a,
-arguments)}catch(ea){console.error("THREE.WebGLState:",ea)}},texImage3D:function(){try{a.texImage3D.apply(a,arguments)}catch(ea){console.error("THREE.WebGLState:",ea)}},scissor:function(b){!1===M.equals(b)&&(a.scissor(b.x,b.y,b.z,b.w),M.copy(b))},viewport:function(b){!1===N.equals(b)&&(a.viewport(b.x,b.y,b.z,b.w),N.copy(b))},reset:function(){for(var b=0;b<x.length;b++)1===x[b]&&(a.disableVertexAttribArray(b),x[b]=0);y={};G=Q=null;H={};D=E=B=fa=null;l.reset();r.reset();u.reset()}}}function bh(a,b,
-c,d,e,f,g){function h(a,b){return F?new OffscreenCanvas(a,b):document.createElementNS("http://www.w3.org/1999/xhtml","canvas")}function k(a,b,c,d){var e=1;if(a.width>d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?H.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),
-void 0===B&&(B=h(b,e)),c=c?h(b,e):B,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),F?c.transferToImageBitmap():c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return H.isPowerOfTwo(a.width)&&H.isPowerOfTwo(a.height)}function q(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}
-function p(b,c,e,f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function v(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");
+arguments)}catch(ea){console.error("THREE.WebGLState:",ea)}},texImage3D:function(){try{a.texImage3D.apply(a,arguments)}catch(ea){console.error("THREE.WebGLState:",ea)}},scissor:function(b){!1===M.equals(b)&&(a.scissor(b.x,b.y,b.z,b.w),M.copy(b))},viewport:function(b){!1===N.equals(b)&&(a.viewport(b.x,b.y,b.z,b.w),N.copy(b))},reset:function(){for(var b=0;b<x.length;b++)1===x[b]&&(a.disableVertexAttribArray(b),x[b]=0);y={};G=Q=null;H={};D=F=B=fa=null;l.reset();r.reset();u.reset()}}}function bh(a,b,
+c,d,e,f,g){function h(a,b){return E?new OffscreenCanvas(a,b):document.createElementNS("http://www.w3.org/1999/xhtml","canvas")}function k(a,b,c,d){var e=1;if(a.width>d||a.height>d)e=d/Math.max(a.width,a.height);if(1>e||!0===b){if("undefined"!==typeof HTMLImageElement&&a instanceof HTMLImageElement||"undefined"!==typeof HTMLCanvasElement&&a instanceof HTMLCanvasElement||"undefined"!==typeof ImageBitmap&&a instanceof ImageBitmap)return d=b?H.floorPowerOfTwo:Math.floor,b=d(e*a.width),e=d(e*a.height),
+void 0===B&&(B=h(b,e)),c=c?h(b,e):B,c.width=b,c.height=e,c.getContext("2d").drawImage(a,0,0,b,e),console.warn("THREE.WebGLRenderer: Texture has been resized from ("+a.width+"x"+a.height+") to ("+b+"x"+e+")."),c;"data"in a&&console.warn("THREE.WebGLRenderer: Image in DataTexture is too big ("+a.width+"x"+a.height+").")}return a}function m(a){return H.isPowerOfTwo(a.width)&&H.isPowerOfTwo(a.height)}function q(a,b){return a.generateMipmaps&&b&&1003!==a.minFilter&&1006!==a.minFilter}function p(b,c,e,
+f){a.generateMipmap(b);d.get(c).__maxMipLevel=Math.log(Math.max(e,f))*Math.LOG2E}function v(a,c){if(!e.isWebGL2)return a;var d=a;6403===a&&(5126===c&&(d=33326),5131===c&&(d=33325),5121===c&&(d=33321));6407===a&&(5126===c&&(d=34837),5131===c&&(d=34843),5121===c&&(d=32849));6408===a&&(5126===c&&(d=34836),5131===c&&(d=34842),5121===c&&(d=32856));33325===d||33326===d||34842===d||34836===d?b.get("EXT_color_buffer_float"):(34843===d||34837===d)&&console.warn("THREE.WebGLRenderer: Floating point textures with RGB format not supported. Please use RGBA instead.");
 return d}function l(a){return 1003===a||1004===a||1005===a?9728:9729}function r(b){b=b.target;b.removeEventListener("dispose",r);var c=d.get(b);void 0!==c.__webglInit&&(a.deleteTexture(c.__webglTexture),d.remove(b));b.isVideoTexture&&delete A[b.id];g.memory.textures--}function u(b){b=b.target;b.removeEventListener("dispose",u);var c=d.get(b),e=d.get(b.texture);if(b){void 0!==e.__webglTexture&&a.deleteTexture(e.__webglTexture);b.depthTexture&&b.depthTexture.dispose();if(b.isWebGLRenderTargetCube)for(e=
 0;6>e;e++)a.deleteFramebuffer(c.__webglFramebuffer[e]),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer[e]);else a.deleteFramebuffer(c.__webglFramebuffer),c.__webglDepthbuffer&&a.deleteRenderbuffer(c.__webglDepthbuffer);d.remove(b.texture);d.remove(b)}g.memory.textures--}function n(a,b){var e=d.get(a);if(a.isVideoTexture){var f=a.id,h=g.render.frame;A[f]!==h&&(A[f]=h,a.update())}if(0<a.version&&e.__version!==a.version)if(f=a.image,void 0===f)console.warn("THREE.WebGLRenderer: Texture marked for update but image is undefined");
 else if(!1===f.complete)console.warn("THREE.WebGLRenderer: Texture marked for update but image is incomplete");else{C(e,a,b);return}c.activeTexture(33984+b);c.bindTexture(3553,e.__webglTexture)}function z(c,g,h){h?(a.texParameteri(c,10242,f.convert(g.wrapS)),a.texParameteri(c,10243,f.convert(g.wrapT)),32879!==c&&35866!==c||a.texParameteri(c,32882,f.convert(g.wrapR)),a.texParameteri(c,10240,f.convert(g.magFilter)),a.texParameteri(c,10241,f.convert(g.minFilter))):(a.texParameteri(c,10242,33071),a.texParameteri(c,
@@ -126,7 +126,7 @@ if(d.isDepthTexture){u=6402;if(1015===d.type){if(!e.isWebGL2)throw Error("Float
 w,u,h.width,h.height,0,h.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()"):c.texImage2D(3553,w,u,h.width,h.height,0,t,r,h.data);b.__maxMipLevel=n.length-1}else if(d.isDataTexture2DArray)c.texImage3D(35866,0,u,g.width,g.height,g.depth,0,t,r,g.data),b.__maxMipLevel=0;else if(d.isDataTexture3D)c.texImage3D(32879,0,u,g.width,g.height,g.depth,0,t,r,g.data),b.__maxMipLevel=0;else if(0<n.length&&l){w=0;for(y=n.length;w<y;w++)h=n[w],c.texImage2D(3553,
 w,u,t,r,h);d.generateMipmaps=!1;b.__maxMipLevel=n.length-1}else c.texImage2D(3553,0,u,t,r,g),b.__maxMipLevel=0;q(d,l)&&p(3553,d,g.width,g.height);b.__version=d.version;if(d.onUpdate)d.onUpdate(d)}function y(b,e,g,h){var k=f.convert(e.texture.format),m=f.convert(e.texture.type),q=v(k,m);c.texImage2D(h,0,q,e.width,e.height,0,k,m,null);a.bindFramebuffer(36160,b);a.framebufferTexture2D(36160,g,h,d.get(e.texture).__webglTexture,0);a.bindFramebuffer(36160,null)}function Q(b,c,d){a.bindRenderbuffer(36161,
 b);if(c.depthBuffer&&!c.stencilBuffer)d?(d=fa(c),a.renderbufferStorageMultisample(36161,d,33189,c.width,c.height)):a.renderbufferStorage(36161,33189,c.width,c.height),a.framebufferRenderbuffer(36160,36096,36161,b);else if(c.depthBuffer&&c.stencilBuffer)d?(d=fa(c),a.renderbufferStorageMultisample(36161,d,34041,c.width,c.height)):a.renderbufferStorage(36161,34041,c.width,c.height),a.framebufferRenderbuffer(36160,33306,36161,b);else{b=f.convert(c.texture.format);var e=f.convert(c.texture.type);b=v(b,
-e);d?(d=fa(c),a.renderbufferStorageMultisample(36161,d,b,c.width,c.height)):a.renderbufferStorage(36161,b,c.width,c.height)}a.bindRenderbuffer(36161,null)}function fa(a){return e.isWebGL2&&a.isWebGLMultisampleRenderTarget?Math.min(e.maxSamples,a.samples):0}var A={},B,F="undefined"!==typeof OffscreenCanvas;this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0<a.version&&e.__version!==a.version?C(e,a,b):(c.activeTexture(33984+b),c.bindTexture(35866,e.__webglTexture))};this.setTexture3D=
+e);d?(d=fa(c),a.renderbufferStorageMultisample(36161,d,b,c.width,c.height)):a.renderbufferStorage(36161,b,c.width,c.height)}a.bindRenderbuffer(36161,null)}function fa(a){return e.isWebGL2&&a.isWebGLMultisampleRenderTarget?Math.min(e.maxSamples,a.samples):0}var A={},B,E="undefined"!==typeof OffscreenCanvas;this.setTexture2D=n;this.setTexture2DArray=function(a,b){var e=d.get(a);0<a.version&&e.__version!==a.version?C(e,a,b):(c.activeTexture(33984+b),c.bindTexture(35866,e.__webglTexture))};this.setTexture3D=
 function(a,b){var e=d.get(a);0<a.version&&e.__version!==a.version?C(e,a,b):(c.activeTexture(33984+b),c.bindTexture(32879,e.__webglTexture))};this.setTextureCube=function(b,g){var h=d.get(b);if(6===b.image.length)if(0<b.version&&h.__version!==b.version){x(h,b);c.activeTexture(33984+g);c.bindTexture(34067,h.__webglTexture);a.pixelStorei(37440,b.flipY);g=b&&b.isCompressedTexture;for(var l=b.image[0]&&b.image[0].isDataTexture,t=[],r=0;6>r;r++)t[r]=g||l?l?b.image[r].image:b.image[r]:k(b.image[r],!1,!0,
 e.maxCubemapSize);var u=t[0],n=m(u)||e.isWebGL2,w=f.convert(b.format),y=f.convert(b.type),C=v(w,y);z(34067,b,n);for(r=0;6>r;r++)if(g)for(var A,fa=t[r].mipmaps,Q=0,Bc=fa.length;Q<Bc;Q++)A=fa[Q],1023!==b.format&&1022!==b.format?-1<c.getCompressedTextureFormats().indexOf(w)?c.compressedTexImage2D(34069+r,Q,C,A.width,A.height,0,A.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()"):c.texImage2D(34069+r,Q,C,A.width,A.height,0,w,y,A.data);
 else l?c.texImage2D(34069+r,0,C,t[r].width,t[r].height,0,w,y,t[r].data):c.texImage2D(34069+r,0,C,w,y,t[r]);h.__maxMipLevel=g?fa.length-1:0;q(b,n)&&p(34067,b,u.width,u.height);h.__version=b.version;if(b.onUpdate)b.onUpdate(b)}else c.activeTexture(33984+g),c.bindTexture(34067,h.__webglTexture)};this.setTextureCubeDynamic=function(a,b){c.activeTexture(33984+b);c.bindTexture(34067,d.get(a).__webglTexture)};this.setupRenderTarget=function(b){var h=d.get(b),k=d.get(b.texture);b.addEventListener("dispose",
@@ -141,7 +141,7 @@ a)return 5121;if(1017===a)return 32819;if(1018===a)return 32820;if(1019===a)retu
 if(1028===a)return 6403;if(100===a)return 32774;if(101===a)return 32778;if(102===a)return 32779;if(200===a)return 0;if(201===a)return 1;if(202===a)return 768;if(203===a)return 769;if(204===a)return 770;if(205===a)return 771;if(206===a)return 772;if(207===a)return 773;if(208===a)return 774;if(209===a)return 775;if(210===a)return 776;if(33776===a||33777===a||33778===a||33779===a)if(d=b.get("WEBGL_compressed_texture_s3tc"),null!==d){if(33776===a)return d.COMPRESSED_RGB_S3TC_DXT1_EXT;if(33777===a)return d.COMPRESSED_RGBA_S3TC_DXT1_EXT;
 if(33778===a)return d.COMPRESSED_RGBA_S3TC_DXT3_EXT;if(33779===a)return d.COMPRESSED_RGBA_S3TC_DXT5_EXT}if(35840===a||35841===a||35842===a||35843===a)if(d=b.get("WEBGL_compressed_texture_pvrtc"),null!==d){if(35840===a)return d.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;if(35841===a)return d.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;if(35842===a)return d.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;if(35843===a)return d.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG}if(36196===a&&(d=b.get("WEBGL_compressed_texture_etc1"),null!==d))return d.COMPRESSED_RGB_ETC1_WEBGL;
 if(37808===a||37809===a||37810===a||37811===a||37812===a||37813===a||37814===a||37815===a||37816===a||37817===a||37818===a||37819===a||37820===a||37821===a)if(d=b.get("WEBGL_compressed_texture_astc"),null!==d)return a;if(103===a||104===a){if(c.isWebGL2){if(103===a)return 32775;if(104===a)return 32776}d=b.get("EXT_blend_minmax");if(null!==d){if(103===a)return d.MIN_EXT;if(104===a)return d.MAX_EXT}}if(1020===a){if(c.isWebGL2)return 34042;d=b.get("WEBGL_depth_texture");if(null!==d)return d.UNSIGNED_INT_24_8_WEBGL}return 0}}}
-function Tb(){E.call(this);this.type="Group"}function Ua(){E.call(this);this.type="Camera";this.matrixWorldInverse=new J;this.projectionMatrix=new J;this.projectionMatrixInverse=new J}function U(a,b,c,d){Ua.call(this);this.type="PerspectiveCamera";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=0;this.updateProjectionMatrix()}function Fc(a){U.call(this);this.cameras=a||
+function Tb(){F.call(this);this.type="Group"}function Ua(){F.call(this);this.type="Camera";this.matrixWorldInverse=new J;this.projectionMatrix=new J;this.projectionMatrixInverse=new J}function U(a,b,c,d){Ua.call(this);this.type="PerspectiveCamera";this.fov=void 0!==a?a:50;this.zoom=1;this.near=void 0!==c?c:.1;this.far=void 0!==d?d:2E3;this.focus=10;this.aspect=void 0!==b?b:1;this.view=null;this.filmGauge=35;this.filmOffset=0;this.updateProjectionMatrix()}function Fc(a){U.call(this);this.cameras=a||
 []}function qf(a,b,c){rf.setFromMatrixPosition(b.matrixWorld);sf.setFromMatrixPosition(c.matrixWorld);var d=rf.distanceTo(sf),e=b.projectionMatrix.elements,f=c.projectionMatrix.elements,g=e[14]/(e[10]-1);c=e[14]/(e[10]+1);var h=(e[9]+1)/e[5],k=(e[9]-1)/e[5],m=(e[8]-1)/e[0],q=(f[8]+1)/f[0];e=g*m;f=g*q;q=d/(-m+q);m=q*-m;b.matrixWorld.decompose(a.position,a.quaternion,a.scale);a.translateX(m);a.translateZ(q);a.matrixWorld.compose(a.position,a.quaternion,a.scale);a.matrixWorldInverse.getInverse(a.matrixWorld);
 b=g+q;g=c+q;a.projectionMatrix.makePerspective(e-m,f+(d-m),h*c/g*b,k*c/g*b,b,g)}function tf(a){function b(){return null!==e&&!0===e.isPresenting}function c(){if(b()){var c=e.getEyeParameters("left"),f=c.renderWidth*q;c=c.renderHeight*q;C=a.getPixelRatio();a.getSize(x);a.setDrawingBufferSize(2*f,c,1);Q.start()}else d.enabled&&a.setDrawingBufferSize(x.width,x.height,C),Q.stop()}var d=this,e=null,f=null,g=null,h=[],k=new J,m=new J,q=1,p="stage";"undefined"!==typeof window&&"VRFrameData"in window&&(f=
 new window.VRFrameData,window.addEventListener("vrdisplaypresentchange",c,!1));var l=new J,t=new aa,r=new n,u=new U;u.bounds=new ba(0,0,.5,1);u.layers.enable(1);var w=new U;w.bounds=new ba(.5,0,.5,1);w.layers.enable(2);var z=new Fc([u,w]);z.layers.enable(1);z.layers.enable(2);var x=new B,C,y=[];this.enabled=!1;this.getController=function(a){var b=h[a];void 0===b&&(b=new Tb,b.matrixAutoUpdate=!1,b.visible=!1,h[a]=b);return b};this.getDevice=function(){return e};this.setDevice=function(a){void 0!==
@@ -158,8 +158,8 @@ if(null!==p)for(var c=h.baseLayer,d=b.views,e=0;e<d.length;e++){var f=d[e],g=c.g
 c.rotation,c.scale);c.visible=!0;continue}c.visible=!1}z&&z(a)});this.setAnimationLoop=function(a){z=a};this.dispose=function(){};this.getStandingMatrix=function(){console.warn("THREE.WebXRManager: getStandingMatrix() is no longer needed.");return new J};this.submitFrame=function(){}}function ie(a){var b;function c(){la=new dg(O);za=new bg(O,la,a);za.isWebGL2||(la.get("WEBGL_depth_texture"),la.get("OES_texture_float"),la.get("OES_texture_half_float"),la.get("OES_texture_half_float_linear"),la.get("OES_standard_derivatives"),
 la.get("OES_element_index_uint"),la.get("ANGLE_instanced_arrays"));la.get("OES_texture_float_linear");ja=new pf(O,la,za);Z=new ah(O,la,ja,za);Z.scissor(W.copy(aa).multiplyScalar(T));Z.viewport(S.copy(ea).multiplyScalar(T));ha=new gg(O);Da=new Tg;da=new bh(O,la,Z,Da,za,ja,ha);ra=new Vf(O);ua=new eg(O,ra,ha);oa=new jg(ua,ha);xa=new ig(O);ma=new Sg(X,la,za);va=new Wg;qa=new $g;na=new $f(X,Z,oa,fa);Aa=new ag(O,la,ha,za);Ba=new fg(O,la,ha,za);ha.programs=ma.programs;X.context=O;X.capabilities=za;X.extensions=
 la;X.properties=Da;X.renderLists=va;X.state=Z;X.info=ha}function d(a){a.preventDefault();console.log("THREE.WebGLRenderer: Context Lost.");K=!0}function e(){console.log("THREE.WebGLRenderer: Context Restored.");K=!1;c()}function f(a){a=a.target;a.removeEventListener("dispose",f);g(a);Da.remove(a)}function g(a){var b=Da.get(a).program;a.program=void 0;void 0!==b&&ma.releaseProgram(b)}function h(a,b){a.render(function(a){X.renderBufferImmediate(a,b)})}function k(a,b,c,d){if(!1!==a.visible){if(a.layers.test(b.layers))if(a.isGroup)c=
-a.renderOrder;else if(a.isLight)D.pushLight(a),a.castShadow&&D.pushShadow(a);else if(a.isSprite){if(!a.frustumCulled||sa.intersectsSprite(a)){d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec);var e=oa.update(a),f=a.material;f.visible&&E.push(a,e,f,c,ib.z,null)}}else if(a.isImmediateRenderObject)d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec),E.push(a,null,a.material,c,ib.z,null);else if(a.isMesh||a.isLine||a.isPoints)if(a.isSkinnedMesh&&a.skeleton.update(),!a.frustumCulled||
-sa.intersectsObject(a))if(d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec),e=oa.update(a),f=a.material,Array.isArray(f))for(var g=e.groups,h=0,m=g.length;h<m;h++){var q=g[h],p=f[q.materialIndex];p&&p.visible&&E.push(a,e,p,c,ib.z,q)}else f.visible&&E.push(a,e,f,c,ib.z,null);a=a.children;h=0;for(m=a.length;h<m;h++)k(a[h],b,c,d)}}function m(a,b,c,d){for(var e=0,f=a.length;e<f;e++){var g=a[e],h=g.object,k=g.geometry,m=void 0===d?g.material:d;g=g.group;if(c.isArrayCamera){R=c;for(var p=c.cameras,
+a.renderOrder;else if(a.isLight)D.pushLight(a),a.castShadow&&D.pushShadow(a);else if(a.isSprite){if(!a.frustumCulled||sa.intersectsSprite(a)){d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec);var e=oa.update(a),f=a.material;f.visible&&F.push(a,e,f,c,ib.z,null)}}else if(a.isImmediateRenderObject)d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec),F.push(a,null,a.material,c,ib.z,null);else if(a.isMesh||a.isLine||a.isPoints)if(a.isSkinnedMesh&&a.skeleton.update(),!a.frustumCulled||
+sa.intersectsObject(a))if(d&&ib.setFromMatrixPosition(a.matrixWorld).applyMatrix4(Ec),e=oa.update(a),f=a.material,Array.isArray(f))for(var g=e.groups,h=0,m=g.length;h<m;h++){var q=g[h],p=f[q.materialIndex];p&&p.visible&&F.push(a,e,p,c,ib.z,q)}else f.visible&&F.push(a,e,f,c,ib.z,null);a=a.children;h=0;for(m=a.length;h<m;h++)k(a[h],b,c,d)}}function m(a,b,c,d){for(var e=0,f=a.length;e<f;e++){var g=a[e],h=g.object,k=g.geometry,m=void 0===d?g.material:d;g=g.group;if(c.isArrayCamera){R=c;for(var p=c.cameras,
 l=0,v=p.length;l<v;l++){var t=p[l];if(h.layers.test(t.layers)){if("viewport"in t)Z.viewport(S.copy(t.viewport));else{var r=t.bounds;Z.viewport(S.set(r.x*U,r.y*N,r.z*U,r.w*N).multiplyScalar(T))}D.setupLights(t);q(h,b,t,k,m,g)}}}else R=null,q(h,b,c,k,m,g)}}function q(a,c,d,e,f,g){a.onBeforeRender(X,c,d,e,f,g);D=qa.get(c,R||d);a.modelViewMatrix.multiplyMatrices(d.matrixWorldInverse,a.matrixWorld);a.normalMatrix.getNormalMatrix(a.modelViewMatrix);if(a.isImmediateRenderObject){Z.setMaterial(f);var k=l(d,
 c.fog,f,a);V=b=null;ta=!1;h(a,k)}else X.renderBufferDirect(d,c.fog,e,f,a,g);a.onAfterRender(X,c,d,e,f,g);D=qa.get(c,R||d)}function p(a,b,c){var d=Da.get(a),e=D.state.lights,h=d.lightsHash,k=e.state.hash;c=ma.getParameters(a,e.state,D.state.shadowsArray,b,Y.numPlanes,Y.numIntersection,c);var m=ma.getProgramCode(a,c),q=d.program,p=!0;if(void 0===q)a.addEventListener("dispose",f);else if(q.code!==m)g(a);else{if(h.stateID!==k.stateID||h.directionalLength!==k.directionalLength||h.pointLength!==k.pointLength||
 h.spotLength!==k.spotLength||h.rectAreaLength!==k.rectAreaLength||h.hemiLength!==k.hemiLength||h.shadowsLength!==k.shadowsLength)h.stateID=k.stateID,h.directionalLength=k.directionalLength,h.pointLength=k.pointLength,h.spotLength=k.spotLength,h.rectAreaLength=k.rectAreaLength,h.hemiLength=k.hemiLength,h.shadowsLength=k.shadowsLength;else if(void 0!==c.shaderID)return;p=!1}p&&(c.shaderID?(m=Ta[c.shaderID],d.shader={name:a.type,uniforms:Mb(m.uniforms),vertexShader:m.vertexShader,fragmentShader:m.fragmentShader}):
@@ -181,9 +181,9 @@ g.setValue(O,"modelViewMatrix",d.modelViewMatrix);g.setValue(O,"normalMatrix",d.
 b.alphaMap?c=b.alphaMap:b.emissiveMap&&(c=b.emissiveMap);void 0!==c&&(c.isWebGLRenderTarget&&(c=c.texture),!0===c.matrixAutoUpdate&&c.updateMatrix(),a.uvTransform.value.copy(c.matrix))}function r(a,b){a.specular.value=b.specular;a.shininess.value=Math.max(b.shininess,1E-4);b.emissiveMap&&(a.emissiveMap.value=b.emissiveMap);b.bumpMap&&(a.bumpMap.value=b.bumpMap,a.bumpScale.value=b.bumpScale,1===b.side&&(a.bumpScale.value*=-1));b.normalMap&&(a.normalMap.value=b.normalMap,a.normalScale.value.copy(b.normalScale),
 1===b.side&&a.normalScale.value.negate());b.displacementMap&&(a.displacementMap.value=b.displacementMap,a.displacementScale.value=b.displacementScale,a.displacementBias.value=b.displacementBias)}function u(a,b){a.roughness.value=b.roughness;a.metalness.value=b.metalness;b.roughnessMap&&(a.roughnessMap.value=b.roughnessMap);b.metalnessMap&&(a.metalnessMap.value=b.metalnessMap);b.emissiveMap&&(a.emissiveMap.value=b.emissiveMap);b.bumpMap&&(a.bumpMap.value=b.bumpMap,a.bumpScale.value=b.bumpScale,1===
 b.side&&(a.bumpScale.value*=-1));b.normalMap&&(a.normalMap.value=b.normalMap,a.normalScale.value.copy(b.normalScale),1===b.side&&a.normalScale.value.negate());b.displacementMap&&(a.displacementMap.value=b.displacementMap,a.displacementScale.value=b.displacementScale,a.displacementBias.value=b.displacementBias);b.envMap&&(a.envMapIntensity.value=b.envMapIntensity)}console.log("THREE.WebGLRenderer","103dev");a=a||{};var w=void 0!==a.canvas?a.canvas:document.createElementNS("http://www.w3.org/1999/xhtml",
-"canvas"),z=void 0!==a.context?a.context:null,x=void 0!==a.alpha?a.alpha:!1,C=void 0!==a.depth?a.depth:!0,y=void 0!==a.stencil?a.stencil:!0,Q=void 0!==a.antialias?a.antialias:!1,fa=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,A=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,F=void 0!==a.powerPreference?a.powerPreference:"default",E=null,D=null;this.domElement=w;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;
+"canvas"),z=void 0!==a.context?a.context:null,x=void 0!==a.alpha?a.alpha:!1,C=void 0!==a.depth?a.depth:!0,y=void 0!==a.stencil?a.stencil:!0,Q=void 0!==a.antialias?a.antialias:!1,fa=void 0!==a.premultipliedAlpha?a.premultipliedAlpha:!0,A=void 0!==a.preserveDrawingBuffer?a.preserveDrawingBuffer:!1,E=void 0!==a.powerPreference?a.powerPreference:"default",F=null,D=null;this.domElement=w;this.context=null;this.sortObjects=this.autoClearStencil=this.autoClearDepth=this.autoClearColor=this.autoClear=!0;
 this.clippingPlanes=[];this.localClippingEnabled=!1;this.gammaFactor=2;this.physicallyCorrectLights=this.gammaOutput=this.gammaInput=!1;this.toneMappingWhitePoint=this.toneMappingExposure=this.toneMapping=1;this.maxMorphTargets=8;this.maxMorphNormals=4;var X=this,K=!1,L=null,G=null,M=null,P=-1;var V=b=null;var ta=!1;var Pb=null,R=null,S=new ba,W=new ba,ca=null,ia=0,U=w.width,N=w.height,T=1,ea=new ba(0,0,U,N),aa=new ba(0,0,U,N),pa=!1,sa=new vd,Y=new cg,yd=!1,he=!1,Ec=new J,ib=new n;try{x={alpha:x,
-depth:C,stencil:y,antialias:Q,premultipliedAlpha:fa,preserveDrawingBuffer:A,powerPreference:F};w.addEventListener("webglcontextlost",d,!1);w.addEventListener("webglcontextrestored",e,!1);var O=z||w.getContext("webgl",x)||w.getContext("experimental-webgl",x);if(null===O){if(null!==w.getContext("webgl"))throw Error("Error creating WebGL context with your selected attributes.");throw Error("Error creating WebGL context.");}void 0===O.getShaderPrecisionFormat&&(O.getShaderPrecisionFormat=function(){return{rangeMin:1,
+depth:C,stencil:y,antialias:Q,premultipliedAlpha:fa,preserveDrawingBuffer:A,powerPreference:E};w.addEventListener("webglcontextlost",d,!1);w.addEventListener("webglcontextrestored",e,!1);var O=z||w.getContext("webgl",x)||w.getContext("experimental-webgl",x);if(null===O){if(null!==w.getContext("webgl"))throw Error("Error creating WebGL context with your selected attributes.");throw Error("Error creating WebGL context.");}void 0===O.getShaderPrecisionFormat&&(O.getShaderPrecisionFormat=function(){return{rangeMin:1,
 rangeMax:1,precision:1}})}catch(uf){throw console.error("THREE.WebGLRenderer: "+uf.message),uf;}var la,za,Z,ha,Da,da,ra,ua,oa,ma,va,qa,na,xa,Aa,Ba,ja;c();var ka=null;"undefined"!==typeof navigator&&(ka="xr"in navigator?new ch(X):new tf(X));this.vr=ka;var Ca=new of(X,oa,za.maxTextureSize);this.shadowMap=Ca;this.getContext=function(){return O};this.getContextAttributes=function(){return O.getContextAttributes()};this.forceContextLoss=function(){var a=la.get("WEBGL_lose_context");a&&a.loseContext()};
 this.forceContextRestore=function(){var a=la.get("WEBGL_lose_context");a&&a.restoreContext()};this.getPixelRatio=function(){return T};this.setPixelRatio=function(a){void 0!==a&&(T=a,this.setSize(U,N,!1))};this.getSize=function(a){void 0===a&&(console.warn("WebGLRenderer: .getsize() now requires a Vector2 as an argument"),a=new B);return a.set(U,N)};this.setSize=function(a,b,c){ka.isPresenting()?console.warn("THREE.WebGLRenderer: Can't change size while VR device is presenting."):(U=a,N=b,w.width=
 a*T,w.height=b*T,!1!==c&&(w.style.width=a+"px",w.style.height=b+"px"),this.setViewport(0,0,a,b))};this.getDrawingBufferSize=function(a){void 0===a&&(console.warn("WebGLRenderer: .getdrawingBufferSize() now requires a Vector2 as an argument"),a=new B);return a.set(U*T,N*T)};this.setDrawingBufferSize=function(a,b,c){U=a;N=b;T=c;w.width=a*c;w.height=b*c;this.setViewport(0,0,a,b)};this.getCurrentViewport=function(a){void 0===a&&(console.warn("WebGLRenderer: .getCurrentViewport() now requires a Vector4 as an argument"),
@@ -198,41 +198,41 @@ n,z,u,0,0)}}else if(void 0!==v&&(u=v[A],void 0!==u))switch(u.length){case 2:O.ve
 e.wireframe)Z.setLineWidth(e.wireframeLinewidth*(null===G?T:1)),a.setMode(1);else switch(f.drawMode){case 0:a.setMode(4);break;case 1:a.setMode(5);break;case 2:a.setMode(6)}else f.isLine?(e=e.linewidth,void 0===e&&(e=1),Z.setLineWidth(e*(null===G?T:1)),f.isLineSegments?a.setMode(1):f.isLineLoop?a.setMode(2):a.setMode(3)):f.isPoints?a.setMode(0):f.isSprite&&a.setMode(4);d&&d.isInstancedBufferGeometry?0<d.maxInstancedCount&&a.renderInstances(d,A,g):a.render(A,g)}};this.compile=function(a,b){D=qa.get(a,
 b);D.init();a.traverse(function(a){a.isLight&&(D.pushLight(a),a.castShadow&&D.pushShadow(a))});D.setupLights(b);a.traverse(function(b){if(b.material)if(Array.isArray(b.material))for(var c=0;c<b.material.length;c++)p(b.material[c],a.fog,b);else p(b.material,a.fog,b)})};var ya=null,wa=new ae;wa.setAnimationLoop(function(a){ka.isPresenting()||ya&&ya(a)});"undefined"!==typeof window&&wa.setContext(window);this.setAnimationLoop=function(a){ya=a;ka.setAnimationLoop(a);wa.start()};this.render=function(a,
 c,d,e){if(void 0!==d){console.warn("THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.");var f=d}if(void 0!==e){console.warn("THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.");var g=e}c&&c.isCamera?K||(V=b=null,ta=!1,P=-1,Pb=null,!0===a.autoUpdate&&a.updateMatrixWorld(),null===c.parent&&c.updateMatrixWorld(),ka.enabled&&(c=ka.getCamera(c)),D=qa.get(a,c),D.init(),a.onBeforeRender(X,a,c,f||G),Ec.multiplyMatrices(c.projectionMatrix,
-c.matrixWorldInverse),sa.setFromMatrix(Ec),he=this.localClippingEnabled,yd=Y.init(this.clippingPlanes,he,c),E=va.get(a,c),E.init(),k(a,c,0,X.sortObjects),!0===X.sortObjects&&E.sort(),yd&&Y.beginShadows(),Ca.render(D.state.shadowsArray,a,c),D.setupLights(c),yd&&Y.endShadows(),this.info.autoReset&&this.info.reset(),void 0!==f&&this.setRenderTarget(f),na.render(E,a,c,g),d=E.opaque,e=E.transparent,a.overrideMaterial?(f=a.overrideMaterial,d.length&&m(d,a,c,f),e.length&&m(e,a,c,f)):(d.length&&m(d,a,c),
-e.length&&m(e,a,c)),null!==G&&(da.updateRenderTargetMipmap(G),da.updateMultisampleRenderTarget(G)),Z.buffers.depth.setTest(!0),Z.buffers.depth.setMask(!0),Z.buffers.color.setMask(!0),Z.setPolygonOffset(!1),a.onAfterRender(X,a,c),ka.enabled&&ka.submitFrame(),D=E=null):console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.")};this.allocTextureUnit=function(){var a=ia;a>=za.maxTextures&&console.warn("THREE.WebGLRenderer: Trying to use "+a+" texture units while this GPU supports only "+
+c.matrixWorldInverse),sa.setFromMatrix(Ec),he=this.localClippingEnabled,yd=Y.init(this.clippingPlanes,he,c),F=va.get(a,c),F.init(),k(a,c,0,X.sortObjects),!0===X.sortObjects&&F.sort(),yd&&Y.beginShadows(),Ca.render(D.state.shadowsArray,a,c),D.setupLights(c),yd&&Y.endShadows(),this.info.autoReset&&this.info.reset(),void 0!==f&&this.setRenderTarget(f),na.render(F,a,c,g),d=F.opaque,e=F.transparent,a.overrideMaterial?(f=a.overrideMaterial,d.length&&m(d,a,c,f),e.length&&m(e,a,c,f)):(d.length&&m(d,a,c),
+e.length&&m(e,a,c)),null!==G&&(da.updateRenderTargetMipmap(G),da.updateMultisampleRenderTarget(G)),Z.buffers.depth.setTest(!0),Z.buffers.depth.setMask(!0),Z.buffers.color.setMask(!0),Z.setPolygonOffset(!1),a.onAfterRender(X,a,c),ka.enabled&&ka.submitFrame(),D=F=null):console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.")};this.allocTextureUnit=function(){var a=ia;a>=za.maxTextures&&console.warn("THREE.WebGLRenderer: Trying to use "+a+" texture units while this GPU supports only "+
 za.maxTextures);ia+=1;return a};this.setTexture2D=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTarget&&(a||(console.warn("THREE.WebGLRenderer.setTexture2D: don't use render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);da.setTexture2D(b,c)}}();this.setTexture2DArray=function(a,b){da.setTexture2DArray(a,b)};this.setTexture3D=function(a,b){da.setTexture3D(a,b)};this.setTexture=function(){var a=!1;return function(b,c){a||(console.warn("THREE.WebGLRenderer: .setTexture is deprecated, use setTexture2D instead."),
 a=!0);da.setTexture2D(b,c)}}();this.setTextureCube=function(){var a=!1;return function(b,c){b&&b.isWebGLRenderTargetCube&&(a||(console.warn("THREE.WebGLRenderer.setTextureCube: don't use cube render targets as textures. Use their .texture property instead."),a=!0),b=b.texture);b&&b.isCubeTexture||Array.isArray(b.image)&&6===b.image.length?da.setTextureCube(b,c):da.setTextureCubeDynamic(b,c)}}();this.setFramebuffer=function(a){L=a};this.getRenderTarget=function(){return G};this.setRenderTarget=function(a,
 b,c){(G=a)&&void 0===Da.get(a).__webglFramebuffer&&da.setupRenderTarget(a);var d=L,e=!1;a?(d=Da.get(a).__webglFramebuffer,a.isWebGLRenderTargetCube?(d=d[b||0],e=!0):d=a.isWebGLMultisampleRenderTarget?Da.get(a).__webglMultisampledFramebuffer:d,S.copy(a.viewport),W.copy(a.scissor),ca=a.scissorTest):(S.copy(ea).multiplyScalar(T),W.copy(aa).multiplyScalar(T),ca=pa);M!==d&&(O.bindFramebuffer(36160,d),M=d);Z.viewport(S);Z.scissor(W);Z.setScissorTest(ca);e&&(a=Da.get(a.texture),O.framebufferTexture2D(36160,
 36064,34069+(b||0),a.__webglTexture,c||0))};this.readRenderTargetPixels=function(a,b,c,d,e,f){if(a&&a.isWebGLRenderTarget){var g=Da.get(a).__webglFramebuffer;if(g){var h=!1;g!==M&&(O.bindFramebuffer(36160,g),h=!0);try{var k=a.texture,m=k.format,q=k.type;1023!==m&&ja.convert(m)!==O.getParameter(35739)?console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format."):1009===q||ja.convert(q)===O.getParameter(35738)||1015===q&&(za.isWebGL2||la.get("OES_texture_float")||
 la.get("WEBGL_color_buffer_float"))||1016===q&&(za.isWebGL2?la.get("EXT_color_buffer_float"):la.get("EXT_color_buffer_half_float"))?36053===O.checkFramebufferStatus(36160)?0<=b&&b<=a.width-d&&0<=c&&c<=a.height-e&&O.readPixels(b,c,d,e,ja.convert(m),ja.convert(q),f):console.error("THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete."):console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.")}finally{h&&
 O.bindFramebuffer(36160,M)}}}else console.error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.")};this.copyFramebufferToTexture=function(a,b,c){var d=b.image.width,e=b.image.height,f=ja.convert(b.format);this.setTexture2D(b,0);O.copyTexImage2D(3553,c||0,f,a.x,a.y,d,e,0)};this.copyTextureToTexture=function(a,b,c,d){var e=b.image.width,f=b.image.height,g=ja.convert(c.format),h=ja.convert(c.type);this.setTexture2D(c,0);b.isDataTexture?O.texSubImage2D(3553,d||
-0,a.x,a.y,e,f,g,h,b.image.data):O.texSubImage2D(3553,d||0,a.x,a.y,g,h,b.image)}}function zd(a,b){this.name="";this.color=new K(a);this.density=void 0!==b?b:2.5E-4}function Ad(a,b,c){this.name="";this.color=new K(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3}function Bd(){E.call(this);this.type="Scene";this.overrideMaterial=this.fog=this.background=null;this.autoUpdate=!0}function ub(a,b){this.array=a;this.stride=b;this.count=void 0!==a?a.length/b:0;this.dynamic=!1;this.updateRange={offset:0,
-count:-1};this.version=0}function Gc(a,b,c,d){this.data=a;this.itemSize=b;this.offset=c;this.normalized=!0===d}function jb(a){M.call(this);this.type="SpriteMaterial";this.color=new K(16777215);this.map=null;this.rotation=0;this.sizeAttenuation=!0;this.lights=!1;this.transparent=!0;this.setValues(a)}function Hc(a){E.call(this);this.type="Sprite";if(void 0===Ub){Ub=new D;var b=new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]);b=new ub(b,5);Ub.setIndex([0,1,2,0,2,3]);Ub.addAttribute("position",
-new Gc(b,3,0,!1));Ub.addAttribute("uv",new Gc(b,2,3,!1))}this.geometry=Ub;this.material=void 0!==a?a:new jb;this.center=new B(.5,.5)}function Ic(){E.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function Jc(a,b){a&&a.isGeometry&&console.error("THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.");va.call(this,a,b);this.type="SkinnedMesh";this.bindMode="attached";this.bindMatrix=new J;this.bindMatrixInverse=new J}function Cd(a,
-b){a=a||[];this.bones=a.slice(0);this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton boneInverses is the wrong length."),this.boneInverses=[],a=0,b=this.bones.length;a<b;a++)this.boneInverses.push(new J)}function je(){E.call(this);this.type="Bone"}function R(a){M.call(this);this.type="LineBasicMaterial";this.color=new K(16777215);this.linewidth=1;this.linejoin=
-this.linecap="round";this.lights=!1;this.setValues(a)}function da(a,b,c){1===c&&console.error("THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.");E.call(this);this.type="Line";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new R({color:16777215*Math.random()})}function W(a,b){da.call(this,a,b);this.type="LineSegments"}function Dd(a,b){da.call(this,a,b);this.type="LineLoop"}function Ia(a){M.call(this);this.type="PointsMaterial";this.color=new K(16777215);
-this.map=null;this.size=1;this.sizeAttenuation=!0;this.lights=this.morphTargets=!1;this.setValues(a)}function Vb(a,b){E.call(this);this.type="Points";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new Ia({color:16777215*Math.random()})}function ke(a,b,c,d,e,f,g,h,k){S.call(this,a,b,c,d,e,f,g,h,k);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Wb(a,b,c,d,e,f,g,h,k,m,q,p){S.call(this,null,f,g,h,k,m,d,e,q,
+0,a.x,a.y,e,f,g,h,b.image.data):O.texSubImage2D(3553,d||0,a.x,a.y,g,h,b.image)}}function zd(a,b){this.name="";this.color=new K(a);this.density=void 0!==b?b:2.5E-4}function Ad(a,b,c){this.name="";this.color=new K(a);this.near=void 0!==b?b:1;this.far=void 0!==c?c:1E3}function Bd(){F.call(this);this.type="Scene";this.overrideMaterial=this.fog=this.background=null;this.autoUpdate=!0}function ub(a,b){this.array=a;this.stride=b;this.count=void 0!==a?a.length/b:0;this.dynamic=!1;this.updateRange={offset:0,
+count:-1};this.version=0}function Gc(a,b,c,d){this.data=a;this.itemSize=b;this.offset=c;this.normalized=!0===d}function jb(a){M.call(this);this.type="SpriteMaterial";this.color=new K(16777215);this.map=null;this.rotation=0;this.sizeAttenuation=!0;this.lights=!1;this.transparent=!0;this.setValues(a)}function Hc(a){F.call(this);this.type="Sprite";if(void 0===Ub){Ub=new D;var b=new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]);b=new ub(b,5);Ub.setIndex([0,1,2,0,2,3]);Ub.addAttribute("position",
+new Gc(b,3,0,!1));Ub.addAttribute("uv",new Gc(b,2,3,!1))}this.geometry=Ub;this.material=void 0!==a?a:new jb;this.center=new B(.5,.5)}function Ic(){F.call(this);this.type="LOD";Object.defineProperties(this,{levels:{enumerable:!0,value:[]}})}function Jc(a,b){a&&a.isGeometry&&console.error("THREE.SkinnedMesh no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.");va.call(this,a,b);this.type="SkinnedMesh";this.bindMode="attached";this.bindMatrix=new J;this.bindMatrixInverse=new J}function Cd(a,
+b){a=a||[];this.bones=a.slice(0);this.boneMatrices=new Float32Array(16*this.bones.length);if(void 0===b)this.calculateInverses();else if(this.bones.length===b.length)this.boneInverses=b.slice(0);else for(console.warn("THREE.Skeleton boneInverses is the wrong length."),this.boneInverses=[],a=0,b=this.bones.length;a<b;a++)this.boneInverses.push(new J)}function je(){F.call(this);this.type="Bone"}function R(a){M.call(this);this.type="LineBasicMaterial";this.color=new K(16777215);this.linewidth=1;this.linejoin=
+this.linecap="round";this.lights=!1;this.setValues(a)}function da(a,b,c){1===c&&console.error("THREE.Line: parameter THREE.LinePieces no longer supported. Use THREE.LineSegments instead.");F.call(this);this.type="Line";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new R({color:16777215*Math.random()})}function W(a,b){da.call(this,a,b);this.type="LineSegments"}function Dd(a,b){da.call(this,a,b);this.type="LineLoop"}function Ia(a){M.call(this);this.type="PointsMaterial";this.color=new K(16777215);
+this.map=null;this.size=1;this.sizeAttenuation=!0;this.lights=this.morphTargets=!1;this.setValues(a)}function Vb(a,b){F.call(this);this.type="Points";this.geometry=void 0!==a?a:new D;this.material=void 0!==b?b:new Ia({color:16777215*Math.random()})}function ke(a,b,c,d,e,f,g,h,k){S.call(this,a,b,c,d,e,f,g,h,k);this.format=void 0!==g?g:1022;this.minFilter=void 0!==f?f:1006;this.magFilter=void 0!==e?e:1006;this.generateMipmaps=!1}function Wb(a,b,c,d,e,f,g,h,k,m,q,p){S.call(this,null,f,g,h,k,m,d,e,q,
 p);this.image={width:b,height:c};this.mipmaps=a;this.generateMipmaps=this.flipY=!1}function Kc(a,b,c,d,e,f,g,h,k){S.call(this,a,b,c,d,e,f,g,h,k);this.needsUpdate=!0}function Lc(a,b,c,d,e,f,g,h,k,m){m=void 0!==m?m:1026;if(1026!==m&&1027!==m)throw Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");void 0===c&&1026===m&&(c=1012);void 0===c&&1027===m&&(c=1020);S.call(this,null,d,e,f,g,h,m,c,k);this.image={width:a,height:b};this.magFilter=void 0!==g?g:1003;this.minFilter=
 void 0!==h?h:1003;this.generateMipmaps=this.flipY=!1}function Xb(a){D.call(this);this.type="WireframeGeometry";var b=[],c,d,e,f=[0,0],g={},h=["a","b","c"];if(a&&a.isGeometry){var k=a.faces;var m=0;for(d=k.length;m<d;m++){var q=k[m];for(c=0;3>c;c++){var p=q[h[c]];var l=q[h[(c+1)%3]];f[0]=Math.min(p,l);f[1]=Math.max(p,l);p=f[0]+","+f[1];void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]})}}for(p in g)m=g[p],h=a.vertices[m.index1],b.push(h.x,h.y,h.z),h=a.vertices[m.index2],b.push(h.x,h.y,h.z)}else if(a&&
 a.isBufferGeometry)if(h=new n,null!==a.index){k=a.attributes.position;q=a.index;var t=a.groups;0===t.length&&(t=[{start:0,count:q.count,materialIndex:0}]);a=0;for(e=t.length;a<e;++a)for(m=t[a],c=m.start,d=m.count,m=c,d=c+d;m<d;m+=3)for(c=0;3>c;c++)p=q.getX(m+c),l=q.getX(m+(c+1)%3),f[0]=Math.min(p,l),f[1]=Math.max(p,l),p=f[0]+","+f[1],void 0===g[p]&&(g[p]={index1:f[0],index2:f[1]});for(p in g)m=g[p],h.fromBufferAttribute(k,m.index1),b.push(h.x,h.y,h.z),h.fromBufferAttribute(k,m.index2),b.push(h.x,
-h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;m<d;m++)for(c=0;3>c;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new F(b,3))}function Mc(a,b,c){G.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Yb(a,b,c));this.mergeVertices()}function Yb(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,
+h.y,h.z)}else for(k=a.attributes.position,m=0,d=k.count/3;m<d;m++)for(c=0;3>c;c++)g=3*m+c,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z),g=3*m+(c+1)%3,h.fromBufferAttribute(k,g),b.push(h.x,h.y,h.z);this.addAttribute("position",new E(b,3))}function Mc(a,b,c){G.call(this);this.type="ParametricGeometry";this.parameters={func:a,slices:b,stacks:c};this.fromBufferGeometry(new Yb(a,b,c));this.mergeVertices()}function Yb(a,b,c){D.call(this);this.type="ParametricBufferGeometry";this.parameters={func:a,slices:b,
 stacks:c};var d=[],e=[],f=[],g=[],h=new n,k=new n,m=new n,q=new n,p=new n,l,t;3>a.length&&console.error("THREE.ParametricGeometry: Function must now modify a Vector3 as third parameter.");var r=b+1;for(l=0;l<=c;l++){var u=l/c;for(t=0;t<=b;t++){var w=t/b;a(w,u,k);e.push(k.x,k.y,k.z);0<=w-1E-5?(a(w-1E-5,u,m),q.subVectors(k,m)):(a(w+1E-5,u,m),q.subVectors(m,k));0<=u-1E-5?(a(w,u-1E-5,m),p.subVectors(k,m)):(a(w,u+1E-5,m),p.subVectors(m,k));h.crossVectors(q,p).normalize();f.push(h.x,h.y,h.z);g.push(w,u)}}for(l=
-0;l<c;l++)for(t=0;t<b;t++)a=l*r+t+1,h=(l+1)*r+t+1,k=(l+1)*r+t,d.push(l*r+t,a,k),d.push(a,h,k);this.setIndex(d);this.addAttribute("position",new F(e,3));this.addAttribute("normal",new F(f,3));this.addAttribute("uv",new F(g,2))}function Nc(a,b,c,d){G.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};this.fromBufferGeometry(new Aa(a,b,c,d));this.mergeVertices()}function Aa(a,b,c,d){function e(a){h.push(a.x,a.y,a.z)}function f(b,c){b*=3;c.x=a[b+0];c.y=
+0;l<c;l++)for(t=0;t<b;t++)a=l*r+t+1,h=(l+1)*r+t+1,k=(l+1)*r+t,d.push(l*r+t,a,k),d.push(a,h,k);this.setIndex(d);this.addAttribute("position",new E(e,3));this.addAttribute("normal",new E(f,3));this.addAttribute("uv",new E(g,2))}function Nc(a,b,c,d){G.call(this);this.type="PolyhedronGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};this.fromBufferGeometry(new Aa(a,b,c,d));this.mergeVertices()}function Aa(a,b,c,d){function e(a){h.push(a.x,a.y,a.z)}function f(b,c){b*=3;c.x=a[b+0];c.y=
 a[b+1];c.z=a[b+2]}function g(a,b,c,d){0>d&&1===a.x&&(k[b]=a.x-1);0===c.x&&0===c.z&&(k[b]=d/2/Math.PI+.5)}D.call(this);this.type="PolyhedronBufferGeometry";this.parameters={vertices:a,indices:b,radius:c,detail:d};c=c||1;d=d||0;var h=[],k=[];(function(a){for(var c=new n,d=new n,g=new n,h=0;h<b.length;h+=3){f(b[h+0],c);f(b[h+1],d);f(b[h+2],g);var k,m,l=c,z=d,x=g,C=Math.pow(2,a),y=[];for(m=0;m<=C;m++){y[m]=[];var Q=l.clone().lerp(x,m/C),B=z.clone().lerp(x,m/C),A=C-m;for(k=0;k<=A;k++)y[m][k]=0===k&&m===
 C?Q:Q.clone().lerp(B,k/A)}for(m=0;m<C;m++)for(k=0;k<2*(C-m)-1;k++)l=Math.floor(k/2),0===k%2?(e(y[m][l+1]),e(y[m+1][l]),e(y[m][l])):(e(y[m][l+1]),e(y[m+1][l+1]),e(y[m+1][l]))}})(d);(function(a){for(var b=new n,c=0;c<h.length;c+=3)b.x=h[c+0],b.y=h[c+1],b.z=h[c+2],b.normalize().multiplyScalar(a),h[c+0]=b.x,h[c+1]=b.y,h[c+2]=b.z})(c);(function(){for(var a=new n,b=0;b<h.length;b+=3)a.x=h[b+0],a.y=h[b+1],a.z=h[b+2],k.push(Math.atan2(a.z,-a.x)/2/Math.PI+.5,1-(Math.atan2(-a.y,Math.sqrt(a.x*a.x+a.z*a.z))/
 Math.PI+.5));a=new n;b=new n;for(var c=new n,d=new n,e=new B,f=new B,l=new B,w=0,z=0;w<h.length;w+=9,z+=6){a.set(h[w+0],h[w+1],h[w+2]);b.set(h[w+3],h[w+4],h[w+5]);c.set(h[w+6],h[w+7],h[w+8]);e.set(k[z+0],k[z+1]);f.set(k[z+2],k[z+3]);l.set(k[z+4],k[z+5]);d.copy(a).add(b).add(c).divideScalar(3);var x=Math.atan2(d.z,-d.x);g(e,z+0,a,x);g(f,z+2,b,x);g(l,z+4,c,x)}for(a=0;a<k.length;a+=6)b=k[a+0],c=k[a+2],d=k[a+4],e=Math.min(b,c,d),.9<Math.max(b,c,d)&&.1>e&&(.2>b&&(k[a+0]+=1),.2>c&&(k[a+2]+=1),.2>d&&(k[a+
-4]+=1))})();this.addAttribute("position",new F(h,3));this.addAttribute("normal",new F(h.slice(),3));this.addAttribute("uv",new F(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Oc(a,b){G.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Zb(a,b));this.mergeVertices()}function Zb(a,b){Aa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,
+4]+=1))})();this.addAttribute("position",new E(h,3));this.addAttribute("normal",new E(h.slice(),3));this.addAttribute("uv",new E(k,2));0===d?this.computeVertexNormals():this.normalizeNormals()}function Oc(a,b){G.call(this);this.type="TetrahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new Zb(a,b));this.mergeVertices()}function Zb(a,b){Aa.call(this,[1,1,1,-1,-1,1,-1,1,-1,1,-1,-1],[2,1,0,0,3,2,1,3,0,2,3,1],a,b);this.type="TetrahedronBufferGeometry";this.parameters={radius:a,
 detail:b}}function Pc(a,b){G.call(this);this.type="OctahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new vb(a,b));this.mergeVertices()}function vb(a,b){Aa.call(this,[1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1],[0,2,4,0,4,3,0,3,5,0,5,2,1,2,5,1,5,3,1,3,4,1,4,2],a,b);this.type="OctahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Qc(a,b){G.call(this);this.type="IcosahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new $b(a,b));this.mergeVertices()}
 function $b(a,b){var c=(1+Math.sqrt(5))/2;Aa.call(this,[-1,c,0,1,c,0,-1,-c,0,1,-c,0,0,-1,c,0,1,c,0,-1,-c,0,1,-c,c,0,-1,c,0,1,-c,0,-1,-c,0,1],[0,11,5,0,5,1,0,1,7,0,7,10,0,10,11,1,5,9,5,11,4,11,10,2,10,7,6,7,1,8,3,9,4,3,4,2,3,2,6,3,6,8,3,8,9,4,9,5,2,4,11,6,2,10,8,6,7,9,8,1],a,b);this.type="IcosahedronBufferGeometry";this.parameters={radius:a,detail:b}}function Rc(a,b){G.call(this);this.type="DodecahedronGeometry";this.parameters={radius:a,detail:b};this.fromBufferGeometry(new ac(a,b));this.mergeVertices()}
 function ac(a,b){var c=(1+Math.sqrt(5))/2,d=1/c;Aa.call(this,[-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-d,-c,0,-d,c,0,d,-c,0,d,c,-d,-c,0,-d,c,0,d,-c,0,d,c,0,-c,0,-d,c,0,-d,-c,0,d,c,0,d],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],a,b);this.type="DodecahedronBufferGeometry";
 this.parameters={radius:a,detail:b}}function Sc(a,b,c,d,e,f){G.call(this);this.type="TubeGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};void 0!==f&&console.warn("THREE.TubeGeometry: taper has been removed.");a=new wb(a,b,c,d,e);this.tangents=a.tangents;this.normals=a.normals;this.binormals=a.binormals;this.fromBufferGeometry(a);this.mergeVertices()}function wb(a,b,c,d,e){function f(e){q=a.getPointAt(e/b,q);var f=g.normals[e];e=g.binormals[e];for(l=0;l<=d;l++){var m=
 l/d*Math.PI*2,p=Math.sin(m);m=-Math.cos(m);k.x=m*f.x+p*e.x;k.y=m*f.y+p*e.y;k.z=m*f.z+p*e.z;k.normalize();r.push(k.x,k.y,k.z);h.x=q.x+c*k.x;h.y=q.y+c*k.y;h.z=q.z+c*k.z;t.push(h.x,h.y,h.z)}}D.call(this);this.type="TubeBufferGeometry";this.parameters={path:a,tubularSegments:b,radius:c,radialSegments:d,closed:e};b=b||64;c=c||1;d=d||8;e=e||!1;var g=a.computeFrenetFrames(b,e);this.tangents=g.tangents;this.normals=g.normals;this.binormals=g.binormals;var h=new n,k=new n,m=new B,q=new n,p,l,t=[],r=[],u=[],
-w=[];for(p=0;p<b;p++)f(p);f(!1===e?b:0);for(p=0;p<=b;p++)for(l=0;l<=d;l++)m.x=p/b,m.y=l/d,u.push(m.x,m.y);(function(){for(l=1;l<=b;l++)for(p=1;p<=d;p++){var a=(d+1)*l+(p-1),c=(d+1)*l+p,e=(d+1)*(l-1)+p;w.push((d+1)*(l-1)+(p-1),a,e);w.push(a,c,e)}})();this.setIndex(w);this.addAttribute("position",new F(t,3));this.addAttribute("normal",new F(r,3));this.addAttribute("uv",new F(u,2))}function Tc(a,b,c,d,e,f,g){G.call(this);this.type="TorusKnotGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,
+w=[];for(p=0;p<b;p++)f(p);f(!1===e?b:0);for(p=0;p<=b;p++)for(l=0;l<=d;l++)m.x=p/b,m.y=l/d,u.push(m.x,m.y);(function(){for(l=1;l<=b;l++)for(p=1;p<=d;p++){var a=(d+1)*l+(p-1),c=(d+1)*l+p,e=(d+1)*(l-1)+p;w.push((d+1)*(l-1)+(p-1),a,e);w.push(a,c,e)}})();this.setIndex(w);this.addAttribute("position",new E(t,3));this.addAttribute("normal",new E(r,3));this.addAttribute("uv",new E(u,2))}function Tc(a,b,c,d,e,f,g){G.call(this);this.type="TorusKnotGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,
 radialSegments:d,p:e,q:f};void 0!==g&&console.warn("THREE.TorusKnotGeometry: heightScale has been deprecated. Use .scale( x, y, z ) instead.");this.fromBufferGeometry(new bc(a,b,c,d,e,f));this.mergeVertices()}function bc(a,b,c,d,e,f){function g(a,b,c,d,e){var f=Math.sin(a);b=c/b*a;c=Math.cos(b);e.x=d*(2+c)*.5*Math.cos(a);e.y=d*(2+c)*f*.5;e.z=d*Math.sin(b)*.5}D.call(this);this.type="TorusKnotBufferGeometry";this.parameters={radius:a,tube:b,tubularSegments:c,radialSegments:d,p:e,q:f};a=a||1;b=b||.4;
 c=Math.floor(c)||64;d=Math.floor(d)||8;e=e||2;f=f||3;var h=[],k=[],m=[],q=[],p,l=new n,t=new n,r=new n,u=new n,w=new n,z=new n,x=new n;for(p=0;p<=c;++p){var C=p/c*e*Math.PI*2;g(C,e,f,a,r);g(C+.01,e,f,a,u);z.subVectors(u,r);x.addVectors(u,r);w.crossVectors(z,x);x.crossVectors(w,z);w.normalize();x.normalize();for(C=0;C<=d;++C){var y=C/d*Math.PI*2,Q=-b*Math.cos(y);y=b*Math.sin(y);l.x=r.x+(Q*x.x+y*w.x);l.y=r.y+(Q*x.y+y*w.y);l.z=r.z+(Q*x.z+y*w.z);k.push(l.x,l.y,l.z);t.subVectors(l,r).normalize();m.push(t.x,
-t.y,t.z);q.push(p/c);q.push(C/d)}}for(C=1;C<=c;C++)for(p=1;p<=d;p++)a=(d+1)*C+(p-1),b=(d+1)*C+p,e=(d+1)*(C-1)+p,h.push((d+1)*(C-1)+(p-1),a,e),h.push(a,b,e);this.setIndex(h);this.addAttribute("position",new F(k,3));this.addAttribute("normal",new F(m,3));this.addAttribute("uv",new F(q,2))}function Uc(a,b,c,d,e){G.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};this.fromBufferGeometry(new cc(a,b,c,d,e));this.mergeVertices()}function cc(a,
+t.y,t.z);q.push(p/c);q.push(C/d)}}for(C=1;C<=c;C++)for(p=1;p<=d;p++)a=(d+1)*C+(p-1),b=(d+1)*C+p,e=(d+1)*(C-1)+p,h.push((d+1)*(C-1)+(p-1),a,e),h.push(a,b,e);this.setIndex(h);this.addAttribute("position",new E(k,3));this.addAttribute("normal",new E(m,3));this.addAttribute("uv",new E(q,2))}function Uc(a,b,c,d,e){G.call(this);this.type="TorusGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};this.fromBufferGeometry(new cc(a,b,c,d,e));this.mergeVertices()}function cc(a,
 b,c,d,e){D.call(this);this.type="TorusBufferGeometry";this.parameters={radius:a,tube:b,radialSegments:c,tubularSegments:d,arc:e};a=a||1;b=b||.4;c=Math.floor(c)||8;d=Math.floor(d)||6;e=e||2*Math.PI;var f=[],g=[],h=[],k=[],m=new n,q=new n,p=new n,l,t;for(l=0;l<=c;l++)for(t=0;t<=d;t++){var r=t/d*e,u=l/c*Math.PI*2;q.x=(a+b*Math.cos(u))*Math.cos(r);q.y=(a+b*Math.cos(u))*Math.sin(r);q.z=b*Math.sin(u);g.push(q.x,q.y,q.z);m.x=a*Math.cos(r);m.y=a*Math.sin(r);p.subVectors(q,m).normalize();h.push(p.x,p.y,p.z);
-k.push(t/d);k.push(l/c)}for(l=1;l<=c;l++)for(t=1;t<=d;t++)a=(d+1)*(l-1)+t-1,b=(d+1)*(l-1)+t,e=(d+1)*l+t,f.push((d+1)*l+t-1,a,e),f.push(a,b,e);this.setIndex(f);this.addAttribute("position",new F(g,3));this.addAttribute("normal",new F(h,3));this.addAttribute("uv",new F(k,2))}function vf(a,b,c,d,e){for(var f,g=0,h=b,k=c-d;h<c;h+=d)g+=(a[k]-a[h])*(a[h+1]+a[k+1]),k=h;if(e===0<g)for(e=b;e<c;e+=d)f=wf(e,a[e],a[e+1],f);else for(e=c-d;e>=b;e-=d)f=wf(e,a[e],a[e+1],f);f&&xb(f,f.next)&&(Vc(f),f=f.next);return f}
+k.push(t/d);k.push(l/c)}for(l=1;l<=c;l++)for(t=1;t<=d;t++)a=(d+1)*(l-1)+t-1,b=(d+1)*(l-1)+t,e=(d+1)*l+t,f.push((d+1)*l+t-1,a,e),f.push(a,b,e);this.setIndex(f);this.addAttribute("position",new E(g,3));this.addAttribute("normal",new E(h,3));this.addAttribute("uv",new E(k,2))}function vf(a,b,c,d,e){for(var f,g=0,h=b,k=c-d;h<c;h+=d)g+=(a[k]-a[h])*(a[h+1]+a[k+1]),k=h;if(e===0<g)for(e=b;e<c;e+=d)f=wf(e,a[e],a[e+1],f);else for(e=c-d;e>=b;e-=d)f=wf(e,a[e],a[e+1],f);f&&xb(f,f.next)&&(Vc(f),f=f.next);return f}
 function Wc(a,b){if(!a)return a;b||(b=a);do{var c=!1;if(a.steiner||!xb(a,a.next)&&0!==qa(a.prev,a,a.next))a=a.next;else{Vc(a);a=b=a.prev;if(a===a.next)break;c=!0}}while(c||a!==b);return b}function Xc(a,b,c,d,e,f,g){if(a){if(!g&&f){var h=a,k=h;do null===k.z&&(k.z=le(k.x,k.y,d,e,f)),k.prevZ=k.prev,k=k.nextZ=k.next;while(k!==h);k.prevZ.nextZ=null;k.prevZ=null;h=k;var m,q,p,l,t=1;do{k=h;var r=h=null;for(q=0;k;){q++;var n=k;for(m=p=0;m<t&&(p++,n=n.nextZ,n);m++);for(l=t;0<p||0<l&&n;)0!==p&&(0===l||!n||
 k.z<=n.z)?(m=k,k=k.nextZ,p--):(m=n,n=n.nextZ,l--),r?r.nextZ=m:h=m,m.prevZ=r,r=m;k=n}r.nextZ=null;t*=2}while(1<q)}for(h=a;a.prev!==a.next;){k=a.prev;n=a.next;if(f)a:{r=a;l=d;var w=e,z=f;q=r.prev;p=r;t=r.next;if(0<=qa(q,p,t))r=!1;else{var x=q.x>p.x?q.x>t.x?q.x:t.x:p.x>t.x?p.x:t.x,C=q.y>p.y?q.y>t.y?q.y:t.y:p.y>t.y?p.y:t.y;m=le(q.x<p.x?q.x<t.x?q.x:t.x:p.x<t.x?p.x:t.x,q.y<p.y?q.y<t.y?q.y:t.y:p.y<t.y?p.y:t.y,l,w,z);l=le(x,C,l,w,z);for(w=r.nextZ;w&&w.z<=l;){if(w!==r.prev&&w!==r.next&&Ed(q.x,q.y,p.x,p.y,
 t.x,t.y,w.x,w.y)&&0<=qa(w.prev,w,w.next)){r=!1;break a}w=w.nextZ}for(w=r.prevZ;w&&w.z>=m;){if(w!==r.prev&&w!==r.next&&Ed(q.x,q.y,p.x,p.y,t.x,t.y,w.x,w.y)&&0<=qa(w.prev,w,w.next)){r=!1;break a}w=w.prevZ}r=!0}}else a:if(r=a,q=r.prev,p=r,t=r.next,0<=qa(q,p,t))r=!1;else{for(m=r.next.next;m!==r.prev;){if(Ed(q.x,q.y,p.x,p.y,t.x,t.y,m.x,m.y)&&0<=qa(m.prev,m,m.next)){r=!1;break a}m=m.next}r=!0}if(r)b.push(k.i/c),b.push(a.i/c),b.push(n.i/c),Vc(a),h=a=n.next;else if(a=n,a===h){if(!g)Xc(Wc(a),b,c,d,e,f,1);else if(1===
@@ -249,25 +249,25 @@ var E=!1;if(D){var X=D.getSpacedPoints(x);E=!0;y=!1;var G=D.computeFrenetFrames(
 R===T&&(R=0),z[N]=g(S[N],S[ea],S[R]);D=[];var da=z.concat();H=0;for(J=M.length;H<J;H++){P=M[H];var aa=[];N=0;T=P.length;ea=T-1;for(R=N+1;N<T;N++,ea++,R++)ea===T&&(ea=0),R===T&&(R=0),aa[N]=g(P[N],P[ea],P[R]);D.push(aa);da=da.concat(aa)}for(ea=0;ea<A;ea++){T=ea/A;var ca=Q*Math.cos(T*Math.PI/2);R=fa*Math.sin(T*Math.PI/2);N=0;for(T=S.length;N<T;N++){var Y=c(S[N],z[N],R);k(Y.x,Y.y,-ca)}H=0;for(J=M.length;H<J;H++)for(P=M[H],aa=D[H],N=0,T=P.length;N<T;N++)Y=c(P[N],aa[N],R),k(Y.x,Y.y,-ca)}R=fa;for(N=0;N<
 W;N++)Y=y?c(a[N],da[N],R):a[N],E?(K.copy(G.normals[0]).multiplyScalar(Y.x),I.copy(G.binormals[0]).multiplyScalar(Y.y),L.copy(X[0]).add(K).add(I),k(L.x,L.y,L.z)):k(Y.x,Y.y,0);for(T=1;T<=x;T++)for(N=0;N<W;N++)Y=y?c(a[N],da[N],R):a[N],E?(K.copy(G.normals[T]).multiplyScalar(Y.x),I.copy(G.binormals[T]).multiplyScalar(Y.y),L.copy(X[T]).add(K).add(I),k(L.x,L.y,L.z)):k(Y.x,Y.y,C/x*T);for(ea=A-1;0<=ea;ea--){T=ea/A;ca=Q*Math.cos(T*Math.PI/2);R=fa*Math.sin(T*Math.PI/2);N=0;for(T=S.length;N<T;N++)Y=c(S[N],z[N],
 R),k(Y.x,Y.y,C+ca);H=0;for(J=M.length;H<J;H++)for(P=M[H],aa=D[H],N=0,T=P.length;N<T;N++)Y=c(P[N],aa[N],R),E?k(Y.x,Y.y+X[x-1].y,X[x-1].x+ca):k(Y.x,Y.y,C+ca)}(function(){var a=e.length/3;if(y){var b=0*W;for(N=0;N<ba;N++)U=V[N],l(U[2]+b,U[1]+b,U[0]+b);b=W*(x+2*A);for(N=0;N<ba;N++)U=V[N],l(U[0]+b,U[1]+b,U[2]+b)}else{for(N=0;N<ba;N++)U=V[N],l(U[2],U[1],U[0]);for(N=0;N<ba;N++)U=V[N],l(U[0]+W*x,U[1]+W*x,U[2]+W*x)}d.addGroup(a,e.length/3-a,0)})();(function(){var a=e.length/3,b=0;h(S,b);b+=S.length;H=0;for(J=
-M.length;H<J;H++)P=M[H],h(P,b),b+=P.length;d.addGroup(a,e.length/3-a,1)})()}D.call(this);this.type="ExtrudeBufferGeometry";this.parameters={shapes:a,options:b};a=Array.isArray(a)?a:[a];for(var d=this,e=[],f=[],g=0,h=a.length;g<h;g++)c(a[g]);this.addAttribute("position",new F(e,3));this.addAttribute("uv",new F(f,2));this.computeVertexNormals()}function Bf(a,b,c){c.shapes=[];if(Array.isArray(a))for(var d=0,e=a.length;d<e;d++)c.shapes.push(a[d].uuid);else c.shapes.push(a.uuid);void 0!==b.extrudePath&&
+M.length;H<J;H++)P=M[H],h(P,b),b+=P.length;d.addGroup(a,e.length/3-a,1)})()}D.call(this);this.type="ExtrudeBufferGeometry";this.parameters={shapes:a,options:b};a=Array.isArray(a)?a:[a];for(var d=this,e=[],f=[],g=0,h=a.length;g<h;g++)c(a[g]);this.addAttribute("position",new E(e,3));this.addAttribute("uv",new E(f,2));this.computeVertexNormals()}function Bf(a,b,c){c.shapes=[];if(Array.isArray(a))for(var d=0,e=a.length;d<e;d++)c.shapes.push(a[d].uuid);else c.shapes.push(a.uuid);void 0!==b.extrudePath&&
 (c.options.extrudePath=b.extrudePath.toJSON());return c}function Zc(a,b){G.call(this);this.type="TextGeometry";this.parameters={text:a,parameters:b};this.fromBufferGeometry(new dc(a,b));this.mergeVertices()}function dc(a,b){b=b||{};var c=b.font;if(!c||!c.isFont)return console.error("THREE.TextGeometry: font parameter is not an instance of THREE.Font."),new G;a=c.generateShapes(a,b.size);b.depth=void 0!==b.height?b.height:50;void 0===b.bevelThickness&&(b.bevelThickness=10);void 0===b.bevelSize&&(b.bevelSize=
 8);void 0===b.bevelEnabled&&(b.bevelEnabled=!1);Va.call(this,a,b);this.type="TextBufferGeometry"}function $c(a,b,c,d,e,f,g){G.call(this);this.type="SphereGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,thetaLength:g};this.fromBufferGeometry(new zb(a,b,c,d,e,f,g));this.mergeVertices()}function zb(a,b,c,d,e,f,g){D.call(this);this.type="SphereBufferGeometry";this.parameters={radius:a,widthSegments:b,heightSegments:c,phiStart:d,phiLength:e,thetaStart:f,
 thetaLength:g};a=a||1;b=Math.max(3,Math.floor(b)||8);c=Math.max(2,Math.floor(c)||6);d=void 0!==d?d:0;e=void 0!==e?e:2*Math.PI;f=void 0!==f?f:0;g=void 0!==g?g:Math.PI;var h=f+g,k,m,q=0,p=[],l=new n,t=new n,r=[],u=[],w=[],z=[];for(m=0;m<=c;m++){var x=[],C=m/c;for(k=0;k<=b;k++){var y=k/b;l.x=-a*Math.cos(d+y*e)*Math.sin(f+C*g);l.y=a*Math.cos(f+C*g);l.z=a*Math.sin(d+y*e)*Math.sin(f+C*g);u.push(l.x,l.y,l.z);t.set(l.x,l.y,l.z).normalize();w.push(t.x,t.y,t.z);z.push(y,1-C);x.push(q++)}p.push(x)}for(m=0;m<
-c;m++)for(k=0;k<b;k++)a=p[m][k+1],d=p[m][k],e=p[m+1][k],g=p[m+1][k+1],(0!==m||0<f)&&r.push(a,d,g),(m!==c-1||h<Math.PI)&&r.push(d,e,g);this.setIndex(r);this.addAttribute("position",new F(u,3));this.addAttribute("normal",new F(w,3));this.addAttribute("uv",new F(z,2))}function ad(a,b,c,d,e,f){G.call(this);this.type="RingGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};this.fromBufferGeometry(new ec(a,b,c,d,e,f));this.mergeVertices()}function ec(a,
+c;m++)for(k=0;k<b;k++)a=p[m][k+1],d=p[m][k],e=p[m+1][k],g=p[m+1][k+1],(0!==m||0<f)&&r.push(a,d,g),(m!==c-1||h<Math.PI)&&r.push(d,e,g);this.setIndex(r);this.addAttribute("position",new E(u,3));this.addAttribute("normal",new E(w,3));this.addAttribute("uv",new E(z,2))}function ad(a,b,c,d,e,f){G.call(this);this.type="RingGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};this.fromBufferGeometry(new ec(a,b,c,d,e,f));this.mergeVertices()}function ec(a,
 b,c,d,e,f){D.call(this);this.type="RingBufferGeometry";this.parameters={innerRadius:a,outerRadius:b,thetaSegments:c,phiSegments:d,thetaStart:e,thetaLength:f};a=a||.5;b=b||1;e=void 0!==e?e:0;f=void 0!==f?f:2*Math.PI;c=void 0!==c?Math.max(3,c):8;d=void 0!==d?Math.max(1,d):1;var g=[],h=[],k=[],m=[],q=a,l=(b-a)/d,v=new n,t=new B,r,u;for(r=0;r<=d;r++){for(u=0;u<=c;u++)a=e+u/c*f,v.x=q*Math.cos(a),v.y=q*Math.sin(a),h.push(v.x,v.y,v.z),k.push(0,0,1),t.x=(v.x/b+1)/2,t.y=(v.y/b+1)/2,m.push(t.x,t.y);q+=l}for(r=
-0;r<d;r++)for(b=r*(c+1),u=0;u<c;u++)a=u+b,e=a+c+1,f=a+c+2,q=a+1,g.push(a,e,q),g.push(e,f,q);this.setIndex(g);this.addAttribute("position",new F(h,3));this.addAttribute("normal",new F(k,3));this.addAttribute("uv",new F(m,2))}function bd(a,b,c,d){G.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};this.fromBufferGeometry(new fc(a,b,c,d));this.mergeVertices()}function fc(a,b,c,d){D.call(this);this.type="LatheBufferGeometry";this.parameters={points:a,segments:b,
-phiStart:c,phiLength:d};b=Math.floor(b)||12;c=c||0;d=d||2*Math.PI;d=H.clamp(d,0,2*Math.PI);var e=[],f=[],g=[],h=1/b,k=new n,m=new B,q;for(q=0;q<=b;q++){var l=c+q*h*d;var v=Math.sin(l),t=Math.cos(l);for(l=0;l<=a.length-1;l++)k.x=a[l].x*v,k.y=a[l].y,k.z=a[l].x*t,f.push(k.x,k.y,k.z),m.x=q/b,m.y=l/(a.length-1),g.push(m.x,m.y)}for(q=0;q<b;q++)for(l=0;l<a.length-1;l++)c=l+q*a.length,h=c+a.length,k=c+a.length+1,m=c+1,e.push(c,h,m),e.push(h,k,m);this.setIndex(e);this.addAttribute("position",new F(f,3));this.addAttribute("uv",
-new F(g,2));this.computeVertexNormals();if(d===2*Math.PI)for(d=this.attributes.normal.array,e=new n,f=new n,g=new n,c=b*a.length*3,l=q=0;q<a.length;q++,l+=3)e.x=d[l+0],e.y=d[l+1],e.z=d[l+2],f.x=d[c+l+0],f.y=d[c+l+1],f.z=d[c+l+2],g.addVectors(e,f).normalize(),d[l+0]=d[c+l+0]=g.x,d[l+1]=d[c+l+1]=g.y,d[l+2]=d[c+l+2]=g.z}function Ab(a,b){G.call(this);this.type="ShapeGeometry";"object"===typeof b&&(console.warn("THREE.ShapeGeometry: Options parameter has been removed."),b=b.curveSegments);this.parameters=
+0;r<d;r++)for(b=r*(c+1),u=0;u<c;u++)a=u+b,e=a+c+1,f=a+c+2,q=a+1,g.push(a,e,q),g.push(e,f,q);this.setIndex(g);this.addAttribute("position",new E(h,3));this.addAttribute("normal",new E(k,3));this.addAttribute("uv",new E(m,2))}function bd(a,b,c,d){G.call(this);this.type="LatheGeometry";this.parameters={points:a,segments:b,phiStart:c,phiLength:d};this.fromBufferGeometry(new fc(a,b,c,d));this.mergeVertices()}function fc(a,b,c,d){D.call(this);this.type="LatheBufferGeometry";this.parameters={points:a,segments:b,
+phiStart:c,phiLength:d};b=Math.floor(b)||12;c=c||0;d=d||2*Math.PI;d=H.clamp(d,0,2*Math.PI);var e=[],f=[],g=[],h=1/b,k=new n,m=new B,q;for(q=0;q<=b;q++){var l=c+q*h*d;var v=Math.sin(l),t=Math.cos(l);for(l=0;l<=a.length-1;l++)k.x=a[l].x*v,k.y=a[l].y,k.z=a[l].x*t,f.push(k.x,k.y,k.z),m.x=q/b,m.y=l/(a.length-1),g.push(m.x,m.y)}for(q=0;q<b;q++)for(l=0;l<a.length-1;l++)c=l+q*a.length,h=c+a.length,k=c+a.length+1,m=c+1,e.push(c,h,m),e.push(h,k,m);this.setIndex(e);this.addAttribute("position",new E(f,3));this.addAttribute("uv",
+new E(g,2));this.computeVertexNormals();if(d===2*Math.PI)for(d=this.attributes.normal.array,e=new n,f=new n,g=new n,c=b*a.length*3,l=q=0;q<a.length;q++,l+=3)e.x=d[l+0],e.y=d[l+1],e.z=d[l+2],f.x=d[c+l+0],f.y=d[c+l+1],f.z=d[c+l+2],g.addVectors(e,f).normalize(),d[l+0]=d[c+l+0]=g.x,d[l+1]=d[c+l+1]=g.y,d[l+2]=d[c+l+2]=g.z}function Ab(a,b){G.call(this);this.type="ShapeGeometry";"object"===typeof b&&(console.warn("THREE.ShapeGeometry: Options parameter has been removed."),b=b.curveSegments);this.parameters=
 {shapes:a,curveSegments:b};this.fromBufferGeometry(new Bb(a,b));this.mergeVertices()}function Bb(a,b){function c(a){var c,h=e.length/3;a=a.extractPoints(b);var m=a.shape,q=a.holes;!1===ab.isClockWise(m)&&(m=m.reverse());a=0;for(c=q.length;a<c;a++){var l=q[a];!0===ab.isClockWise(l)&&(q[a]=l.reverse())}var n=ab.triangulateShape(m,q);a=0;for(c=q.length;a<c;a++)l=q[a],m=m.concat(l);a=0;for(c=m.length;a<c;a++)l=m[a],e.push(l.x,l.y,0),f.push(0,0,1),g.push(l.x,l.y);a=0;for(c=n.length;a<c;a++)m=n[a],d.push(m[0]+
-h,m[1]+h,m[2]+h),k+=3}D.call(this);this.type="ShapeBufferGeometry";this.parameters={shapes:a,curveSegments:b};b=b||12;var d=[],e=[],f=[],g=[],h=0,k=0;if(!1===Array.isArray(a))c(a);else for(var m=0;m<a.length;m++)c(a[m]),this.addGroup(h,k,m),h+=k,k=0;this.setIndex(d);this.addAttribute("position",new F(e,3));this.addAttribute("normal",new F(f,3));this.addAttribute("uv",new F(g,2))}function Cf(a,b){b.shapes=[];if(Array.isArray(a))for(var c=0,d=a.length;c<d;c++)b.shapes.push(a[c].uuid);else b.shapes.push(a.uuid);
+h,m[1]+h,m[2]+h),k+=3}D.call(this);this.type="ShapeBufferGeometry";this.parameters={shapes:a,curveSegments:b};b=b||12;var d=[],e=[],f=[],g=[],h=0,k=0;if(!1===Array.isArray(a))c(a);else for(var m=0;m<a.length;m++)c(a[m]),this.addGroup(h,k,m),h+=k,k=0;this.setIndex(d);this.addAttribute("position",new E(e,3));this.addAttribute("normal",new E(f,3));this.addAttribute("uv",new E(g,2))}function Cf(a,b){b.shapes=[];if(Array.isArray(a))for(var c=0,d=a.length;c<d;c++)b.shapes.push(a[c].uuid);else b.shapes.push(a.uuid);
 return b}function gc(a,b){D.call(this);this.type="EdgesGeometry";this.parameters={thresholdAngle:b};var c=[];b=Math.cos(H.DEG2RAD*(void 0!==b?b:1));var d=[0,0],e={},f=["a","b","c"];if(a.isBufferGeometry){var g=new G;g.fromBufferGeometry(a)}else g=a.clone();g.mergeVertices();g.computeFaceNormals();a=g.vertices;g=g.faces;for(var h=0,k=g.length;h<k;h++)for(var m=g[h],q=0;3>q;q++){var l=m[f[q]];var n=m[f[(q+1)%3]];d[0]=Math.min(l,n);d[1]=Math.max(l,n);l=d[0]+","+d[1];void 0===e[l]?e[l]={index1:d[0],index2:d[1],
-face1:h,face2:void 0}:e[l].face2=h}for(l in e)if(d=e[l],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new F(c,3))}function Cb(a,b,c,d,e,f,g,h){G.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new bb(a,b,c,d,e,f,g,h));this.mergeVertices()}function bb(a,
+face1:h,face2:void 0}:e[l].face2=h}for(l in e)if(d=e[l],void 0===d.face2||g[d.face1].normal.dot(g[d.face2].normal)<=b)f=a[d.index1],c.push(f.x,f.y,f.z),f=a[d.index2],c.push(f.x,f.y,f.z);this.addAttribute("position",new E(c,3))}function Cb(a,b,c,d,e,f,g,h){G.call(this);this.type="CylinderGeometry";this.parameters={radiusTop:a,radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};this.fromBufferGeometry(new bb(a,b,c,d,e,f,g,h));this.mergeVertices()}function bb(a,
 b,c,d,e,f,g,h){function k(c){var e,f=new B,k=new n,p=0,u=!0===c?a:b,x=!0===c?1:-1;var D=r;for(e=1;e<=d;e++)l.push(0,w*x,0),v.push(0,x,0),t.push(.5,.5),r++;var E=r;for(e=0;e<=d;e++){var F=e/d*h+g,H=Math.cos(F);F=Math.sin(F);k.x=u*F;k.y=w*x;k.z=u*H;l.push(k.x,k.y,k.z);v.push(0,x,0);f.x=.5*H+.5;f.y=.5*F*x+.5;t.push(f.x,f.y);r++}for(e=0;e<d;e++)f=D+e,k=E+e,!0===c?q.push(k,k+1,f):q.push(k+1,k,f),p+=3;m.addGroup(z,p,!0===c?1:2);z+=p}D.call(this);this.type="CylinderBufferGeometry";this.parameters={radiusTop:a,
 radiusBottom:b,height:c,radialSegments:d,heightSegments:e,openEnded:f,thetaStart:g,thetaLength:h};var m=this;a=void 0!==a?a:1;b=void 0!==b?b:1;c=c||1;d=Math.floor(d)||8;e=Math.floor(e)||1;f=void 0!==f?f:!1;g=void 0!==g?g:0;h=void 0!==h?h:2*Math.PI;var q=[],l=[],v=[],t=[],r=0,u=[],w=c/2,z=0;(function(){var f,k,p=new n,Q=new n,B=0,A=(b-a)/c;for(k=0;k<=e;k++){var D=[],F=k/e,E=F*(b-a)+a;for(f=0;f<=d;f++){var H=f/d,G=H*h+g,I=Math.sin(G);G=Math.cos(G);Q.x=E*I;Q.y=-F*c+w;Q.z=E*G;l.push(Q.x,Q.y,Q.z);p.set(I,
-A,G).normalize();v.push(p.x,p.y,p.z);t.push(H,1-F);D.push(r++)}u.push(D)}for(f=0;f<d;f++)for(k=0;k<e;k++)p=u[k+1][f],Q=u[k+1][f+1],A=u[k][f+1],q.push(u[k][f],p,A),q.push(p,Q,A),B+=6;m.addGroup(z,B,0);z+=B})();!1===f&&(0<a&&k(!0),0<b&&k(!1));this.setIndex(q);this.addAttribute("position",new F(l,3));this.addAttribute("normal",new F(v,3));this.addAttribute("uv",new F(t,2))}function cd(a,b,c,d,e,f,g){Cb.call(this,0,a,b,c,d,e,f,g);this.type="ConeGeometry";this.parameters={radius:a,height:b,radialSegments:c,
+A,G).normalize();v.push(p.x,p.y,p.z);t.push(H,1-F);D.push(r++)}u.push(D)}for(f=0;f<d;f++)for(k=0;k<e;k++)p=u[k+1][f],Q=u[k+1][f+1],A=u[k][f+1],q.push(u[k][f],p,A),q.push(p,Q,A),B+=6;m.addGroup(z,B,0);z+=B})();!1===f&&(0<a&&k(!0),0<b&&k(!1));this.setIndex(q);this.addAttribute("position",new E(l,3));this.addAttribute("normal",new E(v,3));this.addAttribute("uv",new E(t,2))}function cd(a,b,c,d,e,f,g){Cb.call(this,0,a,b,c,d,e,f,g);this.type="ConeGeometry";this.parameters={radius:a,height:b,radialSegments:c,
 heightSegments:d,openEnded:e,thetaStart:f,thetaLength:g}}function dd(a,b,c,d,e,f,g){bb.call(this,0,a,b,c,d,e,f,g);this.type="ConeBufferGeometry";this.parameters={radius:a,height:b,radialSegments:c,heightSegments:d,openEnded:e,thetaStart:f,thetaLength:g}}function ed(a,b,c,d){G.call(this);this.type="CircleGeometry";this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};this.fromBufferGeometry(new hc(a,b,c,d));this.mergeVertices()}function hc(a,b,c,d){D.call(this);this.type="CircleBufferGeometry";
-this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||1;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=[],f=[],g=[],h=[],k,m=new n,q=new B;f.push(0,0,0);g.push(0,0,1);h.push(.5,.5);var l=0;for(k=3;l<=b;l++,k+=3){var v=c+l/b*d;m.x=a*Math.cos(v);m.y=a*Math.sin(v);f.push(m.x,m.y,m.z);g.push(0,0,1);q.x=(f[k]/a+1)/2;q.y=(f[k+1]/a+1)/2;h.push(q.x,q.y)}for(k=1;k<=b;k++)e.push(k,k+1,0);this.setIndex(e);this.addAttribute("position",new F(f,3));this.addAttribute("normal",
-new F(g,3));this.addAttribute("uv",new F(h,2))}function Db(a){M.call(this);this.type="ShadowMaterial";this.color=new K(0);this.transparent=!0;this.setValues(a)}function ic(a){Ca.call(this,a);this.type="RawShaderMaterial"}function Wa(a){M.call(this);this.defines={STANDARD:""};this.type="MeshStandardMaterial";this.color=new K(16777215);this.metalness=this.roughness=.5;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new K(0);this.emissiveIntensity=
+this.parameters={radius:a,segments:b,thetaStart:c,thetaLength:d};a=a||1;b=void 0!==b?Math.max(3,b):8;c=void 0!==c?c:0;d=void 0!==d?d:2*Math.PI;var e=[],f=[],g=[],h=[],k,m=new n,q=new B;f.push(0,0,0);g.push(0,0,1);h.push(.5,.5);var l=0;for(k=3;l<=b;l++,k+=3){var v=c+l/b*d;m.x=a*Math.cos(v);m.y=a*Math.sin(v);f.push(m.x,m.y,m.z);g.push(0,0,1);q.x=(f[k]/a+1)/2;q.y=(f[k+1]/a+1)/2;h.push(q.x,q.y)}for(k=1;k<=b;k++)e.push(k,k+1,0);this.setIndex(e);this.addAttribute("position",new E(f,3));this.addAttribute("normal",
+new E(g,3));this.addAttribute("uv",new E(h,2))}function Db(a){M.call(this);this.type="ShadowMaterial";this.color=new K(0);this.transparent=!0;this.setValues(a)}function ic(a){Ca.call(this,a);this.type="RawShaderMaterial"}function Wa(a){M.call(this);this.defines={STANDARD:""};this.type="MeshStandardMaterial";this.color=new K(16777215);this.metalness=this.roughness=.5;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new K(0);this.emissiveIntensity=
 1;this.bumpMap=this.emissiveMap=null;this.bumpScale=1;this.normalMap=null;this.normalMapType=0;this.normalScale=new B(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.envMap=this.alphaMap=this.metalnessMap=this.roughnessMap=null;this.envMapIntensity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphNormals=this.morphTargets=this.skinning=!1;this.setValues(a)}function Eb(a){Wa.call(this);
 this.defines={PHYSICAL:""};this.type="MeshPhysicalMaterial";this.reflectivity=.5;this.clearCoatRoughness=this.clearCoat=0;this.setValues(a)}function Ja(a){M.call(this);this.type="MeshPhongMaterial";this.color=new K(16777215);this.specular=new K(1118481);this.shininess=30;this.lightMap=this.map=null;this.lightMapIntensity=1;this.aoMap=null;this.aoMapIntensity=1;this.emissive=new K(0);this.emissiveIntensity=1;this.bumpMap=this.emissiveMap=null;this.bumpScale=1;this.normalMap=null;this.normalMapType=
 0;this.normalScale=new B(1,1);this.displacementMap=null;this.displacementScale=1;this.displacementBias=0;this.envMap=this.alphaMap=this.specularMap=null;this.combine=0;this.reflectivity=1;this.refractionRatio=.98;this.wireframe=!1;this.wireframeLinewidth=1;this.wireframeLinejoin=this.wireframeLinecap="round";this.morphNormals=this.morphTargets=this.skinning=!1;this.setValues(a)}function Fb(a){Ja.call(this);this.defines={TOON:""};this.type="MeshToonMaterial";this.gradientMap=null;this.setValues(a)}
@@ -283,37 +283,37 @@ function L(){this.type="Curve";this.arcLengthDivisions=200}function Ea(a,b,c,d,e
 f,g,h,k,m,q){e=((f-e)/k-(g-e)/(k+m)+(g-f)/m)*m;h=((g-f)/m-(h-f)/(m+q)+(h-g)/q)*m;a=f;b=e;c=-3*f+3*g-2*e-h;d=2*f-2*g+e+h},calc:function(e){var f=e*e;return a+b*e+c*f+d*f*e}}}function oa(a,b,c,d){L.call(this);this.type="CatmullRomCurve3";this.points=a||[];this.closed=b||!1;this.curveType=c||"centripetal";this.tension=d||.5}function Ff(a,b,c,d,e){b=.5*(d-b);e=.5*(e-c);var f=a*a;return(2*c-2*d+b+e)*a*f+(-3*c+3*d-2*b-e)*f+b*a+c}function id(a,b,c,d){var e=1-a;return e*e*b+2*(1-a)*a*c+a*a*d}function jd(a,
 b,c,d,e){var f=1-a,g=1-a;return f*f*f*b+3*g*g*a*c+3*(1-a)*a*a*d+a*a*a*e}function La(a,b,c,d){L.call(this);this.type="CubicBezierCurve";this.v0=a||new B;this.v1=b||new B;this.v2=c||new B;this.v3=d||new B}function Xa(a,b,c,d){L.call(this);this.type="CubicBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n;this.v3=d||new n}function ja(a,b){L.call(this);this.type="LineCurve";this.v1=a||new B;this.v2=b||new B}function Ma(a,b){L.call(this);this.type="LineCurve3";this.v1=a||new n;this.v2=b||
 new n}function Na(a,b,c){L.call(this);this.type="QuadraticBezierCurve";this.v0=a||new B;this.v1=b||new B;this.v2=c||new B}function Ya(a,b,c){L.call(this);this.type="QuadraticBezierCurve3";this.v0=a||new n;this.v1=b||new n;this.v2=c||new n}function Oa(a){L.call(this);this.type="SplineCurve";this.points=a||[]}function cb(){L.call(this);this.type="CurvePath";this.curves=[];this.autoClose=!1}function Pa(a){cb.call(this);this.type="Path";this.currentPoint=new B;a&&this.setFromPoints(a)}function kb(a){Pa.call(this,
-a);this.uuid=H.generateUUID();this.type="Shape";this.holes=[]}function ia(a,b){E.call(this);this.type="Light";this.color=new K(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Md(a,b,c){ia.call(this,a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(E.DefaultUp);this.updateMatrix();this.groundColor=new K(b)}function Kb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new B(512,512);this.map=null;this.matrix=new J}function Nd(){Kb.call(this,new U(50,
-1,.5,500))}function Od(a,b,c,d,e,f){ia.call(this,a,b);this.type="SpotLight";this.position.copy(E.DefaultUp);this.updateMatrix();this.target=new E;Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Nd}function Pd(a,b,c,d){ia.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",
+a);this.uuid=H.generateUUID();this.type="Shape";this.holes=[]}function ia(a,b){F.call(this);this.type="Light";this.color=new K(a);this.intensity=void 0!==b?b:1;this.receiveShadow=void 0}function Md(a,b,c){ia.call(this,a,c);this.type="HemisphereLight";this.castShadow=void 0;this.position.copy(F.DefaultUp);this.updateMatrix();this.groundColor=new K(b)}function Kb(a){this.camera=a;this.bias=0;this.radius=1;this.mapSize=new B(512,512);this.map=null;this.matrix=new J}function Nd(){Kb.call(this,new U(50,
+1,.5,500))}function Od(a,b,c,d,e,f){ia.call(this,a,b);this.type="SpotLight";this.position.copy(F.DefaultUp);this.updateMatrix();this.target=new F;Object.defineProperty(this,"power",{get:function(){return this.intensity*Math.PI},set:function(a){this.intensity=a/Math.PI}});this.distance=void 0!==c?c:0;this.angle=void 0!==d?d:Math.PI/3;this.penumbra=void 0!==e?e:0;this.decay=void 0!==f?f:1;this.shadow=new Nd}function Pd(a,b,c,d){ia.call(this,a,b);this.type="PointLight";Object.defineProperty(this,"power",
 {get:function(){return 4*this.intensity*Math.PI},set:function(a){this.intensity=a/(4*Math.PI)}});this.distance=void 0!==c?c:0;this.decay=void 0!==d?d:1;this.shadow=new Kb(new U(90,1,.5,500))}function kd(a,b,c,d,e,f){Ua.call(this);this.type="OrthographicCamera";this.zoom=1;this.view=null;this.left=void 0!==a?a:-1;this.right=void 0!==b?b:1;this.top=void 0!==c?c:1;this.bottom=void 0!==d?d:-1;this.near=void 0!==e?e:.1;this.far=void 0!==f?f:2E3;this.updateProjectionMatrix()}function Qd(){Kb.call(this,
-new kd(-5,5,5,-5,.5,500))}function Rd(a,b){ia.call(this,a,b);this.type="DirectionalLight";this.position.copy(E.DefaultUp);this.updateMatrix();this.target=new E;this.shadow=new Qd}function Sd(a,b){ia.call(this,a,b);this.type="AmbientLight";this.castShadow=void 0}function Td(a,b,c,d){ia.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function Ud(a){this.manager=void 0!==a?a:Ba;this.textures={}}function re(a){this.manager=void 0!==a?a:Ba}function se(a){this.manager=
+new kd(-5,5,5,-5,.5,500))}function Rd(a,b){ia.call(this,a,b);this.type="DirectionalLight";this.position.copy(F.DefaultUp);this.updateMatrix();this.target=new F;this.shadow=new Qd}function Sd(a,b){ia.call(this,a,b);this.type="AmbientLight";this.castShadow=void 0}function Td(a,b,c,d){ia.call(this,a,b);this.type="RectAreaLight";this.width=void 0!==c?c:10;this.height=void 0!==d?d:10}function Ud(a){this.manager=void 0!==a?a:Ba;this.textures={}}function re(a){this.manager=void 0!==a?a:Ba}function se(a){this.manager=
 void 0!==a?a:Ba;this.resourcePath=""}function te(a){"undefined"===typeof createImageBitmap&&console.warn("THREE.ImageBitmapLoader: createImageBitmap() not supported.");"undefined"===typeof fetch&&console.warn("THREE.ImageBitmapLoader: fetch() not supported.");this.manager=void 0!==a?a:Ba;this.options=void 0}function ue(){this.type="ShapePath";this.color=new K;this.subPaths=[];this.currentPath=null}function ve(a){this.type="Font";this.data=a}function Gf(a){this.manager=void 0!==a?a:Ba}function ld(){}
-function we(a){this.manager=void 0!==a?a:Ba}function Hf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new U;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new U;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function md(a,b,c,d){E.call(this);this.type="CubeCamera";var e=new U(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new n(1,0,0));this.add(e);var f=new U(90,1,a,b);f.up.set(0,-1,0);f.lookAt(new n(-1,0,0));this.add(f);var g=new U(90,1,
+function we(a){this.manager=void 0!==a?a:Ba}function Hf(){this.type="StereoCamera";this.aspect=1;this.eyeSep=.064;this.cameraL=new U;this.cameraL.layers.enable(1);this.cameraL.matrixAutoUpdate=!1;this.cameraR=new U;this.cameraR.layers.enable(2);this.cameraR.matrixAutoUpdate=!1}function md(a,b,c,d){F.call(this);this.type="CubeCamera";var e=new U(90,1,a,b);e.up.set(0,-1,0);e.lookAt(new n(1,0,0));this.add(e);var f=new U(90,1,a,b);f.up.set(0,-1,0);f.lookAt(new n(-1,0,0));this.add(f);var g=new U(90,1,
 a,b);g.up.set(0,0,1);g.lookAt(new n(0,1,0));this.add(g);var h=new U(90,1,a,b);h.up.set(0,0,-1);h.lookAt(new n(0,-1,0));this.add(h);var k=new U(90,1,a,b);k.up.set(0,-1,0);k.lookAt(new n(0,0,1));this.add(k);var m=new U(90,1,a,b);m.up.set(0,-1,0);m.lookAt(new n(0,0,-1));this.add(m);d=d||{format:1022,magFilter:1006,minFilter:1006};this.renderTarget=new mb(c,c,d);this.renderTarget.texture.name="CubeCamera";this.update=function(a,b){null===this.parent&&this.updateMatrixWorld();var c=a.getRenderTarget(),
 d=this.renderTarget,q=d.texture.generateMipmaps;d.texture.generateMipmaps=!1;a.setRenderTarget(d,0);a.render(b,e);a.setRenderTarget(d,1);a.render(b,f);a.setRenderTarget(d,2);a.render(b,g);a.setRenderTarget(d,3);a.render(b,h);a.setRenderTarget(d,4);a.render(b,k);d.texture.generateMipmaps=q;a.setRenderTarget(d,5);a.render(b,m);a.setRenderTarget(c)};this.clear=function(a,b,c,d){for(var e=a.getRenderTarget(),f=this.renderTarget,g=0;6>g;g++)a.setRenderTarget(f,g),a.clear(b,c,d);a.setRenderTarget(e)}}function xe(a){this.autoStart=
-void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function ye(){E.call(this);this.type="AudioListener";this.context=ze.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0}function mc(a){E.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=
+void 0!==a?a:!0;this.elapsedTime=this.oldTime=this.startTime=0;this.running=!1}function ye(){F.call(this);this.type="AudioListener";this.context=ze.getContext();this.gain=this.context.createGain();this.gain.connect(this.context.destination);this.filter=null;this.timeDelta=0}function mc(a){F.call(this);this.type="Audio";this.listener=a;this.context=a.context;this.gain=this.context.createGain();this.gain.connect(a.getInput());this.autoplay=!1;this.buffer=null;this.detune=0;this.loop=!1;this.offset=
 this.startTime=0;this.playbackRate=1;this.isPlaying=!1;this.hasPlaybackControl=!0;this.sourceType="empty";this.filters=[]}function Ae(a){mc.call(this,a);this.panner=this.context.createPanner();this.panner.connect(this.gain)}function Be(a,b){this.analyser=a.context.createAnalyser();this.analyser.fftSize=void 0!==b?b:2048;this.data=new Uint8Array(this.analyser.frequencyBinCount);a.getOutput().connect(this.analyser)}function Ce(a,b,c){this.binding=a;this.valueSize=c;a=Float64Array;switch(b){case "quaternion":b=
 this._slerp;break;case "string":case "bool":a=Array;b=this._select;break;default:b=this._lerp}this.buffer=new a(4*c);this._mixBufferRegion=b;this.referenceCount=this.useCount=this.cumulativeWeight=0}function If(a,b,c){c=c||ma.parseTrackName(b);this._targetGroup=a;this._bindings=a.subscribe_(b,c)}function ma(a,b,c){this.path=b;this.parsedPath=c||ma.parseTrackName(b);this.node=ma.findNode(a,this.parsedPath.nodeName)||a;this.rootNode=a}function Jf(){this.uuid=H.generateUUID();this._objects=Array.prototype.slice.call(arguments);
 this.nCachedObjects_=0;var a={};this._indicesByUUID=a;for(var b=0,c=arguments.length;b!==c;++b)a[arguments[b].uuid]=b;this._paths=[];this._parsedPaths=[];this._bindings=[];this._bindingsIndicesByPath={};var d=this;this.stats={objects:{get total(){return d._objects.length},get inUse(){return this.total-d.nCachedObjects_}},get bindingsPerObject(){return d._bindings.length}}}function Kf(a,b,c){this._mixer=a;this._clip=b;this._localRoot=c||null;a=b.tracks;b=a.length;c=Array(b);for(var d={endingStart:2400,
 endingEnd:2400},e=0;e!==b;++e){var f=a[e].createInterpolant(null);c[e]=f;f.settings=d}this._interpolantSettings=d;this._interpolants=c;this._propertyBindings=Array(b);this._weightInterpolant=this._timeScaleInterpolant=this._byClipCacheIndex=this._cacheIndex=null;this.loop=2201;this._loopCount=-1;this._startTime=null;this.time=0;this._effectiveWeight=this.weight=this._effectiveTimeScale=this.timeScale=1;this.repetitions=Infinity;this.paused=!1;this.enabled=!0;this.clampWhenFinished=!1;this.zeroSlopeAtEnd=
 this.zeroSlopeAtStart=!0}function De(a){this._root=a;this._initMemoryManager();this.time=this._accuIndex=0;this.timeScale=1}function Vd(a,b){"string"===typeof a&&(console.warn("THREE.Uniform: Type parameter is no longer needed."),a=b);this.value=a}function Ee(){D.call(this);this.type="InstancedBufferGeometry";this.maxInstancedCount=void 0}function Fe(a,b,c){ub.call(this,a,b);this.meshPerAttribute=c||1}function Ge(a,b,c,d){"number"===typeof c&&(d=c,c=!1,console.error("THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument."));
 P.call(this,a,b,c);this.meshPerAttribute=d||1}function Lf(a,b,c,d){this.ray=new tb(a,b);this.near=c||0;this.far=d||Infinity;this.params={Mesh:{},Line:{},LOD:{},Points:{threshold:1},Sprite:{}};Object.defineProperties(this.params,{PointCloud:{get:function(){console.warn("THREE.Raycaster: params.PointCloud has been renamed to params.Points.");return this.Points}}})}function Mf(a,b){return a.distance-b.distance}function He(a,b,c,d){if(!1!==a.visible&&(a.raycast(b,c),!0===d)){a=a.children;d=0;for(var e=
-a.length;d<e;d++)He(a[d],b,c,!0)}}function Nf(a,b,c){this.radius=void 0!==a?a:1;this.phi=void 0!==b?b:0;this.theta=void 0!==c?c:0;return this}function Of(a,b,c){this.radius=void 0!==a?a:1;this.theta=void 0!==b?b:0;this.y=void 0!==c?c:0;return this}function Ie(a,b){this.min=void 0!==a?a:new B(Infinity,Infinity);this.max=void 0!==b?b:new B(-Infinity,-Infinity)}function Je(a,b){this.start=void 0!==a?a:new n;this.end=void 0!==b?b:new n}function nd(a){E.call(this);this.material=a;this.render=function(){}}
-function od(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=3*c.faces.length:c&&c.isBufferGeometry&&(b=c.attributes.normal.count);c=new D;b=new F(6*b,3);c.addAttribute("position",b);W.call(this,c,new R({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function nc(a,b){E.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.color=b;a=new D;b=[0,
-0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1];for(var c=0,d=1;32>c;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new F(b,3));b=new R({fog:!1});this.cone=new W(a,b);this.add(this.cone);this.update()}function Pf(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;c<a.children.length;c++)b.push.apply(b,Pf(a.children[c]));return b}function oc(a){for(var b=Pf(a),c=new D,d=[],e=[],f=new K(0,0,1),g=new K(0,1,
-0),h=0;h<b.length;h++){var k=b[h];k.parent&&k.parent.isBone&&(d.push(0,0,0),d.push(0,0,0),e.push(f.r,f.g,f.b),e.push(g.r,g.g,g.b))}c.addAttribute("position",new F(d,3));c.addAttribute("color",new F(e,3));d=new R({vertexColors:2,depthTest:!1,depthWrite:!1,transparent:!0});W.call(this,c,d);this.root=a;this.bones=b;this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1}function pc(a,b,c){this.light=a;this.light.updateMatrixWorld();this.color=c;a=new zb(b,4,2);b=new ya({wireframe:!0,fog:!1});va.call(this,
-a,b);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1;this.update()}function qc(a,b){this.type="RectAreaLightHelper";this.light=a;this.color=b;a=new D;a.addAttribute("position",new F([1,1,0,-1,1,0,-1,-1,0,1,-1,0,1,1,0],3));a.computeBoundingSphere();b=new R({fog:!1});da.call(this,a,b);a=new D;a.addAttribute("position",new F([1,1,0,-1,1,0,-1,-1,0,1,1,0,-1,-1,0,1,-1,0],3));a.computeBoundingSphere();this.add(new va(a,new ya({side:1,fog:!1})));this.update()}function rc(a,b,c){E.call(this);this.light=
+a.length;d<e;d++)He(a[d],b,c,!0)}}function Nf(a,b,c){this.radius=void 0!==a?a:1;this.phi=void 0!==b?b:0;this.theta=void 0!==c?c:0;return this}function Of(a,b,c){this.radius=void 0!==a?a:1;this.theta=void 0!==b?b:0;this.y=void 0!==c?c:0;return this}function Ie(a,b){this.min=void 0!==a?a:new B(Infinity,Infinity);this.max=void 0!==b?b:new B(-Infinity,-Infinity)}function Je(a,b){this.start=void 0!==a?a:new n;this.end=void 0!==b?b:new n}function nd(a){F.call(this);this.material=a;this.render=function(){}}
+function od(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16711680;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=3*c.faces.length:c&&c.isBufferGeometry&&(b=c.attributes.normal.count);c=new D;b=new E(6*b,3);c.addAttribute("position",b);W.call(this,c,new R({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function nc(a,b){F.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.color=b;a=new D;b=[0,
+0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1];for(var c=0,d=1;32>c;c++,d++){var e=c/32*Math.PI*2,f=d/32*Math.PI*2;b.push(Math.cos(e),Math.sin(e),1,Math.cos(f),Math.sin(f),1)}a.addAttribute("position",new E(b,3));b=new R({fog:!1});this.cone=new W(a,b);this.add(this.cone);this.update()}function Pf(a){var b=[];a&&a.isBone&&b.push(a);for(var c=0;c<a.children.length;c++)b.push.apply(b,Pf(a.children[c]));return b}function oc(a){for(var b=Pf(a),c=new D,d=[],e=[],f=new K(0,0,1),g=new K(0,1,
+0),h=0;h<b.length;h++){var k=b[h];k.parent&&k.parent.isBone&&(d.push(0,0,0),d.push(0,0,0),e.push(f.r,f.g,f.b),e.push(g.r,g.g,g.b))}c.addAttribute("position",new E(d,3));c.addAttribute("color",new E(e,3));d=new R({vertexColors:2,depthTest:!1,depthWrite:!1,transparent:!0});W.call(this,c,d);this.root=a;this.bones=b;this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1}function pc(a,b,c){this.light=a;this.light.updateMatrixWorld();this.color=c;a=new zb(b,4,2);b=new ya({wireframe:!0,fog:!1});va.call(this,
+a,b);this.matrix=this.light.matrixWorld;this.matrixAutoUpdate=!1;this.update()}function qc(a,b){this.type="RectAreaLightHelper";this.light=a;this.color=b;a=new D;a.addAttribute("position",new E([1,1,0,-1,1,0,-1,-1,0,1,-1,0,1,1,0],3));a.computeBoundingSphere();b=new R({fog:!1});da.call(this,a,b);a=new D;a.addAttribute("position",new E([1,1,0,-1,1,0,-1,-1,0,1,1,0,-1,-1,0,1,-1,0],3));a.computeBoundingSphere();this.add(new va(a,new ya({side:1,fog:!1})));this.update()}function rc(a,b,c){F.call(this);this.light=
 a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.color=c;a=new vb(b);a.rotateY(.5*Math.PI);this.material=new ya({wireframe:!0,fog:!1});void 0===this.color&&(this.material.vertexColors=2);b=a.getAttribute("position");b=new Float32Array(3*b.count);a.addAttribute("color",new P(b,3));this.add(new va(a,this.material));this.update()}function pd(a,b,c,d){a=a||10;b=b||10;c=new K(void 0!==c?c:4473924);d=new K(void 0!==d?d:8947848);var e=b/2,f=a/b,g=a/2;a=[];for(var h=
-[],k=0,m=0,q=-g;k<=b;k++,q+=f){a.push(-g,0,q,g,0,q);a.push(q,0,-g,q,0,g);var l=k===e?c:d;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3}b=new D;b.addAttribute("position",new F(a,3));b.addAttribute("color",new F(h,3));c=new R({vertexColors:2});W.call(this,b,c)}function Wd(a,b,c,d,e,f){a=a||10;b=b||16;c=c||8;d=d||64;e=new K(void 0!==e?e:4473924);f=new K(void 0!==f?f:8947848);var g=[],h=[],k;for(k=0;k<=b;k++){var m=k/b*2*Math.PI;var q=Math.sin(m)*a;m=Math.cos(m)*a;g.push(0,
-0,0);g.push(q,0,m);var l=k&1?e:f;h.push(l.r,l.g,l.b);h.push(l.r,l.g,l.b)}for(k=0;k<=c;k++){l=k&1?e:f;var n=a-a/c*k;for(b=0;b<d;b++)m=b/d*2*Math.PI,q=Math.sin(m)*n,m=Math.cos(m)*n,g.push(q,0,m),h.push(l.r,l.g,l.b),m=(b+1)/d*2*Math.PI,q=Math.sin(m)*n,m=Math.cos(m)*n,g.push(q,0,m),h.push(l.r,l.g,l.b)}a=new D;a.addAttribute("position",new F(g,3));a.addAttribute("color",new F(h,3));g=new R({vertexColors:2});W.call(this,a,g)}function sc(a,b,c,d){this.audio=a;this.range=b||1;this.divisionsInnerAngle=c||
+[],k=0,m=0,q=-g;k<=b;k++,q+=f){a.push(-g,0,q,g,0,q);a.push(q,0,-g,q,0,g);var l=k===e?c:d;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3;l.toArray(h,m);m+=3}b=new D;b.addAttribute("position",new E(a,3));b.addAttribute("color",new E(h,3));c=new R({vertexColors:2});W.call(this,b,c)}function Wd(a,b,c,d,e,f){a=a||10;b=b||16;c=c||8;d=d||64;e=new K(void 0!==e?e:4473924);f=new K(void 0!==f?f:8947848);var g=[],h=[],k;for(k=0;k<=b;k++){var m=k/b*2*Math.PI;var q=Math.sin(m)*a;m=Math.cos(m)*a;g.push(0,
+0,0);g.push(q,0,m);var l=k&1?e:f;h.push(l.r,l.g,l.b);h.push(l.r,l.g,l.b)}for(k=0;k<=c;k++){l=k&1?e:f;var n=a-a/c*k;for(b=0;b<d;b++)m=b/d*2*Math.PI,q=Math.sin(m)*n,m=Math.cos(m)*n,g.push(q,0,m),h.push(l.r,l.g,l.b),m=(b+1)/d*2*Math.PI,q=Math.sin(m)*n,m=Math.cos(m)*n,g.push(q,0,m),h.push(l.r,l.g,l.b)}a=new D;a.addAttribute("position",new E(g,3));a.addAttribute("color",new E(h,3));g=new R({vertexColors:2});W.call(this,a,g)}function sc(a,b,c,d){this.audio=a;this.range=b||1;this.divisionsInnerAngle=c||
 16;this.divisionsOuterAngle=d||2;a=new D;b=new Float32Array(3*(3*(this.divisionsInnerAngle+2*this.divisionsOuterAngle)+3));a.addAttribute("position",new P(b,3));b=new R({color:65280});c=new R({color:16776960});da.call(this,a,[c,b]);this.update()}function qd(a,b,c,d){this.object=a;this.size=void 0!==b?b:1;a=void 0!==c?c:16776960;d=void 0!==d?d:1;b=0;(c=this.object.geometry)&&c.isGeometry?b=c.faces.length:console.warn("THREE.FaceNormalsHelper: only THREE.Geometry is supported. Use THREE.VertexNormalsHelper, instead.");
-c=new D;b=new F(6*b,3);c.addAttribute("position",b);W.call(this,c,new R({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function tc(a,b,c){E.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.color=c;void 0===b&&(b=1);a=new D;a.addAttribute("position",new F([-b,b,0,b,b,0,b,-b,0,-b,-b,0,-b,b,0],3));b=new R({fog:!1});this.lightPlane=new da(a,b);this.add(this.lightPlane);a=new D;a.addAttribute("position",new F([0,0,0,0,0,1],3));
+c=new D;b=new E(6*b,3);c.addAttribute("position",b);W.call(this,c,new R({color:a,linewidth:d}));this.matrixAutoUpdate=!1;this.update()}function tc(a,b,c){F.call(this);this.light=a;this.light.updateMatrixWorld();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.color=c;void 0===b&&(b=1);a=new D;a.addAttribute("position",new E([-b,b,0,b,b,0,b,-b,0,-b,-b,0,-b,b,0],3));b=new R({fog:!1});this.lightPlane=new da(a,b);this.add(this.lightPlane);a=new D;a.addAttribute("position",new E([0,0,0,0,0,1],3));
 this.targetLine=new da(a,b);this.add(this.targetLine);this.update()}function rd(a){function b(a,b,d){c(a,d);c(b,d)}function c(a,b){f.push(0,0,0);g.push(b.r,b.g,b.b);void 0===h[a]&&(h[a]=[]);h[a].push(f.length/3-1)}var d=new D,e=new R({color:16777215,vertexColors:1}),f=[],g=[],h={},k=new K(16755200),m=new K(16711680),l=new K(43775),p=new K(16777215),n=new K(3355443);b("n1","n2",k);b("n2","n4",k);b("n4","n3",k);b("n3","n1",k);b("f1","f2",k);b("f2","f4",k);b("f4","f3",k);b("f3","f1",k);b("n1","f1",k);
-b("n2","f2",k);b("n3","f3",k);b("n4","f4",k);b("p","n1",m);b("p","n2",m);b("p","n3",m);b("p","n4",m);b("u1","u2",l);b("u2","u3",l);b("u3","u1",l);b("c","t",p);b("p","c",n);b("cn1","cn2",n);b("cn3","cn4",n);b("cf1","cf2",n);b("cf3","cf4",n);d.addAttribute("position",new F(f,3));d.addAttribute("color",new F(g,3));W.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=h;this.update()}function db(a,
-b){this.object=a;void 0===b&&(b=16776960);a=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]);var c=new Float32Array(24),d=new D;d.setIndex(new P(a,1));d.addAttribute("position",new P(c,3));W.call(this,d,new R({color:b}));this.matrixAutoUpdate=!1;this.update()}function sd(a,b){this.type="Box3Helper";this.box=a;a=void 0!==b?b:16776960;b=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]);var c=new D;c.setIndex(new P(b,1));c.addAttribute("position",new F([1,1,1,-1,1,
-1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1],3));W.call(this,c,new R({color:a}));this.geometry.computeBoundingSphere()}function td(a,b,c){this.type="PlaneHelper";this.plane=a;this.size=void 0===b?1:b;a=void 0!==c?c:16776960;b=new D;b.addAttribute("position",new F([1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,0,0,1,0,0,0],3));b.computeBoundingSphere();da.call(this,b,new R({color:a}));b=new D;b.addAttribute("position",new F([1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1],3));b.computeBoundingSphere();
-this.add(new va(b,new ya({color:a,opacity:.2,transparent:!0,depthWrite:!1})))}function eb(a,b,c,d,e,f){E.call(this);void 0===a&&(a=new n(0,0,1));void 0===b&&(b=new n(0,0,0));void 0===c&&(c=1);void 0===d&&(d=16776960);void 0===e&&(e=.2*c);void 0===f&&(f=.2*e);void 0===Xd&&(Xd=new D,Xd.addAttribute("position",new F([0,0,0,0,1,0],3)),Ke=new bb(0,.5,1,5,1),Ke.translate(0,-.5,0));this.position.copy(b);this.line=new da(Xd,new R({color:d}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new va(Ke,
-new ya({color:d}));this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(a);this.setLength(c,e,f)}function ud(a){a=a||1;var b=[0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a];a=new D;a.addAttribute("position",new F(b,3));a.addAttribute("color",new F([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3));b=new R({vertexColors:2});W.call(this,a,b)}function Qf(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");oa.call(this,a);this.type="catmullrom";this.closed=
+b("n2","f2",k);b("n3","f3",k);b("n4","f4",k);b("p","n1",m);b("p","n2",m);b("p","n3",m);b("p","n4",m);b("u1","u2",l);b("u2","u3",l);b("u3","u1",l);b("c","t",p);b("p","c",n);b("cn1","cn2",n);b("cn3","cn4",n);b("cf1","cf2",n);b("cf3","cf4",n);d.addAttribute("position",new E(f,3));d.addAttribute("color",new E(g,3));W.call(this,d,e);this.camera=a;this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix();this.matrix=a.matrixWorld;this.matrixAutoUpdate=!1;this.pointMap=h;this.update()}function db(a,
+b){this.object=a;void 0===b&&(b=16776960);a=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]);var c=new Float32Array(24),d=new D;d.setIndex(new P(a,1));d.addAttribute("position",new P(c,3));W.call(this,d,new R({color:b}));this.matrixAutoUpdate=!1;this.update()}function sd(a,b){this.type="Box3Helper";this.box=a;a=void 0!==b?b:16776960;b=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]);var c=new D;c.setIndex(new P(b,1));c.addAttribute("position",new E([1,1,1,-1,1,
+1,-1,-1,1,1,-1,1,1,1,-1,-1,1,-1,-1,-1,-1,1,-1,-1],3));W.call(this,c,new R({color:a}));this.geometry.computeBoundingSphere()}function td(a,b,c){this.type="PlaneHelper";this.plane=a;this.size=void 0===b?1:b;a=void 0!==c?c:16776960;b=new D;b.addAttribute("position",new E([1,-1,1,-1,1,1,-1,-1,1,1,1,1,-1,1,1,-1,-1,1,1,-1,1,1,1,1,0,0,1,0,0,0],3));b.computeBoundingSphere();da.call(this,b,new R({color:a}));b=new D;b.addAttribute("position",new E([1,1,1,-1,1,1,-1,-1,1,1,1,1,-1,-1,1,1,-1,1],3));b.computeBoundingSphere();
+this.add(new va(b,new ya({color:a,opacity:.2,transparent:!0,depthWrite:!1})))}function eb(a,b,c,d,e,f){F.call(this);void 0===a&&(a=new n(0,0,1));void 0===b&&(b=new n(0,0,0));void 0===c&&(c=1);void 0===d&&(d=16776960);void 0===e&&(e=.2*c);void 0===f&&(f=.2*e);void 0===Xd&&(Xd=new D,Xd.addAttribute("position",new E([0,0,0,0,1,0],3)),Ke=new bb(0,.5,1,5,1),Ke.translate(0,-.5,0));this.position.copy(b);this.line=new da(Xd,new R({color:d}));this.line.matrixAutoUpdate=!1;this.add(this.line);this.cone=new va(Ke,
+new ya({color:d}));this.cone.matrixAutoUpdate=!1;this.add(this.cone);this.setDirection(a);this.setLength(c,e,f)}function ud(a){a=a||1;var b=[0,0,0,a,0,0,0,0,0,0,a,0,0,0,0,0,0,a];a=new D;a.addAttribute("position",new E(b,3));a.addAttribute("color",new E([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3));b=new R({vertexColors:2});W.call(this,a,b)}function Qf(a){console.warn("THREE.ClosedSplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");oa.call(this,a);this.type="catmullrom";this.closed=
 !0}function Rf(a){console.warn("THREE.SplineCurve3 has been deprecated. Use THREE.CatmullRomCurve3 instead.");oa.call(this,a);this.type="catmullrom"}function Le(a){console.warn("THREE.Spline has been removed. Use THREE.CatmullRomCurve3 instead.");oa.call(this,a);this.type="catmullrom"}void 0===Number.EPSILON&&(Number.EPSILON=Math.pow(2,-52));void 0===Number.isInteger&&(Number.isInteger=function(a){return"number"===typeof a&&isFinite(a)&&Math.floor(a)===a});void 0===Math.sign&&(Math.sign=function(a){return 0>
 a?-1:0<a?1:+a});!1==="name"in Function.prototype&&Object.defineProperty(Function.prototype,"name",{get:function(){return this.toString().match(/^\s*function\s*([^\(\s]*)/)[1]}});void 0===Object.assign&&function(){Object.assign=function(a){if(void 0===a||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)Object.prototype.hasOwnProperty.call(d,e)&&(b[e]=d[e])}return b}}();
 Object.assign(ka.prototype,{addEventListener:function(a,b){void 0===this._listeners&&(this._listeners={});var c=this._listeners;void 0===c[a]&&(c[a]=[]);-1===c[a].indexOf(b)&&c[a].push(b)},hasEventListener:function(a,b){if(void 0===this._listeners)return!1;var c=this._listeners;return void 0!==c[a]&&-1!==c[a].indexOf(b)},removeEventListener:function(a,b){void 0!==this._listeners&&(a=this._listeners[a],void 0!==a&&(b=a.indexOf(b),-1!==b&&a.splice(b,1)))},dispatchEvent:function(a){if(void 0!==this._listeners){var b=
@@ -518,7 +518,7 @@ e[6];e=e[10];b=b||this._order;"XYZ"===b?(this._y=Math.asin(d(g,-1,1)),.99999>Mat
 -1,1)),.99999>Math.abs(l)?(this._x=Math.atan2(p,e),this._z=Math.atan2(h,a)):(this._x=0,this._z=Math.atan2(-f,k))):"YZX"===b?(this._z=Math.asin(d(h,-1,1)),.99999>Math.abs(h)?(this._x=Math.atan2(-m,k),this._y=Math.atan2(-l,a)):(this._x=0,this._y=Math.atan2(g,e))):"XZY"===b?(this._z=Math.asin(-d(f,-1,1)),.99999>Math.abs(f)?(this._x=Math.atan2(p,k),this._y=Math.atan2(g,a)):(this._x=Math.atan2(-m,e),this._y=0)):console.warn("THREE.Euler: .setFromRotationMatrix() given unsupported order: "+b);this._order=
 b;if(!1!==c)this.onChangeCallback();return this},setFromQuaternion:function(){var a=new J;return function(b,c,d){a.makeRotationFromQuaternion(b);return this.setFromRotationMatrix(a,c,d)}}(),setFromVector3:function(a,b){return this.set(a.x,a.y,a.z,b||this._order)},reorder:function(){var a=new aa;return function(b){a.setFromEuler(this);return this.setFromQuaternion(a,b)}}(),equals:function(a){return a._x===this._x&&a._y===this._y&&a._z===this._z&&a._order===this._order},fromArray:function(a){this._x=
 a[0];this._y=a[1];this._z=a[2];void 0!==a[3]&&(this._order=a[3]);this.onChangeCallback();return this},toArray:function(a,b){void 0===a&&(a=[]);void 0===b&&(b=0);a[b]=this._x;a[b+1]=this._y;a[b+2]=this._z;a[b+3]=this._order;return a},toVector3:function(a){return a?a.set(this._x,this._y,this._z):new n(this._x,this._y,this._z)},onChange:function(a){this.onChangeCallback=a;return this},onChangeCallback:function(){}});Object.assign(be.prototype,{set:function(a){this.mask=1<<a|0},enable:function(a){this.mask=
-this.mask|1<<a|0},toggle:function(a){this.mask^=1<<a|0},disable:function(a){this.mask&=~(1<<a|0)},test:function(a){return 0!==(this.mask&a.mask)}});var Wf=0;E.DefaultUp=new n(0,1,0);E.DefaultMatrixAutoUpdate=!0;E.prototype=Object.assign(Object.create(ka.prototype),{constructor:E,isObject3D:!0,onBeforeRender:function(){},onAfterRender:function(){},applyMatrix:function(a){this.matrix.multiplyMatrices(a,this.matrix);this.matrix.decompose(this.position,this.quaternion,this.scale)},applyQuaternion:function(a){this.quaternion.premultiply(a);
+this.mask|1<<a|0},toggle:function(a){this.mask^=1<<a|0},disable:function(a){this.mask&=~(1<<a|0)},test:function(a){return 0!==(this.mask&a.mask)}});var Wf=0;F.DefaultUp=new n(0,1,0);F.DefaultMatrixAutoUpdate=!0;F.prototype=Object.assign(Object.create(ka.prototype),{constructor:F,isObject3D:!0,onBeforeRender:function(){},onAfterRender:function(){},applyMatrix:function(a){this.matrix.multiplyMatrices(a,this.matrix);this.matrix.decompose(this.position,this.quaternion,this.scale)},applyQuaternion:function(a){this.quaternion.premultiply(a);
 return this},setRotationFromAxisAngle:function(a,b){this.quaternion.setFromAxisAngle(a,b)},setRotationFromEuler:function(a){this.quaternion.setFromEuler(a,!0)},setRotationFromMatrix:function(a){this.quaternion.setFromRotationMatrix(a)},setRotationFromQuaternion:function(a){this.quaternion.copy(a)},rotateOnAxis:function(){var a=new aa;return function(b,c){a.setFromAxisAngle(b,c);this.quaternion.multiply(a);return this}}(),rotateOnWorldAxis:function(){var a=new aa;return function(b,c){a.setFromAxisAngle(b,
 c);this.quaternion.premultiply(a);return this}}(),rotateX:function(){var a=new n(1,0,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateY:function(){var a=new n(0,1,0);return function(b){return this.rotateOnAxis(a,b)}}(),rotateZ:function(){var a=new n(0,0,1);return function(b){return this.rotateOnAxis(a,b)}}(),translateOnAxis:function(){var a=new n;return function(b,c){a.copy(b).applyQuaternion(this.quaternion);this.position.add(a.multiplyScalar(c));return this}}(),translateX:function(){var a=
 new n(1,0,0);return function(b){return this.translateOnAxis(a,b)}}(),translateY:function(){var a=new n(0,1,0);return function(b){return this.translateOnAxis(a,b)}}(),translateZ:function(){var a=new n(0,0,1);return function(b){return this.translateOnAxis(a,b)}}(),localToWorld:function(a){return a.applyMatrix4(this.matrixWorld)},worldToLocal:function(){var a=new J;return function(b){return b.applyMatrix4(a.getInverse(this.matrixWorld))}}(),lookAt:function(){var a=new aa,b=new J,c=new n,d=new n;return function(e,
@@ -535,7 +535,7 @@ g}else f.material=b(a.materials,this.material);if(0<this.children.length)for(f.c
 b&&(b=!0);this.name=a.name;this.up.copy(a.up);this.position.copy(a.position);this.quaternion.copy(a.quaternion);this.scale.copy(a.scale);this.matrix.copy(a.matrix);this.matrixWorld.copy(a.matrixWorld);this.matrixAutoUpdate=a.matrixAutoUpdate;this.matrixWorldNeedsUpdate=a.matrixWorldNeedsUpdate;this.layers.mask=a.layers.mask;this.visible=a.visible;this.castShadow=a.castShadow;this.receiveShadow=a.receiveShadow;this.frustumCulled=a.frustumCulled;this.renderOrder=a.renderOrder;this.userData=JSON.parse(JSON.stringify(a.userData));
 if(!0===b)for(b=0;b<a.children.length;b++)this.add(a.children[b].clone());return this}});var Xf=0;G.prototype=Object.assign(Object.create(ka.prototype),{constructor:G,isGeometry:!0,applyMatrix:function(a){for(var b=(new pa).getNormalMatrix(a),c=0,d=this.vertices.length;c<d;c++)this.vertices[c].applyMatrix4(a);c=0;for(d=this.faces.length;c<d;c++){a=this.faces[c];a.normal.applyMatrix3(b).normalize();for(var e=0,f=a.vertexNormals.length;e<f;e++)a.vertexNormals[e].applyMatrix3(b).normalize()}null!==this.boundingBox&&
 this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();this.normalsNeedUpdate=this.verticesNeedUpdate=!0;return this},rotateX:function(){var a=new J;return function(b){a.makeRotationX(b);this.applyMatrix(a);return this}}(),rotateY:function(){var a=new J;return function(b){a.makeRotationY(b);this.applyMatrix(a);return this}}(),rotateZ:function(){var a=new J;return function(b){a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a=new J;return function(b,
-c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new J;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new E;return function(b){a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),fromBufferGeometry:function(a){function b(a,b,d,e){var f=void 0===h?[]:[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()],l=void 0===g?[]:[(new n).fromArray(g,3*a),(new n).fromArray(g,3*b),(new n).fromArray(g,
+c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new J;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new F;return function(b){a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),fromBufferGeometry:function(a){function b(a,b,d,e){var f=void 0===h?[]:[c.colors[a].clone(),c.colors[b].clone(),c.colors[d].clone()],l=void 0===g?[]:[(new n).fromArray(g,3*a),(new n).fromArray(g,3*b),(new n).fromArray(g,
 3*d)];e=new Nb(a,b,d,l,f,e);c.faces.push(e);void 0!==k&&c.faceVertexUvs[0].push([(new B).fromArray(k,2*a),(new B).fromArray(k,2*b),(new B).fromArray(k,2*d)]);void 0!==m&&c.faceVertexUvs[1].push([(new B).fromArray(m,2*a),(new B).fromArray(m,2*b),(new B).fromArray(m,2*d)])}var c=this,d=null!==a.index?a.index.array:void 0,e=a.attributes,f=e.position.array,g=void 0!==e.normal?e.normal.array:void 0,h=void 0!==e.color?e.color.array:void 0,k=void 0!==e.uv?e.uv.array:void 0,m=void 0!==e.uv2?e.uv2.array:void 0;
 void 0!==m&&(this.faceVertexUvs[1]=[]);for(var l=e=0;e<f.length;e+=3,l+=2)c.vertices.push((new n).fromArray(f,e)),void 0!==h&&c.colors.push((new K).fromArray(h,e));var p=a.groups;if(0<p.length)for(e=0;e<p.length;e++){f=p[e];var v=f.start,t=f.count;l=v;for(v+=t;l<v;l+=3)void 0!==d?b(d[l],d[l+1],d[l+2],f.materialIndex):b(l,l+1,l+2,f.materialIndex)}else if(void 0!==d)for(e=0;e<d.length;e+=3)b(d[e],d[e+1],d[e+2]);else for(e=0;e<f.length/3;e+=3)b(e,e+1,e+2);this.computeFaceNormals();null!==a.boundingBox&&
 (this.boundingBox=a.boundingBox.clone());null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());return this},center:function(){var a=new n;return function(){this.computeBoundingBox();this.boundingBox.getCenter(a).negate();this.translate(a.x,a.y,a.z);return this}}(),normalize:function(){this.computeBoundingSphere();var a=this.boundingSphere.center,b=this.boundingSphere.radius;b=0===b?1:1/b;var c=new J;c.set(b,0,0,-b*a.x,0,b,0,-b*a.y,0,0,b,-b*a.z,0,0,0,1);this.applyMatrix(c);return this},
@@ -563,21 +563,21 @@ d),f=new B);b[c++]=f.x;b[c++]=f.y}return this},copyVector3sArray:function(a){for
 b[c++]=f.z;b[c++]=f.w}return this},set:function(a,b){void 0===b&&(b=0);this.array.set(a,b);return this},getX:function(a){return this.array[a*this.itemSize]},setX:function(a,b){this.array[a*this.itemSize]=b;return this},getY:function(a){return this.array[a*this.itemSize+1]},setY:function(a,b){this.array[a*this.itemSize+1]=b;return this},getZ:function(a){return this.array[a*this.itemSize+2]},setZ:function(a,b){this.array[a*this.itemSize+2]=b;return this},getW:function(a){return this.array[a*this.itemSize+
 3]},setW:function(a,b){this.array[a*this.itemSize+3]=b;return this},setXY:function(a,b,c){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;return this},setXYZ:function(a,b,c,d){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;return this},setXYZW:function(a,b,c,d,e){a*=this.itemSize;this.array[a+0]=b;this.array[a+1]=c;this.array[a+2]=d;this.array[a+3]=e;return this},onUpload:function(a){this.onUploadCallback=a;return this},clone:function(){return(new this.constructor(this.array,
 this.itemSize)).copy(this)}});vc.prototype=Object.create(P.prototype);vc.prototype.constructor=vc;wc.prototype=Object.create(P.prototype);wc.prototype.constructor=wc;xc.prototype=Object.create(P.prototype);xc.prototype.constructor=xc;yc.prototype=Object.create(P.prototype);yc.prototype.constructor=yc;pb.prototype=Object.create(P.prototype);pb.prototype.constructor=pb;zc.prototype=Object.create(P.prototype);zc.prototype.constructor=zc;qb.prototype=Object.create(P.prototype);qb.prototype.constructor=
-qb;F.prototype=Object.create(P.prototype);F.prototype.constructor=F;Ac.prototype=Object.create(P.prototype);Ac.prototype.constructor=Ac;Object.assign(Se.prototype,{computeGroups:function(a){var b=[],c=void 0;a=a.faces;for(var d=0;d<a.length;d++){var e=a[d];if(e.materialIndex!==c){c=e.materialIndex;void 0!==f&&(f.count=3*d-f.start,b.push(f));var f={start:3*d,materialIndex:c}}}void 0!==f&&(f.count=3*d-f.start,b.push(f));this.groups=b},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,
+qb;E.prototype=Object.create(P.prototype);E.prototype.constructor=E;Ac.prototype=Object.create(P.prototype);Ac.prototype.constructor=Ac;Object.assign(Se.prototype,{computeGroups:function(a){var b=[],c=void 0;a=a.faces;for(var d=0;d<a.length;d++){var e=a[d];if(e.materialIndex!==c){c=e.materialIndex;void 0!==f&&(f.count=3*d-f.start,b.push(f));var f={start:3*d,materialIndex:c}}}void 0!==f&&(f.count=3*d-f.start,b.push(f));this.groups=b},fromGeometry:function(a){var b=a.faces,c=a.vertices,d=a.faceVertexUvs,
 e=d[0]&&0<d[0].length,f=d[1]&&0<d[1].length,g=a.morphTargets,h=g.length;if(0<h){var k=[];for(var m=0;m<h;m++)k[m]={name:g[m].name,data:[]};this.morphTargets.position=k}var l=a.morphNormals,p=l.length;if(0<p){var n=[];for(m=0;m<p;m++)n[m]={name:l[m].name,data:[]};this.morphTargets.normal=n}var t=a.skinIndices,r=a.skinWeights,u=t.length===c.length,w=r.length===c.length;0<c.length&&0===b.length&&console.error("THREE.DirectGeometry: Faceless geometries are not supported.");for(m=0;m<b.length;m++){var z=
 b[m];this.vertices.push(c[z.a],c[z.b],c[z.c]);var x=z.vertexNormals;3===x.length?this.normals.push(x[0],x[1],x[2]):(x=z.normal,this.normals.push(x,x,x));x=z.vertexColors;3===x.length?this.colors.push(x[0],x[1],x[2]):(x=z.color,this.colors.push(x,x,x));!0===e&&(x=d[0][m],void 0!==x?this.uvs.push(x[0],x[1],x[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv ",m),this.uvs.push(new B,new B,new B)));!0===f&&(x=d[1][m],void 0!==x?this.uvs2.push(x[0],x[1],x[2]):(console.warn("THREE.DirectGeometry.fromGeometry(): Undefined vertexUv2 ",
 m),this.uvs2.push(new B,new B,new B)));for(x=0;x<h;x++){var C=g[x].vertices;k[x].data.push(C[z.a],C[z.b],C[z.c])}for(x=0;x<p;x++)C=l[x].vertexNormals[m],n[x].data.push(C.a,C.b,C.c);u&&this.skinIndices.push(t[z.a],t[z.b],t[z.c]);w&&this.skinWeights.push(r[z.a],r[z.b],r[z.c])}this.computeGroups(a);this.verticesNeedUpdate=a.verticesNeedUpdate;this.normalsNeedUpdate=a.normalsNeedUpdate;this.colorsNeedUpdate=a.colorsNeedUpdate;this.uvsNeedUpdate=a.uvsNeedUpdate;this.groupsNeedUpdate=a.groupsNeedUpdate;
 return this}});var Yf=1;D.prototype=Object.assign(Object.create(ka.prototype),{constructor:D,isBufferGeometry:!0,getIndex:function(){return this.index},setIndex:function(a){Array.isArray(a)?this.index=new (65535<Te(a)?qb:pb)(a,1):this.index=a},addAttribute:function(a,b,c){if(!(b&&b.isBufferAttribute||b&&b.isInterleavedBufferAttribute))return console.warn("THREE.BufferGeometry: .addAttribute() now expects ( name, attribute )."),this.addAttribute(a,new P(b,c));if("index"===a)return console.warn("THREE.BufferGeometry.addAttribute: Use .setIndex() for index attribute."),
 this.setIndex(b),this;this.attributes[a]=b;return this},getAttribute:function(a){return this.attributes[a]},removeAttribute:function(a){delete this.attributes[a];return this},addGroup:function(a,b,c){this.groups.push({start:a,count:b,materialIndex:void 0!==c?c:0})},clearGroups:function(){this.groups=[]},setDrawRange:function(a,b){this.drawRange.start=a;this.drawRange.count=b},applyMatrix:function(a){var b=this.attributes.position;void 0!==b&&(a.applyToBufferAttribute(b),b.needsUpdate=!0);var c=this.attributes.normal;
 void 0!==c&&(b=(new pa).getNormalMatrix(a),b.applyToBufferAttribute(c),c.needsUpdate=!0);c=this.attributes.tangent;void 0!==c&&(b=(new pa).getNormalMatrix(a),b.applyToBufferAttribute(c),c.needsUpdate=!0);null!==this.boundingBox&&this.computeBoundingBox();null!==this.boundingSphere&&this.computeBoundingSphere();return this},rotateX:function(){var a=new J;return function(b){a.makeRotationX(b);this.applyMatrix(a);return this}}(),rotateY:function(){var a=new J;return function(b){a.makeRotationY(b);this.applyMatrix(a);
-return this}}(),rotateZ:function(){var a=new J;return function(b){a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a=new J;return function(b,c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new J;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new E;return function(b){a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),center:function(){var a=new n;return function(){this.computeBoundingBox();
-this.boundingBox.getCenter(a).negate();this.translate(a.x,a.y,a.z);return this}}(),setFromObject:function(a){var b=a.geometry;if(a.isPoints||a.isLine){a=new F(3*b.vertices.length,3);var c=new F(3*b.colors.length,3);this.addAttribute("position",a.copyVector3sArray(b.vertices));this.addAttribute("color",c.copyColorsArray(b.colors));b.lineDistances&&b.lineDistances.length===b.vertices.length&&(a=new F(b.lineDistances.length,1),this.addAttribute("lineDistance",a.copyArray(b.lineDistances)));null!==b.boundingSphere&&
-(this.boundingSphere=b.boundingSphere.clone());null!==b.boundingBox&&(this.boundingBox=b.boundingBox.clone())}else a.isMesh&&b&&b.isGeometry&&this.fromGeometry(b);return this},setFromPoints:function(a){for(var b=[],c=0,d=a.length;c<d;c++){var e=a[c];b.push(e.x,e.y,e.z||0)}this.addAttribute("position",new F(b,3));return this},updateFromObject:function(a){var b=a.geometry;if(a.isMesh){var c=b.__directGeometry;!0===b.elementsNeedUpdate&&(c=void 0,b.elementsNeedUpdate=!1);if(void 0===c)return this.fromGeometry(b);
+return this}}(),rotateZ:function(){var a=new J;return function(b){a.makeRotationZ(b);this.applyMatrix(a);return this}}(),translate:function(){var a=new J;return function(b,c,d){a.makeTranslation(b,c,d);this.applyMatrix(a);return this}}(),scale:function(){var a=new J;return function(b,c,d){a.makeScale(b,c,d);this.applyMatrix(a);return this}}(),lookAt:function(){var a=new F;return function(b){a.lookAt(b);a.updateMatrix();this.applyMatrix(a.matrix)}}(),center:function(){var a=new n;return function(){this.computeBoundingBox();
+this.boundingBox.getCenter(a).negate();this.translate(a.x,a.y,a.z);return this}}(),setFromObject:function(a){var b=a.geometry;if(a.isPoints||a.isLine){a=new E(3*b.vertices.length,3);var c=new E(3*b.colors.length,3);this.addAttribute("position",a.copyVector3sArray(b.vertices));this.addAttribute("color",c.copyColorsArray(b.colors));b.lineDistances&&b.lineDistances.length===b.vertices.length&&(a=new E(b.lineDistances.length,1),this.addAttribute("lineDistance",a.copyArray(b.lineDistances)));null!==b.boundingSphere&&
+(this.boundingSphere=b.boundingSphere.clone());null!==b.boundingBox&&(this.boundingBox=b.boundingBox.clone())}else a.isMesh&&b&&b.isGeometry&&this.fromGeometry(b);return this},setFromPoints:function(a){for(var b=[],c=0,d=a.length;c<d;c++){var e=a[c];b.push(e.x,e.y,e.z||0)}this.addAttribute("position",new E(b,3));return this},updateFromObject:function(a){var b=a.geometry;if(a.isMesh){var c=b.__directGeometry;!0===b.elementsNeedUpdate&&(c=void 0,b.elementsNeedUpdate=!1);if(void 0===c)return this.fromGeometry(b);
 c.verticesNeedUpdate=b.verticesNeedUpdate;c.normalsNeedUpdate=b.normalsNeedUpdate;c.colorsNeedUpdate=b.colorsNeedUpdate;c.uvsNeedUpdate=b.uvsNeedUpdate;c.groupsNeedUpdate=b.groupsNeedUpdate;b.verticesNeedUpdate=!1;b.normalsNeedUpdate=!1;b.colorsNeedUpdate=!1;b.uvsNeedUpdate=!1;b.groupsNeedUpdate=!1;b=c}!0===b.verticesNeedUpdate&&(c=this.attributes.position,void 0!==c&&(c.copyVector3sArray(b.vertices),c.needsUpdate=!0),b.verticesNeedUpdate=!1);!0===b.normalsNeedUpdate&&(c=this.attributes.normal,void 0!==
 c&&(c.copyVector3sArray(b.normals),c.needsUpdate=!0),b.normalsNeedUpdate=!1);!0===b.colorsNeedUpdate&&(c=this.attributes.color,void 0!==c&&(c.copyColorsArray(b.colors),c.needsUpdate=!0),b.colorsNeedUpdate=!1);b.uvsNeedUpdate&&(c=this.attributes.uv,void 0!==c&&(c.copyVector2sArray(b.uvs),c.needsUpdate=!0),b.uvsNeedUpdate=!1);b.lineDistancesNeedUpdate&&(c=this.attributes.lineDistance,void 0!==c&&(c.copyArray(b.lineDistances),c.needsUpdate=!0),b.lineDistancesNeedUpdate=!1);b.groupsNeedUpdate&&(b.computeGroups(a.geometry),
 this.groups=b.groups,b.groupsNeedUpdate=!1);return this},fromGeometry:function(a){a.__directGeometry=(new Se).fromGeometry(a);return this.fromDirectGeometry(a.__directGeometry)},fromDirectGeometry:function(a){var b=new Float32Array(3*a.vertices.length);this.addAttribute("position",(new P(b,3)).copyVector3sArray(a.vertices));0<a.normals.length&&(b=new Float32Array(3*a.normals.length),this.addAttribute("normal",(new P(b,3)).copyVector3sArray(a.normals)));0<a.colors.length&&(b=new Float32Array(3*a.colors.length),
-this.addAttribute("color",(new P(b,3)).copyColorsArray(a.colors)));0<a.uvs.length&&(b=new Float32Array(2*a.uvs.length),this.addAttribute("uv",(new P(b,2)).copyVector2sArray(a.uvs)));0<a.uvs2.length&&(b=new Float32Array(2*a.uvs2.length),this.addAttribute("uv2",(new P(b,2)).copyVector2sArray(a.uvs2)));this.groups=a.groups;for(var c in a.morphTargets){b=[];for(var d=a.morphTargets[c],e=0,f=d.length;e<f;e++){var g=d[e],h=new F(3*g.data.length,3);h.name=g.name;b.push(h.copyVector3sArray(g.data))}this.morphAttributes[c]=
-b}0<a.skinIndices.length&&(c=new F(4*a.skinIndices.length,4),this.addAttribute("skinIndex",c.copyVector4sArray(a.skinIndices)));0<a.skinWeights.length&&(c=new F(4*a.skinWeights.length,4),this.addAttribute("skinWeight",c.copyVector4sArray(a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new Za);var a=this.attributes.position;
+this.addAttribute("color",(new P(b,3)).copyColorsArray(a.colors)));0<a.uvs.length&&(b=new Float32Array(2*a.uvs.length),this.addAttribute("uv",(new P(b,2)).copyVector2sArray(a.uvs)));0<a.uvs2.length&&(b=new Float32Array(2*a.uvs2.length),this.addAttribute("uv2",(new P(b,2)).copyVector2sArray(a.uvs2)));this.groups=a.groups;for(var c in a.morphTargets){b=[];for(var d=a.morphTargets[c],e=0,f=d.length;e<f;e++){var g=d[e],h=new E(3*g.data.length,3);h.name=g.name;b.push(h.copyVector3sArray(g.data))}this.morphAttributes[c]=
+b}0<a.skinIndices.length&&(c=new E(4*a.skinIndices.length,4),this.addAttribute("skinIndex",c.copyVector4sArray(a.skinIndices)));0<a.skinWeights.length&&(c=new E(4*a.skinWeights.length,4),this.addAttribute("skinWeight",c.copyVector4sArray(a.skinWeights)));null!==a.boundingSphere&&(this.boundingSphere=a.boundingSphere.clone());null!==a.boundingBox&&(this.boundingBox=a.boundingBox.clone());return this},computeBoundingBox:function(){null===this.boundingBox&&(this.boundingBox=new Za);var a=this.attributes.position;
 void 0!==a?this.boundingBox.setFromBufferAttribute(a):this.boundingBox.makeEmpty();(isNaN(this.boundingBox.min.x)||isNaN(this.boundingBox.min.y)||isNaN(this.boundingBox.min.z))&&console.error('THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.',this)},computeBoundingSphere:function(){var a=new Za,b=new n;return function(){null===this.boundingSphere&&(this.boundingSphere=new Ha);var c=this.attributes.position;if(c){var d=
 this.boundingSphere.center;a.setFromBufferAttribute(c);a.getCenter(d);for(var e=0,f=0,g=c.count;f<g;f++)b.x=c.getX(f),b.y=c.getY(f),b.z=c.getZ(f),e=Math.max(e,d.distanceToSquared(b));this.boundingSphere.radius=Math.sqrt(e);isNaN(this.boundingSphere.radius)&&console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.',this)}}}(),computeFaceNormals:function(){},computeVertexNormals:function(){var a=this.index,b=this.attributes;
 if(b.position){var c=b.position.array;if(void 0===b.normal)this.addAttribute("normal",new P(new Float32Array(c.length),3));else for(var d=b.normal.array,e=0,f=d.length;e<f;e++)d[e]=0;d=b.normal.array;var g=new n,h=new n,k=new n,m=new n,l=new n;if(a){var p=a.array;e=0;for(f=a.count;e<f;e+=3){a=3*p[e+0];var v=3*p[e+1];var t=3*p[e+2];g.fromArray(c,a);h.fromArray(c,v);k.fromArray(c,t);m.subVectors(k,h);l.subVectors(g,h);m.cross(l);d[a]+=m.x;d[a+1]+=m.y;d[a+2]+=m.z;d[v]+=m.x;d[v+1]+=m.y;d[v+2]+=m.z;d[t]+=
@@ -618,7 +618,7 @@ this.b,this.c,a)},getPlane:function(a){void 0===a&&(console.warn("THREE.Triangle
 new n,b=new n,c=new n,d=new n,e=new n,f=new n;return function(g,h){void 0===h&&(console.warn("THREE.Triangle: .closestPointToPoint() target is now required"),h=new n);var k=this.a,m=this.b,l=this.c;a.subVectors(m,k);b.subVectors(l,k);d.subVectors(g,k);var p=a.dot(d),v=b.dot(d);if(0>=p&&0>=v)return h.copy(k);e.subVectors(g,m);var t=a.dot(e),r=b.dot(e);if(0<=t&&r<=t)return h.copy(m);var u=p*r-t*v;if(0>=u&&0<=p&&0>=t)return m=p/(p-t),h.copy(k).addScaledVector(a,m);f.subVectors(g,l);g=a.dot(f);var w=
 b.dot(f);if(0<=w&&g<=w)return h.copy(l);p=g*v-p*w;if(0>=p&&0<=v&&0>=w)return u=v/(v-w),h.copy(k).addScaledVector(b,u);v=t*w-g*r;if(0>=v&&0<=r-t&&0<=g-w)return c.subVectors(l,m),u=(r-t)/(r-t+(g-w)),h.copy(m).addScaledVector(c,u);l=1/(v+p+u);m=p*l;u*=l;return h.copy(k).addScaledVector(a,m).addScaledVector(b,u)}}(),equals:function(a){return a.a.equals(this.a)&&a.b.equals(this.b)&&a.c.equals(this.c)}});ya.prototype=Object.create(M.prototype);ya.prototype.constructor=ya;ya.prototype.isMeshBasicMaterial=
 !0;ya.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.lightMap=a.lightMap;this.lightMapIntensity=a.lightMapIntensity;this.aoMap=a.aoMap;this.aoMapIntensity=a.aoMapIntensity;this.specularMap=a.specularMap;this.alphaMap=a.alphaMap;this.envMap=a.envMap;this.combine=a.combine;this.reflectivity=a.reflectivity;this.refractionRatio=a.refractionRatio;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;this.wireframeLinecap=a.wireframeLinecap;
-this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;return this};va.prototype=Object.assign(Object.create(E.prototype),{constructor:va,isMesh:!0,setDrawMode:function(a){this.drawMode=a},copy:function(a){E.prototype.copy.call(this,a);this.drawMode=a.drawMode;void 0!==a.morphTargetInfluences&&(this.morphTargetInfluences=a.morphTargetInfluences.slice());void 0!==a.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},a.morphTargetDictionary));
+this.wireframeLinejoin=a.wireframeLinejoin;this.skinning=a.skinning;this.morphTargets=a.morphTargets;return this};va.prototype=Object.assign(Object.create(F.prototype),{constructor:va,isMesh:!0,setDrawMode:function(a){this.drawMode=a},copy:function(a){F.prototype.copy.call(this,a);this.drawMode=a.drawMode;void 0!==a.morphTargetInfluences&&(this.morphTargetInfluences=a.morphTargetInfluences.slice());void 0!==a.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},a.morphTargetDictionary));
 return this},updateMorphTargets:function(){var a=this.geometry;if(a.isBufferGeometry){a=a.morphAttributes;var b=Object.keys(a);if(0<b.length){var c=a[b[0]];if(void 0!==c)for(this.morphTargetInfluences=[],this.morphTargetDictionary={},a=0,b=c.length;a<b;a++){var d=c[a].name||String(a);this.morphTargetInfluences.push(0);this.morphTargetDictionary[d]=a}}}else a=a.morphTargets,void 0!==a&&0<a.length&&console.error("THREE.Mesh.updateMorphTargets() no longer supports THREE.Geometry. Use THREE.BufferGeometry instead.")},
 raycast:function(){function a(a,b,c,d,e,f,g,h){if(null===(1===b.side?d.intersectTriangle(g,f,e,!0,h):d.intersectTriangle(e,f,g,2!==b.side,h)))return null;u.copy(h);u.applyMatrix4(a.matrixWorld);b=c.ray.origin.distanceTo(u);return b<c.near||b>c.far?null:{distance:b,point:u.clone(),object:a}}function b(b,c,d,e,k,m,l,q,n){f.fromBufferAttribute(k,l);g.fromBufferAttribute(k,q);h.fromBufferAttribute(k,n);if(b=a(b,c,d,e,f,g,h,r))m&&(p.fromBufferAttribute(m,l),v.fromBufferAttribute(m,q),t.fromBufferAttribute(m,
 n),b.uv=ua.getUV(r,f,g,h,p,v,t,new B)),m=new Nb(l,q,n),ua.getNormal(f,g,h,m.normal),b.face=m;return b}var c=new J,d=new tb,e=new Ha,f=new n,g=new n,h=new n,k=new n,m=new n,l=new n,p=new B,v=new B,t=new B,r=new n,u=new n;return function(q,n){var u=this.geometry,w=this.material,y=this.matrixWorld;if(void 0!==w&&(null===u.boundingSphere&&u.computeBoundingSphere(),e.copy(u.boundingSphere),e.applyMatrix4(y),!1!==q.ray.intersectsSphere(e)&&(c.getInverse(y),d.copy(q.ray).applyMatrix4(c),null===u.boundingBox||
@@ -630,36 +630,36 @@ $a;$a.prototype.isCubeTexture=!0;Object.defineProperty($a.prototype,"images",{ge
 this.cache;a instanceof Float32Array&&b.length!==a.length&&(this.cache=new Float32Array(a.length));ha(b,a)};ff.prototype.setValue=function(a,b,c){for(var d=this.seq,e=0,f=d.length;e!==f;++e){var g=d[e];g.setValue(a,b[g.id],c)}};var fe=/([\w\d_]+)(\])?(\[|\.)?/g;fb.prototype.setValue=function(a,b,c){b=this.map[b];void 0!==b&&b.setValue(a,c,this.renderer)};fb.prototype.setOptional=function(a,b,c){b=b[c];void 0!==b&&this.setValue(a,c,b)};fb.upload=function(a,b,c,d){for(var e=0,f=b.length;e!==f;++e){var g=
 b[e],h=c[g.id];!1!==h.needsUpdate&&g.setValue(a,h.value,d)}};fb.seqWithValue=function(a,b){for(var c=[],d=0,e=a.length;d!==e;++d){var f=a[d];f.id in b&&c.push(f)}return c};var Rg=0,Zg=0;gb.prototype=Object.create(M.prototype);gb.prototype.constructor=gb;gb.prototype.isMeshDepthMaterial=!0;gb.prototype.copy=function(a){M.prototype.copy.call(this,a);this.depthPacking=a.depthPacking;this.skinning=a.skinning;this.morphTargets=a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=
 a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;this.wireframe=a.wireframe;this.wireframeLinewidth=a.wireframeLinewidth;return this};hb.prototype=Object.create(M.prototype);hb.prototype.constructor=hb;hb.prototype.isMeshDistanceMaterial=!0;hb.prototype.copy=function(a){M.prototype.copy.call(this,a);this.referencePosition.copy(a.referencePosition);this.nearDistance=a.nearDistance;this.farDistance=a.farDistance;this.skinning=a.skinning;this.morphTargets=
-a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};Tb.prototype=Object.assign(Object.create(E.prototype),{constructor:Tb,isGroup:!0});Ua.prototype=Object.assign(Object.create(E.prototype),{constructor:Ua,isCamera:!0,copy:function(a,b){E.prototype.copy.call(this,a,b);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);
-this.projectionMatrixInverse.copy(a.projectionMatrixInverse);return this},getWorldDirection:function(a){void 0===a&&(console.warn("THREE.Camera: .getWorldDirection() target is now required"),a=new n);this.updateMatrixWorld(!0);var b=this.matrixWorld.elements;return a.set(-b[8],-b[9],-b[10]).normalize()},updateMatrixWorld:function(a){E.prototype.updateMatrixWorld.call(this,a);this.matrixWorldInverse.getInverse(this.matrixWorld)},clone:function(){return(new this.constructor).copy(this)}});U.prototype=
+a.morphTargets;this.map=a.map;this.alphaMap=a.alphaMap;this.displacementMap=a.displacementMap;this.displacementScale=a.displacementScale;this.displacementBias=a.displacementBias;return this};Tb.prototype=Object.assign(Object.create(F.prototype),{constructor:Tb,isGroup:!0});Ua.prototype=Object.assign(Object.create(F.prototype),{constructor:Ua,isCamera:!0,copy:function(a,b){F.prototype.copy.call(this,a,b);this.matrixWorldInverse.copy(a.matrixWorldInverse);this.projectionMatrix.copy(a.projectionMatrix);
+this.projectionMatrixInverse.copy(a.projectionMatrixInverse);return this},getWorldDirection:function(a){void 0===a&&(console.warn("THREE.Camera: .getWorldDirection() target is now required"),a=new n);this.updateMatrixWorld(!0);var b=this.matrixWorld.elements;return a.set(-b[8],-b[9],-b[10]).normalize()},updateMatrixWorld:function(a){F.prototype.updateMatrixWorld.call(this,a);this.matrixWorldInverse.getInverse(this.matrixWorld)},clone:function(){return(new this.constructor).copy(this)}});U.prototype=
 Object.assign(Object.create(Ua.prototype),{constructor:U,isPerspectiveCamera:!0,copy:function(a,b){Ua.prototype.copy.call(this,a,b);this.fov=a.fov;this.zoom=a.zoom;this.near=a.near;this.far=a.far;this.focus=a.focus;this.aspect=a.aspect;this.view=null===a.view?null:Object.assign({},a.view);this.filmGauge=a.filmGauge;this.filmOffset=a.filmOffset;return this},setFocalLength:function(a){a=.5*this.getFilmHeight()/a;this.fov=2*H.RAD2DEG*Math.atan(a);this.updateProjectionMatrix()},getFocalLength:function(){var a=
 Math.tan(.5*H.DEG2RAD*this.fov);return.5*this.getFilmHeight()/a},getEffectiveFOV:function(){return 2*H.RAD2DEG*Math.atan(Math.tan(.5*H.DEG2RAD*this.fov)/this.zoom)},getFilmWidth:function(){return this.filmGauge*Math.min(this.aspect,1)},getFilmHeight:function(){return this.filmGauge/Math.max(this.aspect,1)},setViewOffset:function(a,b,c,d,e,f){this.aspect=a/b;null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1});this.view.enabled=!0;this.view.fullWidth=
 a;this.view.fullHeight=b;this.view.offsetX=c;this.view.offsetY=d;this.view.width=e;this.view.height=f;this.updateProjectionMatrix()},clearViewOffset:function(){null!==this.view&&(this.view.enabled=!1);this.updateProjectionMatrix()},updateProjectionMatrix:function(){var a=this.near,b=a*Math.tan(.5*H.DEG2RAD*this.fov)/this.zoom,c=2*b,d=this.aspect*c,e=-.5*d,f=this.view;if(null!==this.view&&this.view.enabled){var g=f.fullWidth,h=f.fullHeight;e+=f.offsetX*d/g;b-=f.offsetY*c/h;d*=f.width/g;c*=f.height/
-h}f=this.filmOffset;0!==f&&(e+=a*f/this.getFilmWidth());this.projectionMatrix.makePerspective(e,e+d,b,b-c,a,this.far);this.projectionMatrixInverse.getInverse(this.projectionMatrix)},toJSON:function(a){a=E.prototype.toJSON.call(this,a);a.object.fov=this.fov;a.object.zoom=this.zoom;a.object.near=this.near;a.object.far=this.far;a.object.focus=this.focus;a.object.aspect=this.aspect;null!==this.view&&(a.object.view=Object.assign({},this.view));a.object.filmGauge=this.filmGauge;a.object.filmOffset=this.filmOffset;
+h}f=this.filmOffset;0!==f&&(e+=a*f/this.getFilmWidth());this.projectionMatrix.makePerspective(e,e+d,b,b-c,a,this.far);this.projectionMatrixInverse.getInverse(this.projectionMatrix)},toJSON:function(a){a=F.prototype.toJSON.call(this,a);a.object.fov=this.fov;a.object.zoom=this.zoom;a.object.near=this.near;a.object.far=this.far;a.object.focus=this.focus;a.object.aspect=this.aspect;null!==this.view&&(a.object.view=Object.assign({},this.view));a.object.filmGauge=this.filmGauge;a.object.filmOffset=this.filmOffset;
 return a}});Fc.prototype=Object.assign(Object.create(U.prototype),{constructor:Fc,isArrayCamera:!0});var rf=new n,sf=new n;Object.assign(zd.prototype,{isFogExp2:!0,clone:function(){return new zd(this.color,this.density)},toJSON:function(){return{type:"FogExp2",color:this.color.getHex(),density:this.density}}});Object.assign(Ad.prototype,{isFog:!0,clone:function(){return new Ad(this.color,this.near,this.far)},toJSON:function(){return{type:"Fog",color:this.color.getHex(),near:this.near,far:this.far}}});
-Bd.prototype=Object.assign(Object.create(E.prototype),{constructor:Bd,isScene:!0,copy:function(a,b){E.prototype.copy.call(this,a,b);null!==a.background&&(this.background=a.background.clone());null!==a.fog&&(this.fog=a.fog.clone());null!==a.overrideMaterial&&(this.overrideMaterial=a.overrideMaterial.clone());this.autoUpdate=a.autoUpdate;this.matrixAutoUpdate=a.matrixAutoUpdate;return this},toJSON:function(a){var b=E.prototype.toJSON.call(this,a);null!==this.background&&(b.object.background=this.background.toJSON(a));
+Bd.prototype=Object.assign(Object.create(F.prototype),{constructor:Bd,isScene:!0,copy:function(a,b){F.prototype.copy.call(this,a,b);null!==a.background&&(this.background=a.background.clone());null!==a.fog&&(this.fog=a.fog.clone());null!==a.overrideMaterial&&(this.overrideMaterial=a.overrideMaterial.clone());this.autoUpdate=a.autoUpdate;this.matrixAutoUpdate=a.matrixAutoUpdate;return this},toJSON:function(a){var b=F.prototype.toJSON.call(this,a);null!==this.background&&(b.object.background=this.background.toJSON(a));
 null!==this.fog&&(b.object.fog=this.fog.toJSON());return b},dispose:function(){this.dispatchEvent({type:"dispose"})}});Object.defineProperty(ub.prototype,"needsUpdate",{set:function(a){!0===a&&this.version++}});Object.assign(ub.prototype,{isInterleavedBuffer:!0,onUploadCallback:function(){},setArray:function(a){if(Array.isArray(a))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.count=void 0!==a?a.length/this.stride:0;this.array=a;return this},setDynamic:function(a){this.dynamic=
 a;return this},copy:function(a){this.array=new a.array.constructor(a.array);this.count=a.count;this.stride=a.stride;this.dynamic=a.dynamic;return this},copyAt:function(a,b,c){a*=this.stride;c*=b.stride;for(var d=0,e=this.stride;d<e;d++)this.array[a+d]=b.array[c+d];return this},set:function(a,b){void 0===b&&(b=0);this.array.set(a,b);return this},clone:function(){return(new this.constructor).copy(this)},onUpload:function(a){this.onUploadCallback=a;return this}});Object.defineProperties(Gc.prototype,
 {count:{get:function(){return this.data.count}},array:{get:function(){return this.data.array}}});Object.assign(Gc.prototype,{isInterleavedBufferAttribute:!0,setX:function(a,b){this.data.array[a*this.data.stride+this.offset]=b;return this},setY:function(a,b){this.data.array[a*this.data.stride+this.offset+1]=b;return this},setZ:function(a,b){this.data.array[a*this.data.stride+this.offset+2]=b;return this},setW:function(a,b){this.data.array[a*this.data.stride+this.offset+3]=b;return this},getX:function(a){return this.data.array[a*
 this.data.stride+this.offset]},getY:function(a){return this.data.array[a*this.data.stride+this.offset+1]},getZ:function(a){return this.data.array[a*this.data.stride+this.offset+2]},getW:function(a){return this.data.array[a*this.data.stride+this.offset+3]},setXY:function(a,b,c){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;return this},setXYZ:function(a,b,c,d){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;return this},
-setXYZW:function(a,b,c,d,e){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;this.data.array[a+3]=e;return this}});jb.prototype=Object.create(M.prototype);jb.prototype.constructor=jb;jb.prototype.isSpriteMaterial=!0;jb.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.rotation=a.rotation;this.sizeAttenuation=a.sizeAttenuation;return this};var Ub;Hc.prototype=Object.assign(Object.create(E.prototype),
+setXYZW:function(a,b,c,d,e){a=a*this.data.stride+this.offset;this.data.array[a+0]=b;this.data.array[a+1]=c;this.data.array[a+2]=d;this.data.array[a+3]=e;return this}});jb.prototype=Object.create(M.prototype);jb.prototype.constructor=jb;jb.prototype.isSpriteMaterial=!0;jb.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.rotation=a.rotation;this.sizeAttenuation=a.sizeAttenuation;return this};var Ub;Hc.prototype=Object.assign(Object.create(F.prototype),
 {constructor:Hc,isSprite:!0,raycast:function(){function a(a,b,c,d,h,k){e.subVectors(a,c).addScalar(.5).multiply(d);void 0!==h?(f.x=k*e.x-h*e.y,f.y=h*e.x+k*e.y):f.copy(e);a.copy(b);a.x+=f.x;a.y+=f.y;a.applyMatrix4(g)}var b=new n,c=new n,d=new n,e=new B,f=new B,g=new J,h=new n,k=new n,m=new n,l=new B,p=new B,v=new B;return function(e,f){c.setFromMatrixScale(this.matrixWorld);g.getInverse(this.modelViewMatrix).premultiply(this.matrixWorld);d.setFromMatrixPosition(this.modelViewMatrix);var q=this.material.rotation;
 if(0!==q){var n=Math.cos(q);var r=Math.sin(q)}q=this.center;a(h.set(-.5,-.5,0),d,q,c,r,n);a(k.set(.5,-.5,0),d,q,c,r,n);a(m.set(.5,.5,0),d,q,c,r,n);l.set(0,0);p.set(1,0);v.set(1,1);var t=e.ray.intersectTriangle(h,k,m,!1,b);if(null===t&&(a(k.set(-.5,.5,0),d,q,c,r,n),p.set(0,1),t=e.ray.intersectTriangle(h,m,k,!1,b),null===t))return;r=e.ray.origin.distanceTo(b);r<e.near||r>e.far||f.push({distance:r,point:b.clone(),uv:ua.getUV(b,h,k,m,l,p,v,new B),face:null,object:this})}}(),clone:function(){return(new this.constructor(this.material)).copy(this)},
-copy:function(a){E.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Ic.prototype=Object.assign(Object.create(E.prototype),{constructor:Ic,copy:function(a){E.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this},addLevel:function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)},
+copy:function(a){F.prototype.copy.call(this,a);void 0!==a.center&&this.center.copy(a.center);return this}});Ic.prototype=Object.assign(Object.create(F.prototype),{constructor:Ic,copy:function(a){F.prototype.copy.call(this,a,!1);a=a.levels;for(var b=0,c=a.length;b<c;b++){var d=a[b];this.addLevel(d.object.clone(),d.distance)}return this},addLevel:function(a,b){void 0===b&&(b=0);b=Math.abs(b);for(var c=this.levels,d=0;d<c.length&&!(b<c[d].distance);d++);c.splice(d,0,{distance:b,object:a});this.add(a)},
 getObjectForDistance:function(a){for(var b=this.levels,c=1,d=b.length;c<d&&!(a<b[c].distance);c++);return b[c-1].object},raycast:function(){var a=new n;return function(b,c){a.setFromMatrixPosition(this.matrixWorld);var d=b.ray.origin.distanceTo(a);this.getObjectForDistance(d).raycast(b,c)}}(),update:function(){var a=new n,b=new n;return function(c){var d=this.levels;if(1<d.length){a.setFromMatrixPosition(c.matrixWorld);b.setFromMatrixPosition(this.matrixWorld);c=a.distanceTo(b);d[0].object.visible=
-!0;for(var e=1,f=d.length;e<f;e++)if(c>=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;e<f;e++)d[e].object.visible=!1}}}(),toJSON:function(a){a=E.prototype.toJSON.call(this,a);a.object.levels=[];for(var b=this.levels,c=0,d=b.length;c<d;c++){var e=b[c];a.object.levels.push({object:e.object.uuid,distance:e.distance})}return a}});Jc.prototype=Object.assign(Object.create(va.prototype),{constructor:Jc,isSkinnedMesh:!0,bind:function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),
+!0;for(var e=1,f=d.length;e<f;e++)if(c>=d[e].distance)d[e-1].object.visible=!1,d[e].object.visible=!0;else break;for(;e<f;e++)d[e].object.visible=!1}}}(),toJSON:function(a){a=F.prototype.toJSON.call(this,a);a.object.levels=[];for(var b=this.levels,c=0,d=b.length;c<d;c++){var e=b[c];a.object.levels.push({object:e.object.uuid,distance:e.distance})}return a}});Jc.prototype=Object.assign(Object.create(va.prototype),{constructor:Jc,isSkinnedMesh:!0,bind:function(a,b){this.skeleton=a;void 0===b&&(this.updateMatrixWorld(!0),
 this.skeleton.calculateInverses(),b=this.matrixWorld);this.bindMatrix.copy(b);this.bindMatrixInverse.getInverse(b)},pose:function(){this.skeleton.pose()},normalizeSkinWeights:function(){for(var a=new ba,b=this.geometry.attributes.skinWeight,c=0,d=b.count;c<d;c++){a.x=b.getX(c);a.y=b.getY(c);a.z=b.getZ(c);a.w=b.getW(c);var e=1/a.manhattanLength();Infinity!==e?a.multiplyScalar(e):a.set(1,0,0,0);b.setXYZW(c,a.x,a.y,a.z,a.w)}},updateMatrixWorld:function(a){va.prototype.updateMatrixWorld.call(this,a);
 "attached"===this.bindMode?this.bindMatrixInverse.getInverse(this.matrixWorld):"detached"===this.bindMode?this.bindMatrixInverse.getInverse(this.bindMatrix):console.warn("THREE.SkinnedMesh: Unrecognized bindMode: "+this.bindMode)},clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});Object.assign(Cd.prototype,{calculateInverses:function(){this.boneInverses=[];for(var a=0,b=this.bones.length;a<b;a++){var c=new J;this.bones[a]&&c.getInverse(this.bones[a].matrixWorld);
 this.boneInverses.push(c)}},pose:function(){var a,b;var c=0;for(b=this.bones.length;c<b;c++)(a=this.bones[c])&&a.matrixWorld.getInverse(this.boneInverses[c]);c=0;for(b=this.bones.length;c<b;c++)if(a=this.bones[c])a.parent&&a.parent.isBone?(a.matrix.getInverse(a.parent.matrixWorld),a.matrix.multiply(a.matrixWorld)):a.matrix.copy(a.matrixWorld),a.matrix.decompose(a.position,a.quaternion,a.scale)},update:function(){var a=new J,b=new J;return function(){for(var c=this.bones,d=this.boneInverses,e=this.boneMatrices,
-f=this.boneTexture,g=0,h=c.length;g<h;g++)a.multiplyMatrices(c[g]?c[g].matrixWorld:b,d[g]),a.toArray(e,16*g);void 0!==f&&(f.needsUpdate=!0)}}(),clone:function(){return new Cd(this.bones,this.boneInverses)},getBoneByName:function(a){for(var b=0,c=this.bones.length;b<c;b++){var d=this.bones[b];if(d.name===a)return d}}});je.prototype=Object.assign(Object.create(E.prototype),{constructor:je,isBone:!0});R.prototype=Object.create(M.prototype);R.prototype.constructor=R;R.prototype.isLineBasicMaterial=!0;
-R.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.linewidth=a.linewidth;this.linecap=a.linecap;this.linejoin=a.linejoin;return this};da.prototype=Object.assign(Object.create(E.prototype),{constructor:da,isLine:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[0],f=1,g=d.count;f<g;f++)a.fromBufferAttribute(d,f-1),b.fromBufferAttribute(d,f),e[f]=
-e[f-1],e[f]+=a.distanceTo(b);c.addAttribute("lineDistance",new F(e,1))}else console.warn("THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");else if(c.isGeometry)for(d=c.vertices,e=c.lineDistances,e[0]=0,f=1,g=d.length;f<g;f++)e[f]=e[f-1],e[f]+=d[f-1].distanceTo(d[f]);return this}}(),raycast:function(){var a=new J,b=new tb,c=new Ha;return function(d,e){var f=d.linePrecision,g=this.geometry,h=this.matrixWorld;null===g.boundingSphere&&g.computeBoundingSphere();
+f=this.boneTexture,g=0,h=c.length;g<h;g++)a.multiplyMatrices(c[g]?c[g].matrixWorld:b,d[g]),a.toArray(e,16*g);void 0!==f&&(f.needsUpdate=!0)}}(),clone:function(){return new Cd(this.bones,this.boneInverses)},getBoneByName:function(a){for(var b=0,c=this.bones.length;b<c;b++){var d=this.bones[b];if(d.name===a)return d}}});je.prototype=Object.assign(Object.create(F.prototype),{constructor:je,isBone:!0});R.prototype=Object.create(M.prototype);R.prototype.constructor=R;R.prototype.isLineBasicMaterial=!0;
+R.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.linewidth=a.linewidth;this.linecap=a.linecap;this.linejoin=a.linejoin;return this};da.prototype=Object.assign(Object.create(F.prototype),{constructor:da,isLine:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[0],f=1,g=d.count;f<g;f++)a.fromBufferAttribute(d,f-1),b.fromBufferAttribute(d,f),e[f]=
+e[f-1],e[f]+=a.distanceTo(b);c.addAttribute("lineDistance",new E(e,1))}else console.warn("THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");else if(c.isGeometry)for(d=c.vertices,e=c.lineDistances,e[0]=0,f=1,g=d.length;f<g;f++)e[f]=e[f-1],e[f]+=d[f-1].distanceTo(d[f]);return this}}(),raycast:function(){var a=new J,b=new tb,c=new Ha;return function(d,e){var f=d.linePrecision,g=this.geometry,h=this.matrixWorld;null===g.boundingSphere&&g.computeBoundingSphere();
 c.copy(g.boundingSphere);c.applyMatrix4(h);c.radius+=f;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(h);b.copy(d.ray).applyMatrix4(a);f/=(this.scale.x+this.scale.y+this.scale.z)/3;f*=f;var k=new n,m=new n;h=new n;var l=new n,p=this&&this.isLineSegments?2:1;if(g.isBufferGeometry){var v=g.index,t=g.attributes.position.array;if(null!==v){v=v.array;g=0;for(var r=v.length-1;g<r;g+=p){var u=v[g+1];k.fromArray(t,3*v[g]);m.fromArray(t,3*u);u=b.distanceSqToSegment(k,m,l,h);u>f||(l.applyMatrix4(this.matrixWorld),
 u=d.ray.origin.distanceTo(l),u<d.near||u>d.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}else for(g=0,r=t.length/3-1;g<r;g+=p)k.fromArray(t,3*g),m.fromArray(t,3*g+3),u=b.distanceSqToSegment(k,m,l,h),u>f||(l.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(l),u<d.near||u>d.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}else if(g.isGeometry)for(k=
-g.vertices,m=k.length,g=0;g<m-1;g+=p)u=b.distanceSqToSegment(k[g],k[g+1],l,h),u>f||(l.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(l),u<d.near||u>d.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),copy:function(a){E.prototype.copy.call(this,a);this.geometry.copy(a.geometry);this.material.copy(a.material);return this},clone:function(){return(new this.constructor).copy(this)}});W.prototype=Object.assign(Object.create(da.prototype),
-{constructor:W,isLineSegments:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;f<g;f+=2)a.fromBufferAttribute(d,f),b.fromBufferAttribute(d,f+1),e[f]=0===f?0:e[f-1],e[f+1]=e[f]+a.distanceTo(b);c.addAttribute("lineDistance",new F(e,1))}else console.warn("THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");else if(c.isGeometry)for(d=
+g.vertices,m=k.length,g=0;g<m-1;g+=p)u=b.distanceSqToSegment(k[g],k[g+1],l,h),u>f||(l.applyMatrix4(this.matrixWorld),u=d.ray.origin.distanceTo(l),u<d.near||u>d.far||e.push({distance:u,point:h.clone().applyMatrix4(this.matrixWorld),index:g,face:null,faceIndex:null,object:this}))}}}(),copy:function(a){F.prototype.copy.call(this,a);this.geometry.copy(a.geometry);this.material.copy(a.material);return this},clone:function(){return(new this.constructor).copy(this)}});W.prototype=Object.assign(Object.create(da.prototype),
+{constructor:W,isLineSegments:!0,computeLineDistances:function(){var a=new n,b=new n;return function(){var c=this.geometry;if(c.isBufferGeometry)if(null===c.index){for(var d=c.attributes.position,e=[],f=0,g=d.count;f<g;f+=2)a.fromBufferAttribute(d,f),b.fromBufferAttribute(d,f+1),e[f]=0===f?0:e[f-1],e[f+1]=e[f]+a.distanceTo(b);c.addAttribute("lineDistance",new E(e,1))}else console.warn("THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.");else if(c.isGeometry)for(d=
 c.vertices,e=c.lineDistances,f=0,g=d.length;f<g;f+=2)a.copy(d[f]),b.copy(d[f+1]),e[f]=0===f?0:e[f-1],e[f+1]=e[f]+a.distanceTo(b);return this}}()});Dd.prototype=Object.assign(Object.create(da.prototype),{constructor:Dd,isLineLoop:!0});Ia.prototype=Object.create(M.prototype);Ia.prototype.constructor=Ia;Ia.prototype.isPointsMaterial=!0;Ia.prototype.copy=function(a){M.prototype.copy.call(this,a);this.color.copy(a.color);this.map=a.map;this.size=a.size;this.sizeAttenuation=a.sizeAttenuation;this.morphTargets=
-a.morphTargets;return this};Vb.prototype=Object.assign(Object.create(E.prototype),{constructor:Vb,isPoints:!0,raycast:function(){var a=new J,b=new tb,c=new Ha;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);f<l&&(b.closestPointToPoint(a,p),p.applyMatrix4(k),a=d.ray.origin.distanceTo(p),a<d.near||a>d.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:p.clone(),index:c,face:null,object:g}))}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&
+a.morphTargets;return this};Vb.prototype=Object.assign(Object.create(F.prototype),{constructor:Vb,isPoints:!0,raycast:function(){var a=new J,b=new tb,c=new Ha;return function(d,e){function f(a,c){var f=b.distanceSqToPoint(a);f<l&&(b.closestPointToPoint(a,p),p.applyMatrix4(k),a=d.ray.origin.distanceTo(p),a<d.near||a>d.far||e.push({distance:a,distanceToRay:Math.sqrt(f),point:p.clone(),index:c,face:null,object:g}))}var g=this,h=this.geometry,k=this.matrixWorld,m=d.params.Points.threshold;null===h.boundingSphere&&
 h.computeBoundingSphere();c.copy(h.boundingSphere);c.applyMatrix4(k);c.radius+=m;if(!1!==d.ray.intersectsSphere(c)){a.getInverse(k);b.copy(d.ray).applyMatrix4(a);m/=(this.scale.x+this.scale.y+this.scale.z)/3;var l=m*m;m=new n;var p=new n;if(h.isBufferGeometry){var v=h.index;h=h.attributes.position.array;if(null!==v){var t=v.array;v=0;for(var r=t.length;v<r;v++){var u=t[v];m.fromArray(h,3*u);f(m,u)}}else for(v=0,t=h.length/3;v<t;v++)m.fromArray(h,3*v),f(m,v)}else for(m=h.vertices,v=0,t=m.length;v<
 t;v++)f(m[v],v)}}}(),clone:function(){return(new this.constructor(this.geometry,this.material)).copy(this)}});ke.prototype=Object.assign(Object.create(S.prototype),{constructor:ke,isVideoTexture:!0,update:function(){var a=this.image;a.readyState>=a.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}});Wb.prototype=Object.create(S.prototype);Wb.prototype.constructor=Wb;Wb.prototype.isCompressedTexture=!0;Kc.prototype=Object.create(S.prototype);Kc.prototype.constructor=Kc;Kc.prototype.isCanvasTexture=!0;Lc.prototype=
 Object.create(S.prototype);Lc.prototype.constructor=Lc;Lc.prototype.isDepthTexture=!0;Xb.prototype=Object.create(D.prototype);Xb.prototype.constructor=Xb;Mc.prototype=Object.create(G.prototype);Mc.prototype.constructor=Mc;Yb.prototype=Object.create(D.prototype);Yb.prototype.constructor=Yb;Nc.prototype=Object.create(G.prototype);Nc.prototype.constructor=Nc;Aa.prototype=Object.create(D.prototype);Aa.prototype.constructor=Aa;Oc.prototype=Object.create(G.prototype);Oc.prototype.constructor=Oc;Zb.prototype=
@@ -711,7 +711,7 @@ this.duration,a)}});var Lb={enabled:!1,files:{},add:function(a,b){!1!==this.enab
 break;default:l=g}setTimeout(function(){b&&b(l);e.manager.itemEnd(a)},0)}catch(v){setTimeout(function(){d&&d(v);e.manager.itemError(a);e.manager.itemEnd(a)},0)}}else{Qa[a]=[];Qa[a].push({onLoad:b,onProgress:c,onError:d});var n=new XMLHttpRequest;n.open("GET",a,!0);n.addEventListener("load",function(b){var c=this.response;Lb.add(a,c);var d=Qa[a];delete Qa[a];if(200===this.status||0===this.status){0===this.status&&console.warn("THREE.FileLoader: HTTP Status 0 received.");for(var f=0,g=d.length;f<g;f++){var h=
 d[f];if(h.onLoad)h.onLoad(c)}}else{f=0;for(g=d.length;f<g;f++)if(h=d[f],h.onError)h.onError(b);e.manager.itemError(a)}e.manager.itemEnd(a)},!1);n.addEventListener("progress",function(b){for(var c=Qa[a],d=0,e=c.length;d<e;d++){var f=c[d];if(f.onProgress)f.onProgress(b)}},!1);n.addEventListener("error",function(b){var c=Qa[a];delete Qa[a];for(var d=0,f=c.length;d<f;d++){var g=c[d];if(g.onError)g.onError(b)}e.manager.itemError(a);e.manager.itemEnd(a)},!1);n.addEventListener("abort",function(b){var c=
 Qa[a];delete Qa[a];for(var d=0,f=c.length;d<f;d++){var g=c[d];if(g.onError)g.onError(b)}e.manager.itemError(a);e.manager.itemEnd(a)},!1);void 0!==this.responseType&&(n.responseType=this.responseType);void 0!==this.withCredentials&&(n.withCredentials=this.withCredentials);n.overrideMimeType&&n.overrideMimeType(void 0!==this.mimeType?this.mimeType:"text/plain");for(h in this.requestHeader)n.setRequestHeader(h,this.requestHeader[h]);n.send(null)}e.manager.itemStart(a);return n}},setPath:function(a){this.path=
-a;return this},setResponseType:function(a){this.responseType=a;return this},setWithCredentials:function(a){this.withCredentials=a;return this},setMimeType:function(a){this.mimeType=a;return this},setRequestHeader:function(a){this.requestHeader=a;return this}});Object.assign(Df.prototype,{load:function(a,b,c,d){var e=this,f=new Ka(e.manager);f.setPath(e.path);f.load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a,b){for(var c=[],d=0;d<a.length;d++){var e=Ga.parse(a[d]);c.push(e)}b(c)},
+a;return this},setResponseType:function(a){this.responseType=a;return this},setWithCredentials:function(a){this.withCredentials=a;return this},setMimeType:function(a){this.mimeType=a;return this},setRequestHeader:function(a){this.requestHeader=a;return this}});Object.assign(Df.prototype,{load:function(a,b,c,d){var e=this,f=new Ka(e.manager);f.setPath(e.path);f.load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a){for(var b=[],c=0;c<a.length;c++){var d=Ga.parse(a[c]);b.push(d)}return b},
 setPath:function(a){this.path=a;return this}});Object.assign(Ef.prototype,{load:function(a,b,c,d){function e(e){k.load(a[e],function(a){a=f._parser(a,!0);g[e]={width:a.width,height:a.height,format:a.format,mipmaps:a.mipmaps};m+=1;6===m&&(1===a.mipmapCount&&(h.minFilter=1006),h.format=a.format,h.needsUpdate=!0,b&&b(h))},c,d)}var f=this,g=[],h=new Wb;h.image=g;var k=new Ka(this.manager);k.setPath(this.path);k.setResponseType("arraybuffer");if(Array.isArray(a))for(var m=0,l=0,n=a.length;l<n;++l)e(l);
 else k.load(a,function(a){a=f._parser(a,!0);if(a.isCubemap)for(var c=a.mipmaps.length/a.mipmapCount,d=0;d<c;d++){g[d]={mipmaps:[]};for(var e=0;e<a.mipmapCount;e++)g[d].mipmaps.push(a.mipmaps[d*a.mipmapCount+e]),g[d].format=a.format,g[d].width=a.width,g[d].height=a.height}else h.image.width=a.width,h.image.height=a.height,h.mipmaps=a.mipmaps;1===a.mipmapCount&&(h.minFilter=1006);h.format=a.format;h.needsUpdate=!0;b&&b(h)},c,d);return h},setPath:function(a){this.path=a;return this}});Object.assign(oe.prototype,
 {load:function(a,b,c,d){var e=this,f=new nb,g=new Ka(this.manager);g.setResponseType("arraybuffer");g.setPath(this.path);g.load(a,function(a){if(a=e._parser(a))void 0!==a.image?f.image=a.image:void 0!==a.data&&(f.image.width=a.width,f.image.height=a.height,f.image.data=a.data),f.wrapS=void 0!==a.wrapS?a.wrapS:1001,f.wrapT=void 0!==a.wrapT?a.wrapT:1001,f.magFilter=void 0!==a.magFilter?a.magFilter:1006,f.minFilter=void 0!==a.minFilter?a.minFilter:1008,f.anisotropy=void 0!==a.anisotropy?a.anisotropy:
@@ -749,14 +749,14 @@ a[0].y);for(var b=1,c=a.length;b<c;b++)this.lineTo(a[b].x,a[b].y)},moveTo:functi
 this.currentPoint.set(e,f)},splineThru:function(a){var b=[this.currentPoint.clone()].concat(a);b=new Oa(b);this.curves.push(b);this.currentPoint.copy(a[a.length-1])},arc:function(a,b,c,d,e,f){this.absarc(a+this.currentPoint.x,b+this.currentPoint.y,c,d,e,f)},absarc:function(a,b,c,d,e,f){this.absellipse(a,b,c,c,d,e,f)},ellipse:function(a,b,c,d,e,f,g,h){this.absellipse(a+this.currentPoint.x,b+this.currentPoint.y,c,d,e,f,g,h)},absellipse:function(a,b,c,d,e,f,g,h){a=new Ea(a,b,c,d,e,f,g,h);0<this.curves.length&&
 (b=a.getPoint(0),b.equals(this.currentPoint)||this.lineTo(b.x,b.y));this.curves.push(a);a=a.getPoint(1);this.currentPoint.copy(a)},copy:function(a){cb.prototype.copy.call(this,a);this.currentPoint.copy(a.currentPoint);return this},toJSON:function(){var a=cb.prototype.toJSON.call(this);a.currentPoint=this.currentPoint.toArray();return a},fromJSON:function(a){cb.prototype.fromJSON.call(this,a);this.currentPoint.fromArray(a.currentPoint);return this}});kb.prototype=Object.assign(Object.create(Pa.prototype),
 {constructor:kb,getPointsHoles:function(a){for(var b=[],c=0,d=this.holes.length;c<d;c++)b[c]=this.holes[c].getPoints(a);return b},extractPoints:function(a){return{shape:this.getPoints(a),holes:this.getPointsHoles(a)}},copy:function(a){Pa.prototype.copy.call(this,a);this.holes=[];for(var b=0,c=a.holes.length;b<c;b++)this.holes.push(a.holes[b].clone());return this},toJSON:function(){var a=Pa.prototype.toJSON.call(this);a.uuid=this.uuid;a.holes=[];for(var b=0,c=this.holes.length;b<c;b++)a.holes.push(this.holes[b].toJSON());
-return a},fromJSON:function(a){Pa.prototype.fromJSON.call(this,a);this.uuid=a.uuid;this.holes=[];for(var b=0,c=a.holes.length;b<c;b++){var d=a.holes[b];this.holes.push((new Pa).fromJSON(d))}return this}});ia.prototype=Object.assign(Object.create(E.prototype),{constructor:ia,isLight:!0,copy:function(a){E.prototype.copy.call(this,a);this.color.copy(a.color);this.intensity=a.intensity;return this},toJSON:function(a){a=E.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();a.object.intensity=
+return a},fromJSON:function(a){Pa.prototype.fromJSON.call(this,a);this.uuid=a.uuid;this.holes=[];for(var b=0,c=a.holes.length;b<c;b++){var d=a.holes[b];this.holes.push((new Pa).fromJSON(d))}return this}});ia.prototype=Object.assign(Object.create(F.prototype),{constructor:ia,isLight:!0,copy:function(a){F.prototype.copy.call(this,a);this.color.copy(a.color);this.intensity=a.intensity;return this},toJSON:function(a){a=F.prototype.toJSON.call(this,a);a.object.color=this.color.getHex();a.object.intensity=
 this.intensity;void 0!==this.groundColor&&(a.object.groundColor=this.groundColor.getHex());void 0!==this.distance&&(a.object.distance=this.distance);void 0!==this.angle&&(a.object.angle=this.angle);void 0!==this.decay&&(a.object.decay=this.decay);void 0!==this.penumbra&&(a.object.penumbra=this.penumbra);void 0!==this.shadow&&(a.object.shadow=this.shadow.toJSON());return a}});Md.prototype=Object.assign(Object.create(ia.prototype),{constructor:Md,isHemisphereLight:!0,copy:function(a){ia.prototype.copy.call(this,
 a);this.groundColor.copy(a.groundColor);return this}});Object.assign(Kb.prototype,{copy:function(a){this.camera=a.camera.clone();this.bias=a.bias;this.radius=a.radius;this.mapSize.copy(a.mapSize);return this},clone:function(){return(new this.constructor).copy(this)},toJSON:function(){var a={};0!==this.bias&&(a.bias=this.bias);1!==this.radius&&(a.radius=this.radius);if(512!==this.mapSize.x||512!==this.mapSize.y)a.mapSize=this.mapSize.toArray();a.camera=this.camera.toJSON(!1).object;delete a.camera.matrix;
 return a}});Nd.prototype=Object.assign(Object.create(Kb.prototype),{constructor:Nd,isSpotLightShadow:!0,update:function(a){var b=this.camera,c=2*H.RAD2DEG*a.angle,d=this.mapSize.width/this.mapSize.height;a=a.distance||b.far;if(c!==b.fov||d!==b.aspect||a!==b.far)b.fov=c,b.aspect=d,b.far=a,b.updateProjectionMatrix()}});Od.prototype=Object.assign(Object.create(ia.prototype),{constructor:Od,isSpotLight:!0,copy:function(a){ia.prototype.copy.call(this,a);this.distance=a.distance;this.angle=a.angle;this.penumbra=
 a.penumbra;this.decay=a.decay;this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});Pd.prototype=Object.assign(Object.create(ia.prototype),{constructor:Pd,isPointLight:!0,copy:function(a){ia.prototype.copy.call(this,a);this.distance=a.distance;this.decay=a.decay;this.shadow=a.shadow.clone();return this}});kd.prototype=Object.assign(Object.create(Ua.prototype),{constructor:kd,isOrthographicCamera:!0,copy:function(a,b){Ua.prototype.copy.call(this,a,b);this.left=a.left;this.right=
 a.right;this.top=a.top;this.bottom=a.bottom;this.near=a.near;this.far=a.far;this.zoom=a.zoom;this.view=null===a.view?null:Object.assign({},a.view);return this},setViewOffset:function(a,b,c,d,e,f){null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1});this.view.enabled=!0;this.view.fullWidth=a;this.view.fullHeight=b;this.view.offsetX=c;this.view.offsetY=d;this.view.width=e;this.view.height=f;this.updateProjectionMatrix()},clearViewOffset:function(){null!==
 this.view&&(this.view.enabled=!1);this.updateProjectionMatrix()},updateProjectionMatrix:function(){var a=(this.right-this.left)/(2*this.zoom),b=(this.top-this.bottom)/(2*this.zoom),c=(this.right+this.left)/2,d=(this.top+this.bottom)/2,e=c-a;c+=a;a=d+b;b=d-b;if(null!==this.view&&this.view.enabled){c=this.zoom/(this.view.width/this.view.fullWidth);b=this.zoom/(this.view.height/this.view.fullHeight);var f=(this.right-this.left)/this.view.width;d=(this.top-this.bottom)/this.view.height;e+=this.view.offsetX/
-c*f;c=e+this.view.width/c*f;a-=this.view.offsetY/b*d;b=a-this.view.height/b*d}this.projectionMatrix.makeOrthographic(e,c,a,b,this.near,this.far);this.projectionMatrixInverse.getInverse(this.projectionMatrix)},toJSON:function(a){a=E.prototype.toJSON.call(this,a);a.object.zoom=this.zoom;a.object.left=this.left;a.object.right=this.right;a.object.top=this.top;a.object.bottom=this.bottom;a.object.near=this.near;a.object.far=this.far;null!==this.view&&(a.object.view=Object.assign({},this.view));return a}});
+c*f;c=e+this.view.width/c*f;a-=this.view.offsetY/b*d;b=a-this.view.height/b*d}this.projectionMatrix.makeOrthographic(e,c,a,b,this.near,this.far);this.projectionMatrixInverse.getInverse(this.projectionMatrix)},toJSON:function(a){a=F.prototype.toJSON.call(this,a);a.object.zoom=this.zoom;a.object.left=this.left;a.object.right=this.right;a.object.top=this.top;a.object.bottom=this.bottom;a.object.near=this.near;a.object.far=this.far;null!==this.view&&(a.object.view=Object.assign({},this.view));return a}});
 Qd.prototype=Object.assign(Object.create(Kb.prototype),{constructor:Qd});Rd.prototype=Object.assign(Object.create(ia.prototype),{constructor:Rd,isDirectionalLight:!0,copy:function(a){ia.prototype.copy.call(this,a);this.target=a.target.clone();this.shadow=a.shadow.clone();return this}});Sd.prototype=Object.assign(Object.create(ia.prototype),{constructor:Sd,isAmbientLight:!0});Td.prototype=Object.assign(Object.create(ia.prototype),{constructor:Td,isRectAreaLight:!0,copy:function(a){ia.prototype.copy.call(this,
 a);this.width=a.width;this.height=a.height;return this},toJSON:function(a){a=ia.prototype.toJSON.call(this,a);a.object.width=this.width;a.object.height=this.height;return a}});Object.assign(Ud.prototype,{load:function(a,b,c,d){var e=this,f=new Ka(e.manager);f.setPath(e.path);f.load(a,function(a){b(e.parse(JSON.parse(a)))},c,d)},parse:function(a){function b(a){void 0===c[a]&&console.warn("THREE.MaterialLoader: Undefined texture",a);return c[a]}var c=this.textures,d=new mh[a.type];void 0!==a.uuid&&
 (d.uuid=a.uuid);void 0!==a.name&&(d.name=a.name);void 0!==a.color&&d.color.setHex(a.color);void 0!==a.roughness&&(d.roughness=a.roughness);void 0!==a.metalness&&(d.metalness=a.metalness);void 0!==a.emissive&&d.emissive.setHex(a.emissive);void 0!==a.specular&&d.specular.setHex(a.specular);void 0!==a.shininess&&(d.shininess=a.shininess);void 0!==a.clearCoat&&(d.clearCoat=a.clearCoat);void 0!==a.clearCoatRoughness&&(d.clearCoatRoughness=a.clearCoatRoughness);void 0!==a.vertexColors&&(d.vertexColors=
@@ -788,7 +788,7 @@ a){if(Array.isArray(a)){for(var b=[],d=0,e=a.length;d<e;d++){var f=a[d];void 0==
 a.fog.density)));break;case "PerspectiveCamera":f=new U(a.fov,a.aspect,a.near,a.far);void 0!==a.focus&&(f.focus=a.focus);void 0!==a.zoom&&(f.zoom=a.zoom);void 0!==a.filmGauge&&(f.filmGauge=a.filmGauge);void 0!==a.filmOffset&&(f.filmOffset=a.filmOffset);void 0!==a.view&&(f.view=Object.assign({},a.view));break;case "OrthographicCamera":f=new kd(a.left,a.right,a.top,a.bottom,a.near,a.far);void 0!==a.zoom&&(f.zoom=a.zoom);void 0!==a.view&&(f.view=Object.assign({},a.view));break;case "AmbientLight":f=
 new Sd(a.color,a.intensity);break;case "DirectionalLight":f=new Rd(a.color,a.intensity);break;case "PointLight":f=new Pd(a.color,a.intensity,a.distance,a.decay);break;case "RectAreaLight":f=new Td(a.color,a.intensity,a.width,a.height);break;case "SpotLight":f=new Od(a.color,a.intensity,a.distance,a.angle,a.penumbra,a.decay);break;case "HemisphereLight":f=new Md(a.color,a.groundColor,a.intensity);break;case "SkinnedMesh":console.warn("THREE.ObjectLoader.parseObject() does not support SkinnedMesh yet.");
 case "Mesh":f=d(a.geometry);var g=e(a.material);f=f.bones&&0<f.bones.length?new Jc(f,g):new va(f,g);void 0!==a.drawMode&&f.setDrawMode(a.drawMode);break;case "LOD":f=new Ic;break;case "Line":f=new da(d(a.geometry),e(a.material),a.mode);break;case "LineLoop":f=new Dd(d(a.geometry),e(a.material));break;case "LineSegments":f=new W(d(a.geometry),e(a.material));break;case "PointCloud":case "Points":f=new Vb(d(a.geometry),e(a.material));break;case "Sprite":f=new Hc(e(a.material));break;case "Group":f=new Tb;
-break;default:f=new E}f.uuid=a.uuid;void 0!==a.name&&(f.name=a.name);void 0!==a.matrix?(f.matrix.fromArray(a.matrix),void 0!==a.matrixAutoUpdate&&(f.matrixAutoUpdate=a.matrixAutoUpdate),f.matrixAutoUpdate&&f.matrix.decompose(f.position,f.quaternion,f.scale)):(void 0!==a.position&&f.position.fromArray(a.position),void 0!==a.rotation&&f.rotation.fromArray(a.rotation),void 0!==a.quaternion&&f.quaternion.fromArray(a.quaternion),void 0!==a.scale&&f.scale.fromArray(a.scale));void 0!==a.castShadow&&(f.castShadow=
+break;default:f=new F}f.uuid=a.uuid;void 0!==a.name&&(f.name=a.name);void 0!==a.matrix?(f.matrix.fromArray(a.matrix),void 0!==a.matrixAutoUpdate&&(f.matrixAutoUpdate=a.matrixAutoUpdate),f.matrixAutoUpdate&&f.matrix.decompose(f.position,f.quaternion,f.scale)):(void 0!==a.position&&f.position.fromArray(a.position),void 0!==a.rotation&&f.rotation.fromArray(a.rotation),void 0!==a.quaternion&&f.quaternion.fromArray(a.quaternion),void 0!==a.scale&&f.scale.fromArray(a.scale));void 0!==a.castShadow&&(f.castShadow=
 a.castShadow);void 0!==a.receiveShadow&&(f.receiveShadow=a.receiveShadow);a.shadow&&(void 0!==a.shadow.bias&&(f.shadow.bias=a.shadow.bias),void 0!==a.shadow.radius&&(f.shadow.radius=a.shadow.radius),void 0!==a.shadow.mapSize&&f.shadow.mapSize.fromArray(a.shadow.mapSize),void 0!==a.shadow.camera&&(f.shadow.camera=this.parseObject(a.shadow.camera)));void 0!==a.visible&&(f.visible=a.visible);void 0!==a.frustumCulled&&(f.frustumCulled=a.frustumCulled);void 0!==a.renderOrder&&(f.renderOrder=a.renderOrder);
 void 0!==a.userData&&(f.userData=a.userData);void 0!==a.layers&&(f.layers.mask=a.layers);if(void 0!==a.children){g=a.children;for(var h=0;h<g.length;h++)f.add(this.parseObject(g[h],b,c))}if("LOD"===a.type)for(a=a.levels,g=0;g<a.length;g++){h=a[g];var k=f.getObjectByProperty("uuid",h.object);void 0!==k&&f.addLevel(k,h.distance)}return f}});var nh={UVMapping:300,CubeReflectionMapping:301,CubeRefractionMapping:302,EquirectangularReflectionMapping:303,EquirectangularRefractionMapping:304,SphericalReflectionMapping:305,
 CubeUVReflectionMapping:306,CubeUVRefractionMapping:307},Sf={RepeatWrapping:1E3,ClampToEdgeWrapping:1001,MirroredRepeatWrapping:1002},Tf={NearestFilter:1003,NearestMipMapNearestFilter:1004,NearestMipMapLinearFilter:1005,LinearFilter:1006,LinearMipMapNearestFilter:1007,LinearMipMapLinearFilter:1008};te.prototype={constructor:te,setOptions:function(a){this.options=a;return this},load:function(a,b,c,d){void 0===a&&(a="");void 0!==this.path&&(a=this.path+a);a=this.manager.resolveURL(a);var e=this,f=Lb.get(a);
@@ -810,11 +810,11 @@ case "mapRoughness":l.roughnessMap=h(p,e.mapRoughnessRepeat,e.mapRoughnessOffset
 2;break;case "transparency":console.warn("THREE.Loader.createMaterial: transparency has been renamed to opacity");l.opacity=p;break;case "depthTest":case "depthWrite":case "colorWrite":case "opacity":case "reflectivity":case "transparent":case "visible":case "wireframe":l[n]=p;break;case "vertexColors":!0===p&&(l.vertexColors=2);"face"===p&&(l.vertexColors=1);break;default:console.error("THREE.Loader.createMaterial: Unsupported",n,p)}}"MeshBasicMaterial"===l.type&&delete l.emissive;"MeshPhongMaterial"!==
 l.type&&delete l.specular;1>l.opacity&&(l.transparent=!0);d.setTextures(k);return d.parse(l)}}()});var Zd,ze={getContext:function(){void 0===Zd&&(Zd=new (window.AudioContext||window.webkitAudioContext));return Zd},setContext:function(a){Zd=a}};Object.assign(we.prototype,{load:function(a,b,c,d){var e=new Ka(this.manager);e.setResponseType("arraybuffer");e.setPath(this.path);e.load(a,function(a){a=a.slice(0);ze.getContext().decodeAudioData(a,function(a){b(a)})},c,d)},setPath:function(a){this.path=a;
 return this}});Object.assign(Hf.prototype,{update:function(){var a,b,c,d,e,f,g,h,k=new J,l=new J;return function(m){if(a!==this||b!==m.focus||c!==m.fov||d!==m.aspect*this.aspect||e!==m.near||f!==m.far||g!==m.zoom||h!==this.eyeSep){a=this;b=m.focus;c=m.fov;d=m.aspect*this.aspect;e=m.near;f=m.far;g=m.zoom;var n=m.projectionMatrix.clone();h=this.eyeSep/2;var q=h*e/b,t=e*Math.tan(H.DEG2RAD*c*.5)/g;l.elements[12]=-h;k.elements[12]=h;var r=-t*d+q;var u=t*d+q;n.elements[0]=2*e/(u-r);n.elements[8]=(u+r)/
-(u-r);this.cameraL.projectionMatrix.copy(n);r=-t*d-q;u=t*d-q;n.elements[0]=2*e/(u-r);n.elements[8]=(u+r)/(u-r);this.cameraR.projectionMatrix.copy(n)}this.cameraL.matrixWorld.copy(m.matrixWorld).multiply(l);this.cameraR.matrixWorld.copy(m.matrixWorld).multiply(k)}}()});md.prototype=Object.create(E.prototype);md.prototype.constructor=md;Object.assign(xe.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},
-stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});ye.prototype=Object.assign(Object.create(E.prototype),{constructor:ye,getInput:function(){return this.gain},removeFilter:function(){null!==
+(u-r);this.cameraL.projectionMatrix.copy(n);r=-t*d-q;u=t*d-q;n.elements[0]=2*e/(u-r);n.elements[8]=(u+r)/(u-r);this.cameraR.projectionMatrix.copy(n)}this.cameraL.matrixWorld.copy(m.matrixWorld).multiply(l);this.cameraR.matrixWorld.copy(m.matrixWorld).multiply(k)}}()});md.prototype=Object.create(F.prototype);md.prototype.constructor=md;Object.assign(xe.prototype,{start:function(){this.oldTime=this.startTime=("undefined"===typeof performance?Date:performance).now();this.elapsedTime=0;this.running=!0},
+stop:function(){this.getElapsedTime();this.autoStart=this.running=!1},getElapsedTime:function(){this.getDelta();return this.elapsedTime},getDelta:function(){var a=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){var b=("undefined"===typeof performance?Date:performance).now();a=(b-this.oldTime)/1E3;this.oldTime=b;this.elapsedTime+=a}return a}});ye.prototype=Object.assign(Object.create(F.prototype),{constructor:ye,getInput:function(){return this.gain},removeFilter:function(){null!==
 this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null);return this},getFilter:function(){return this.filter},setFilter:function(a){null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination);this.filter=a;this.gain.connect(this.filter);this.filter.connect(this.context.destination);return this},getMasterVolume:function(){return this.gain.gain.value},
-setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this},updateMatrixWorld:function(){var a=new n,b=new aa,c=new n,d=new n,e=new xe;return function(f){E.prototype.updateMatrixWorld.call(this,f);f=this.context.listener;var g=this.up;this.timeDelta=e.getDelta();this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);if(f.positionX){var h=this.context.currentTime+this.timeDelta;f.positionX.linearRampToValueAtTime(a.x,h);f.positionY.linearRampToValueAtTime(a.y,
-h);f.positionZ.linearRampToValueAtTime(a.z,h);f.forwardX.linearRampToValueAtTime(d.x,h);f.forwardY.linearRampToValueAtTime(d.y,h);f.forwardZ.linearRampToValueAtTime(d.z,h);f.upX.linearRampToValueAtTime(g.x,h);f.upY.linearRampToValueAtTime(g.y,h);f.upZ.linearRampToValueAtTime(g.z,h)}else f.setPosition(a.x,a.y,a.z),f.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}()});mc.prototype=Object.assign(Object.create(E.prototype),{constructor:mc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=
+setMasterVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this},updateMatrixWorld:function(){var a=new n,b=new aa,c=new n,d=new n,e=new xe;return function(f){F.prototype.updateMatrixWorld.call(this,f);f=this.context.listener;var g=this.up;this.timeDelta=e.getDelta();this.matrixWorld.decompose(a,b,c);d.set(0,0,-1).applyQuaternion(b);if(f.positionX){var h=this.context.currentTime+this.timeDelta;f.positionX.linearRampToValueAtTime(a.x,h);f.positionY.linearRampToValueAtTime(a.y,
+h);f.positionZ.linearRampToValueAtTime(a.z,h);f.forwardX.linearRampToValueAtTime(d.x,h);f.forwardY.linearRampToValueAtTime(d.y,h);f.forwardZ.linearRampToValueAtTime(d.z,h);f.upX.linearRampToValueAtTime(g.x,h);f.upY.linearRampToValueAtTime(g.y,h);f.upZ.linearRampToValueAtTime(g.z,h)}else f.setPosition(a.x,a.y,a.z),f.setOrientation(d.x,d.y,d.z,g.x,g.y,g.z)}}()});mc.prototype=Object.assign(Object.create(F.prototype),{constructor:mc,getOutput:function(){return this.gain},setNodeSource:function(a){this.hasPlaybackControl=
 !1;this.sourceType="audioNode";this.source=a;this.connect();return this},setMediaElementSource:function(a){this.hasPlaybackControl=!1;this.sourceType="mediaNode";this.source=this.context.createMediaElementSource(a);this.connect();return this},setBuffer:function(a){this.buffer=a;this.sourceType="buffer";this.autoplay&&this.play();return this},play:function(){if(!0===this.isPlaying)console.warn("THREE.Audio: Audio is already playing.");else if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");
 else{var a=this.context.createBufferSource();a.buffer=this.buffer;a.loop=this.loop;a.onended=this.onEnded.bind(this);this.startTime=this.context.currentTime;a.start(this.startTime,this.offset);this.isPlaying=!0;this.source=a;this.setDetune(this.detune);this.setPlaybackRate(this.playbackRate);return this.connect()}},pause:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return!0===this.isPlaying&&(this.source.stop(),this.source.onended=
 null,this.offset+=(this.context.currentTime-this.startTime)*this.playbackRate,this.isPlaying=!1),this},stop:function(){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.source.stop(),this.source.onended=null,this.offset=0,this.isPlaying=!1,this},connect:function(){if(0<this.filters.length){this.source.connect(this.filters[0]);for(var a=1,b=this.filters.length;a<b;a++)this.filters[a-1].connect(this.filters[a]);this.filters[this.filters.length-
@@ -822,7 +822,7 @@ null,this.offset+=(this.context.currentTime-this.startTime)*this.playbackRate,th
 a,this.connect()):this.filters=a;return this},setDetune:function(a){this.detune=a;if(void 0!==this.source.detune)return!0===this.isPlaying&&this.source.detune.setTargetAtTime(this.detune,this.context.currentTime,.01),this},getDetune:function(){return this.detune},getFilter:function(){return this.getFilters()[0]},setFilter:function(a){return this.setFilters(a?[a]:[])},setPlaybackRate:function(a){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.playbackRate=
 a,!0===this.isPlaying&&this.source.playbackRate.setTargetAtTime(this.playbackRate,this.context.currentTime,.01),this},getPlaybackRate:function(){return this.playbackRate},onEnded:function(){this.isPlaying=!1},getLoop:function(){return!1===this.hasPlaybackControl?(console.warn("THREE.Audio: this Audio has no playback control."),!1):this.loop},setLoop:function(a){if(!1===this.hasPlaybackControl)console.warn("THREE.Audio: this Audio has no playback control.");else return this.loop=a,!0===this.isPlaying&&
 (this.source.loop=this.loop),this},getVolume:function(){return this.gain.gain.value},setVolume:function(a){this.gain.gain.setTargetAtTime(a,this.context.currentTime,.01);return this}});Ae.prototype=Object.assign(Object.create(mc.prototype),{constructor:Ae,getOutput:function(){return this.panner},getRefDistance:function(){return this.panner.refDistance},setRefDistance:function(a){this.panner.refDistance=a;return this},getRolloffFactor:function(){return this.panner.rolloffFactor},setRolloffFactor:function(a){this.panner.rolloffFactor=
-a;return this},getDistanceModel:function(){return this.panner.distanceModel},setDistanceModel:function(a){this.panner.distanceModel=a;return this},getMaxDistance:function(){return this.panner.maxDistance},setMaxDistance:function(a){this.panner.maxDistance=a;return this},setDirectionalCone:function(a,b,c){this.panner.coneInnerAngle=a;this.panner.coneOuterAngle=b;this.panner.coneOuterGain=c;return this},updateMatrixWorld:function(){var a=new n,b=new aa,c=new n,d=new n;return function(e){E.prototype.updateMatrixWorld.call(this,
+a;return this},getDistanceModel:function(){return this.panner.distanceModel},setDistanceModel:function(a){this.panner.distanceModel=a;return this},getMaxDistance:function(){return this.panner.maxDistance},setMaxDistance:function(a){this.panner.maxDistance=a;return this},setDirectionalCone:function(a,b,c){this.panner.coneInnerAngle=a;this.panner.coneOuterAngle=b;this.panner.coneOuterGain=c;return this},updateMatrixWorld:function(){var a=new n,b=new aa,c=new n,d=new n;return function(e){F.prototype.updateMatrixWorld.call(this,
 e);if(!0!==this.hasPlaybackControl||!1!==this.isPlaying)if(this.matrixWorld.decompose(a,b,c),d.set(0,0,1).applyQuaternion(b),e=this.panner,e.positionX){var f=this.context.currentTime+this.listener.timeDelta;e.positionX.linearRampToValueAtTime(a.x,f);e.positionY.linearRampToValueAtTime(a.y,f);e.positionZ.linearRampToValueAtTime(a.z,f);e.orientationX.linearRampToValueAtTime(d.x,f);e.orientationY.linearRampToValueAtTime(d.y,f);e.orientationZ.linearRampToValueAtTime(d.z,f)}else e.setPosition(a.x,a.y,
 a.z),e.setOrientation(d.x,d.y,d.z)}}()});Object.assign(Be.prototype,{getFrequencyData:function(){this.analyser.getByteFrequencyData(this.data);return this.data},getAverageFrequency:function(){for(var a=0,b=this.getFrequencyData(),c=0;c<b.length;c++)a+=b[c];return a/b.length}});Object.assign(Ce.prototype,{accumulate:function(a,b){var c=this.buffer,d=this.valueSize;a=a*d+d;var e=this.cumulativeWeight;if(0===e){for(e=0;e!==d;++e)c[a+e]=c[e];e=b}else e+=b,this._mixBufferRegion(c,a,0,b/e,d);this.cumulativeWeight=
 e},apply:function(a){var b=this.valueSize,c=this.buffer;a=a*b+b;var d=this.cumulativeWeight,e=this.binding;this.cumulativeWeight=0;1>d&&this._mixBufferRegion(c,a,3*b,1-d,b);d=b;for(var f=b+b;d!==f;++d)if(c[d]!==c[d+b]){e.setValue(c,a);break}},saveOriginalState:function(){var a=this.buffer,b=this.valueSize,c=3*b;this.binding.getValue(a,c);for(var d=b;d!==c;++d)a[d]=a[c+d%b];this.cumulativeWeight=0},restoreOriginalState:function(){this.binding.setValue(this.buffer,3*this.valueSize)},_select:function(a,
@@ -876,24 +876,24 @@ return b.set((a.x-this.min.x)/(this.max.x-this.min.x),(a.y-this.min.y)/(this.max
 this.max.min(a.max);return this},union:function(a){this.min.min(a.min);this.max.max(a.max);return this},translate:function(a){this.min.add(a);this.max.add(a);return this},equals:function(a){return a.min.equals(this.min)&&a.max.equals(this.max)}});Object.assign(Je.prototype,{set:function(a,b){this.start.copy(a);this.end.copy(b);return this},clone:function(){return(new this.constructor).copy(this)},copy:function(a){this.start.copy(a.start);this.end.copy(a.end);return this},getCenter:function(a){void 0===
 a&&(console.warn("THREE.Line3: .getCenter() target is now required"),a=new n);return a.addVectors(this.start,this.end).multiplyScalar(.5)},delta:function(a){void 0===a&&(console.warn("THREE.Line3: .delta() target is now required"),a=new n);return a.subVectors(this.end,this.start)},distanceSq:function(){return this.start.distanceToSquared(this.end)},distance:function(){return this.start.distanceTo(this.end)},at:function(a,b){void 0===b&&(console.warn("THREE.Line3: .at() target is now required"),b=
 new n);return this.delta(b).multiplyScalar(a).add(this.start)},closestPointToPointParameter:function(){var a=new n,b=new n;return function(c,d){a.subVectors(c,this.start);b.subVectors(this.end,this.start);c=b.dot(b);c=b.dot(a)/c;d&&(c=H.clamp(c,0,1));return c}}(),closestPointToPoint:function(a,b,c){a=this.closestPointToPointParameter(a,b);void 0===c&&(console.warn("THREE.Line3: .closestPointToPoint() target is now required"),c=new n);return this.delta(c).multiplyScalar(a).add(this.start)},applyMatrix4:function(a){this.start.applyMatrix4(a);
-this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});nd.prototype=Object.create(E.prototype);nd.prototype.constructor=nd;nd.prototype.isImmediateRenderObject=!0;od.prototype=Object.create(W.prototype);od.prototype.constructor=od;od.prototype.update=function(){var a=new n,b=new n,c=new pa;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=
+this.end.applyMatrix4(a);return this},equals:function(a){return a.start.equals(this.start)&&a.end.equals(this.end)}});nd.prototype=Object.create(F.prototype);nd.prototype.constructor=nd;nd.prototype.isImmediateRenderObject=!0;od.prototype=Object.create(W.prototype);od.prototype.constructor=od;od.prototype.update=function(){var a=new n,b=new n,c=new pa;return function(){var d=["a","b","c"];this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var e=this.object.matrixWorld,f=
 this.geometry.attributes.position,g=this.object.geometry;if(g&&g.isGeometry)for(var h=g.vertices,k=g.faces,l=g=0,n=k.length;l<n;l++)for(var p=k[l],v=0,t=p.vertexNormals.length;v<t;v++){var r=p.vertexNormals[v];a.copy(h[p[d[v]]]).applyMatrix4(e);b.copy(r).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);f.setXYZ(g,a.x,a.y,a.z);g+=1;f.setXYZ(g,b.x,b.y,b.z);g+=1}else if(g&&g.isBufferGeometry)for(d=g.attributes.position,h=g.attributes.normal,v=g=0,t=d.count;v<t;v++)a.set(d.getX(v),d.getY(v),
-d.getZ(v)).applyMatrix4(e),b.set(h.getX(v),h.getY(v),h.getZ(v)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),f.setXYZ(g,a.x,a.y,a.z),g+=1,f.setXYZ(g,b.x,b.y,b.z),g+=1;f.needsUpdate=!0}}();nc.prototype=Object.create(E.prototype);nc.prototype.constructor=nc;nc.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};nc.prototype.update=function(){var a=new n;return function(){this.light.updateMatrixWorld();var b=this.light.distance?this.light.distance:
+d.getZ(v)).applyMatrix4(e),b.set(h.getX(v),h.getY(v),h.getZ(v)),b.applyMatrix3(c).normalize().multiplyScalar(this.size).add(a),f.setXYZ(g,a.x,a.y,a.z),g+=1,f.setXYZ(g,b.x,b.y,b.z),g+=1;f.needsUpdate=!0}}();nc.prototype=Object.create(F.prototype);nc.prototype.constructor=nc;nc.prototype.dispose=function(){this.cone.geometry.dispose();this.cone.material.dispose()};nc.prototype.update=function(){var a=new n;return function(){this.light.updateMatrixWorld();var b=this.light.distance?this.light.distance:
 1E3,c=b*Math.tan(this.light.angle);this.cone.scale.set(c,c,b);a.setFromMatrixPosition(this.light.target.matrixWorld);this.cone.lookAt(a);void 0!==this.color?this.cone.material.color.set(this.color):this.cone.material.color.copy(this.light.color)}}();oc.prototype=Object.create(W.prototype);oc.prototype.constructor=oc;oc.prototype.updateMatrixWorld=function(){var a=new n,b=new J,c=new J;return function(d){var e=this.bones,f=this.geometry,g=f.getAttribute("position");c.getInverse(this.root.matrixWorld);
-for(var h=0,k=0;h<e.length;h++){var l=e[h];l.parent&&l.parent.isBone&&(b.multiplyMatrices(c,l.matrixWorld),a.setFromMatrixPosition(b),g.setXYZ(k,a.x,a.y,a.z),b.multiplyMatrices(c,l.parent.matrixWorld),a.setFromMatrixPosition(b),g.setXYZ(k+1,a.x,a.y,a.z),k+=2)}f.getAttribute("position").needsUpdate=!0;E.prototype.updateMatrixWorld.call(this,d)}}();pc.prototype=Object.create(va.prototype);pc.prototype.constructor=pc;pc.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};pc.prototype.update=
+for(var h=0,k=0;h<e.length;h++){var l=e[h];l.parent&&l.parent.isBone&&(b.multiplyMatrices(c,l.matrixWorld),a.setFromMatrixPosition(b),g.setXYZ(k,a.x,a.y,a.z),b.multiplyMatrices(c,l.parent.matrixWorld),a.setFromMatrixPosition(b),g.setXYZ(k+1,a.x,a.y,a.z),k+=2)}f.getAttribute("position").needsUpdate=!0;F.prototype.updateMatrixWorld.call(this,d)}}();pc.prototype=Object.create(va.prototype);pc.prototype.constructor=pc;pc.prototype.dispose=function(){this.geometry.dispose();this.material.dispose()};pc.prototype.update=
 function(){void 0!==this.color?this.material.color.set(this.color):this.material.color.copy(this.light.color)};qc.prototype=Object.create(da.prototype);qc.prototype.constructor=qc;qc.prototype.update=function(){this.scale.set(.5*this.light.width,.5*this.light.height,1);if(void 0!==this.color)this.material.color.set(this.color),this.children[0].material.color.set(this.color);else{this.material.color.copy(this.light.color).multiplyScalar(this.light.intensity);var a=this.material.color,b=Math.max(a.r,
-a.g,a.b);1<b&&a.multiplyScalar(1/b);this.children[0].material.color.copy(this.material.color)}};qc.prototype.dispose=function(){this.geometry.dispose();this.material.dispose();this.children[0].geometry.dispose();this.children[0].material.dispose()};rc.prototype=Object.create(E.prototype);rc.prototype.constructor=rc;rc.prototype.dispose=function(){this.children[0].geometry.dispose();this.children[0].material.dispose()};rc.prototype.update=function(){var a=new n,b=new K,c=new K;return function(){var d=
+a.g,a.b);1<b&&a.multiplyScalar(1/b);this.children[0].material.color.copy(this.material.color)}};qc.prototype.dispose=function(){this.geometry.dispose();this.material.dispose();this.children[0].geometry.dispose();this.children[0].material.dispose()};rc.prototype=Object.create(F.prototype);rc.prototype.constructor=rc;rc.prototype.dispose=function(){this.children[0].geometry.dispose();this.children[0].material.dispose()};rc.prototype.update=function(){var a=new n,b=new K,c=new K;return function(){var d=
 this.children[0];if(void 0!==this.color)this.material.color.set(this.color);else{var e=d.geometry.getAttribute("color");b.copy(this.light.color);c.copy(this.light.groundColor);for(var f=0,g=e.count;f<g;f++){var h=f<g/2?b:c;e.setXYZ(f,h.r,h.g,h.b)}e.needsUpdate=!0}d.lookAt(a.setFromMatrixPosition(this.light.matrixWorld).negate())}}();pd.prototype=Object.create(W.prototype);pd.prototype.constructor=pd;Wd.prototype=Object.create(W.prototype);Wd.prototype.constructor=Wd;sc.prototype=Object.create(da.prototype);
 sc.prototype.constructor=sc;sc.prototype.update=function(){function a(a,b,d,e){d=(b-a)/d;t.setXYZ(k,0,0,0);l++;for(n=a;n<b;n+=d)p=k+l,t.setXYZ(p,Math.sin(n)*c,0,Math.cos(n)*c),t.setXYZ(p+1,Math.sin(Math.min(n+d,b))*c,0,Math.cos(Math.min(n+d,b))*c),t.setXYZ(p+2,0,0,0),l+=3;v.addGroup(k,l,e);k+=l;l=0}var b=this.audio,c=this.range,d=this.divisionsInnerAngle,e=this.divisionsOuterAngle,f=H.degToRad(b.panner.coneInnerAngle);b=H.degToRad(b.panner.coneOuterAngle);var g=f/2,h=b/2,k=0,l=0,n,p,v=this.geometry,
 t=v.attributes.position;v.clearGroups();a(-h,-g,e,0);a(-g,g,d,1);a(g,h,e,0);t.needsUpdate=!0;f===b&&(this.material[0].visible=!1)};sc.prototype.dispose=function(){this.geometry.dispose();this.material[0].dispose();this.material[1].dispose()};qd.prototype=Object.create(W.prototype);qd.prototype.constructor=qd;qd.prototype.update=function(){var a=new n,b=new n,c=new pa;return function(){this.object.updateMatrixWorld(!0);c.getNormalMatrix(this.object.matrixWorld);var d=this.object.matrixWorld,e=this.geometry.attributes.position,
-f=this.object.geometry,g=f.vertices;f=f.faces;for(var h=0,k=0,l=f.length;k<l;k++){var n=f[k],p=n.normal;a.copy(g[n.a]).add(g[n.b]).add(g[n.c]).divideScalar(3).applyMatrix4(d);b.copy(p).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);e.setXYZ(h,a.x,a.y,a.z);h+=1;e.setXYZ(h,b.x,b.y,b.z);h+=1}e.needsUpdate=!0}}();tc.prototype=Object.create(E.prototype);tc.prototype.constructor=tc;tc.prototype.dispose=function(){this.lightPlane.geometry.dispose();this.lightPlane.material.dispose();this.targetLine.geometry.dispose();
+f=this.object.geometry,g=f.vertices;f=f.faces;for(var h=0,k=0,l=f.length;k<l;k++){var n=f[k],p=n.normal;a.copy(g[n.a]).add(g[n.b]).add(g[n.c]).divideScalar(3).applyMatrix4(d);b.copy(p).applyMatrix3(c).normalize().multiplyScalar(this.size).add(a);e.setXYZ(h,a.x,a.y,a.z);h+=1;e.setXYZ(h,b.x,b.y,b.z);h+=1}e.needsUpdate=!0}}();tc.prototype=Object.create(F.prototype);tc.prototype.constructor=tc;tc.prototype.dispose=function(){this.lightPlane.geometry.dispose();this.lightPlane.material.dispose();this.targetLine.geometry.dispose();
 this.targetLine.material.dispose()};tc.prototype.update=function(){var a=new n,b=new n,c=new n;return function(){a.setFromMatrixPosition(this.light.matrixWorld);b.setFromMatrixPosition(this.light.target.matrixWorld);c.subVectors(b,a);this.lightPlane.lookAt(b);void 0!==this.color?(this.lightPlane.material.color.set(this.color),this.targetLine.material.color.set(this.color)):(this.lightPlane.material.color.copy(this.light.color),this.targetLine.material.color.copy(this.light.color));this.targetLine.lookAt(b);
 this.targetLine.scale.z=c.length()}}();rd.prototype=Object.create(W.prototype);rd.prototype.constructor=rd;rd.prototype.update=function(){function a(a,g,h,k){d.set(g,h,k).unproject(e);a=c[a];if(void 0!==a)for(g=b.getAttribute("position"),h=0,k=a.length;h<k;h++)g.setXYZ(a[h],d.x,d.y,d.z)}var b,c,d=new n,e=new Ua;return function(){b=this.geometry;c=this.pointMap;e.projectionMatrix.copy(this.camera.projectionMatrix);a("c",0,0,-1);a("t",0,0,1);a("n1",-1,-1,-1);a("n2",1,-1,-1);a("n3",-1,1,-1);a("n4",1,
 1,-1);a("f1",-1,-1,1);a("f2",1,-1,1);a("f3",-1,1,1);a("f4",1,1,1);a("u1",.7,1.1,-1);a("u2",-.7,1.1,-1);a("u3",0,2,-1);a("cf1",-1,0,1);a("cf2",1,0,1);a("cf3",0,-1,1);a("cf4",0,1,1);a("cn1",-1,0,-1);a("cn2",1,0,-1);a("cn3",0,-1,-1);a("cn4",0,1,-1);b.getAttribute("position").needsUpdate=!0}}();db.prototype=Object.create(W.prototype);db.prototype.constructor=db;db.prototype.update=function(){var a=new Za;return function(b){void 0!==b&&console.warn("THREE.BoxHelper: .update() has no longer arguments.");
 void 0!==this.object&&a.setFromObject(this.object);if(!a.isEmpty()){b=a.min;var c=a.max,d=this.geometry.attributes.position,e=d.array;e[0]=c.x;e[1]=c.y;e[2]=c.z;e[3]=b.x;e[4]=c.y;e[5]=c.z;e[6]=b.x;e[7]=b.y;e[8]=c.z;e[9]=c.x;e[10]=b.y;e[11]=c.z;e[12]=c.x;e[13]=c.y;e[14]=b.z;e[15]=b.x;e[16]=c.y;e[17]=b.z;e[18]=b.x;e[19]=b.y;e[20]=b.z;e[21]=c.x;e[22]=b.y;e[23]=b.z;d.needsUpdate=!0;this.geometry.computeBoundingSphere()}}}();db.prototype.setFromObject=function(a){this.object=a;this.update();return this};
-db.prototype.copy=function(a){W.prototype.copy.call(this,a);this.object=a.object;return this};db.prototype.clone=function(){return(new this.constructor).copy(this)};sd.prototype=Object.create(W.prototype);sd.prototype.constructor=sd;sd.prototype.updateMatrixWorld=function(a){var b=this.box;b.isEmpty()||(b.getCenter(this.position),b.getSize(this.scale),this.scale.multiplyScalar(.5),E.prototype.updateMatrixWorld.call(this,a))};td.prototype=Object.create(da.prototype);td.prototype.constructor=td;td.prototype.updateMatrixWorld=
-function(a){var b=-this.plane.constant;1E-8>Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);E.prototype.updateMatrixWorld.call(this,a)};var Xd,Ke;eb.prototype=Object.create(E.prototype);eb.prototype.constructor=eb;eb.prototype.setDirection=function(){var a=new n,b;return function(c){.99999<c.y?this.quaternion.set(0,0,0,1):-.99999>c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),
-this.quaternion.setFromAxisAngle(a,b))}}();eb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};eb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};eb.prototype.copy=function(a){E.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};eb.prototype.clone=
+db.prototype.copy=function(a){W.prototype.copy.call(this,a);this.object=a.object;return this};db.prototype.clone=function(){return(new this.constructor).copy(this)};sd.prototype=Object.create(W.prototype);sd.prototype.constructor=sd;sd.prototype.updateMatrixWorld=function(a){var b=this.box;b.isEmpty()||(b.getCenter(this.position),b.getSize(this.scale),this.scale.multiplyScalar(.5),F.prototype.updateMatrixWorld.call(this,a))};td.prototype=Object.create(da.prototype);td.prototype.constructor=td;td.prototype.updateMatrixWorld=
+function(a){var b=-this.plane.constant;1E-8>Math.abs(b)&&(b=1E-8);this.scale.set(.5*this.size,.5*this.size,b);this.children[0].material.side=0>b?1:0;this.lookAt(this.plane.normal);F.prototype.updateMatrixWorld.call(this,a)};var Xd,Ke;eb.prototype=Object.create(F.prototype);eb.prototype.constructor=eb;eb.prototype.setDirection=function(){var a=new n,b;return function(c){.99999<c.y?this.quaternion.set(0,0,0,1):-.99999>c.y?this.quaternion.set(1,0,0,0):(a.set(c.z,0,-c.x).normalize(),b=Math.acos(c.y),
+this.quaternion.setFromAxisAngle(a,b))}}();eb.prototype.setLength=function(a,b,c){void 0===b&&(b=.2*a);void 0===c&&(c=.2*b);this.line.scale.set(1,Math.max(0,a-b),1);this.line.updateMatrix();this.cone.scale.set(c,b,c);this.cone.position.y=a;this.cone.updateMatrix()};eb.prototype.setColor=function(a){this.line.material.color.copy(a);this.cone.material.color.copy(a)};eb.prototype.copy=function(a){F.prototype.copy.call(this,a,!1);this.line.copy(a.line);this.cone.copy(a.cone);return this};eb.prototype.clone=
 function(){return(new this.constructor).copy(this)};ud.prototype=Object.create(W.prototype);ud.prototype.constructor=ud;L.create=function(a,b){console.log("THREE.Curve.create() has been deprecated");a.prototype=Object.create(L.prototype);a.prototype.constructor=a;a.prototype.getPoint=b;return a};Object.assign(cb.prototype,{createPointsGeometry:function(a){console.warn("THREE.CurvePath: .createPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getPoints(a);
 return this.createGeometry(a)},createSpacedPointsGeometry:function(a){console.warn("THREE.CurvePath: .createSpacedPointsGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");a=this.getSpacedPoints(a);return this.createGeometry(a)},createGeometry:function(a){console.warn("THREE.CurvePath: .createGeometry() has been removed. Use new THREE.Geometry().setFromPoints( points ) instead.");for(var b=new G,c=0,d=a.length;c<d;c++){var e=a[c];b.vertices.push(new n(e.x,e.y,
 e.z||0))}return b}});Object.assign(Pa.prototype,{fromPoints:function(a){console.warn("THREE.Path: .fromPoints() has been renamed to .setFromPoints().");this.setFromPoints(a)}});Qf.prototype=Object.create(oa.prototype);Rf.prototype=Object.create(oa.prototype);Le.prototype=Object.create(oa.prototype);Object.assign(Le.prototype,{initFromArray:function(){console.error("THREE.Spline: .initFromArray() has been removed.")},getControlPointsArray:function(){console.error("THREE.Spline: .getControlPointsArray() has been removed.")},
@@ -916,8 +916,8 @@ return this.manhattanDistanceTo(a)},lengthManhattan:function(){console.warn("THR
 getPositionFromMatrix:function(a){console.warn("THREE.Vector3: .getPositionFromMatrix() has been renamed to .setFromMatrixPosition().");return this.setFromMatrixPosition(a)},getScaleFromMatrix:function(a){console.warn("THREE.Vector3: .getScaleFromMatrix() has been renamed to .setFromMatrixScale().");return this.setFromMatrixScale(a)},getColumnFromMatrix:function(a,b){console.warn("THREE.Vector3: .getColumnFromMatrix() has been renamed to .setFromMatrixColumn().");return this.setFromMatrixColumn(b,
 a)},applyProjection:function(a){console.warn("THREE.Vector3: .applyProjection() has been removed. Use .applyMatrix4( m ) instead.");return this.applyMatrix4(a)},fromAttribute:function(a,b,c){console.warn("THREE.Vector3: .fromAttribute() has been renamed to .fromBufferAttribute().");return this.fromBufferAttribute(a,b,c)},distanceToManhattan:function(a){console.warn("THREE.Vector3: .distanceToManhattan() has been renamed to .manhattanDistanceTo().");return this.manhattanDistanceTo(a)},lengthManhattan:function(){console.warn("THREE.Vector3: .lengthManhattan() has been renamed to .manhattanLength().");
 return this.manhattanLength()}});Object.assign(ba.prototype,{fromAttribute:function(a,b,c){console.warn("THREE.Vector4: .fromAttribute() has been renamed to .fromBufferAttribute().");return this.fromBufferAttribute(a,b,c)},lengthManhattan:function(){console.warn("THREE.Vector4: .lengthManhattan() has been renamed to .manhattanLength().");return this.manhattanLength()}});Object.assign(G.prototype,{computeTangents:function(){console.error("THREE.Geometry: .computeTangents() has been removed.")},computeLineDistances:function(){console.error("THREE.Geometry: .computeLineDistances() has been removed. Use THREE.Line.computeLineDistances() instead.")}});
-Object.assign(E.prototype,{getChildByName:function(a){console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().");return this.getObjectByName(a)},renderDepth:function(){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},translate:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)},getWorldRotation:function(){console.error("THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.")}});
-Object.defineProperties(E.prototype,{eulerOrder:{get:function(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set:function(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");this.rotation.order=a}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}});
+Object.assign(F.prototype,{getChildByName:function(a){console.warn("THREE.Object3D: .getChildByName() has been renamed to .getObjectByName().");return this.getObjectByName(a)},renderDepth:function(){console.warn("THREE.Object3D: .renderDepth has been removed. Use .renderOrder, instead.")},translate:function(a,b){console.warn("THREE.Object3D: .translate() has been removed. Use .translateOnAxis( axis, distance ) instead.");return this.translateOnAxis(b,a)},getWorldRotation:function(){console.error("THREE.Object3D: .getWorldRotation() has been removed. Use THREE.Object3D.getWorldQuaternion( target ) instead.")}});
+Object.defineProperties(F.prototype,{eulerOrder:{get:function(){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");return this.rotation.order},set:function(a){console.warn("THREE.Object3D: .eulerOrder is now .rotation.order.");this.rotation.order=a}},useQuaternion:{get:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")},set:function(){console.warn("THREE.Object3D: .useQuaternion has been removed. The library now uses quaternions by default.")}}});
 Object.defineProperties(Ic.prototype,{objects:{get:function(){console.warn("THREE.LOD: .objects has been renamed to .levels.");return this.levels}}});Object.defineProperty(Cd.prototype,"useVertexTexture",{get:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")},set:function(){console.warn("THREE.Skeleton: useVertexTexture has been removed.")}});Jc.prototype.initBones=function(){console.error("THREE.SkinnedMesh: initBones() has been removed.")};Object.defineProperty(L.prototype,
 "__arcLengthDivisions",{get:function(){console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.");return this.arcLengthDivisions},set:function(a){console.warn("THREE.Curve: .__arcLengthDivisions is now .arcLengthDivisions.");this.arcLengthDivisions=a}});U.prototype.setLens=function(a,b){console.warn("THREE.PerspectiveCamera.setLens is deprecated. Use .setFocalLength and .filmGauge for a photographic setup.");void 0!==b&&(this.filmGauge=b);this.setFocalLength(a)};Object.defineProperties(ia.prototype,
 {onlyShadow:{set:function(){console.warn("THREE.Light: .onlyShadow has been removed.")}},shadowCameraFov:{set:function(a){console.warn("THREE.Light: .shadowCameraFov is now .shadow.camera.fov.");this.shadow.camera.fov=a}},shadowCameraLeft:{set:function(a){console.warn("THREE.Light: .shadowCameraLeft is now .shadow.camera.left.");this.shadow.camera.left=a}},shadowCameraRight:{set:function(a){console.warn("THREE.Light: .shadowCameraRight is now .shadow.camera.right.");this.shadow.camera.right=a}},shadowCameraTop:{set:function(a){console.warn("THREE.Light: .shadowCameraTop is now .shadow.camera.top.");
@@ -949,11 +949,11 @@ var e=new pe;e.setCrossOrigin(this.crossOrigin);a=e.load(a,c,void 0,d);b&&(a.map
 Ta;l.UniformsLib=I;l.UniformsUtils=jh;l.ShaderChunk=V;l.FogExp2=zd;l.Fog=Ad;l.Scene=Bd;l.Sprite=Hc;l.LOD=Ic;l.SkinnedMesh=Jc;l.Skeleton=Cd;l.Bone=je;l.Mesh=va;l.LineSegments=W;l.LineLoop=Dd;l.Line=da;l.Points=Vb;l.Group=Tb;l.VideoTexture=ke;l.DataTexture=nb;l.DataTexture2DArray=Qb;l.DataTexture3D=Rb;l.CompressedTexture=Wb;l.CubeTexture=$a;l.CanvasTexture=Kc;l.DepthTexture=Lc;l.Texture=S;l.AnimationLoader=Df;l.CompressedTextureLoader=Ef;l.DataTextureLoader=oe;l.CubeTextureLoader=pe;l.TextureLoader=
 Ld;l.ObjectLoader=se;l.MaterialLoader=Ud;l.BufferGeometryLoader=re;l.DefaultLoadingManager=Ba;l.LoadingManager=ne;l.ImageLoader=hd;l.ImageBitmapLoader=te;l.FontLoader=Gf;l.FileLoader=Ka;l.Loader=ld;l.LoaderUtils=Qe;l.Cache=Lb;l.AudioLoader=we;l.SpotLightShadow=Nd;l.SpotLight=Od;l.PointLight=Pd;l.RectAreaLight=Td;l.HemisphereLight=Md;l.DirectionalLightShadow=Qd;l.DirectionalLight=Rd;l.AmbientLight=Sd;l.LightShadow=Kb;l.Light=ia;l.StereoCamera=Hf;l.PerspectiveCamera=U;l.OrthographicCamera=kd;l.CubeCamera=
 md;l.ArrayCamera=Fc;l.Camera=Ua;l.AudioListener=ye;l.PositionalAudio=Ae;l.AudioContext=ze;l.AudioAnalyser=Be;l.Audio=mc;l.VectorKeyframeTrack=kc;l.StringKeyframeTrack=Kd;l.QuaternionKeyframeTrack=gd;l.NumberKeyframeTrack=jc;l.ColorKeyframeTrack=Id;l.BooleanKeyframeTrack=Hd;l.PropertyMixer=Ce;l.PropertyBinding=ma;l.KeyframeTrack=ra;l.AnimationUtils=sa;l.AnimationObjectGroup=Jf;l.AnimationMixer=De;l.AnimationClip=Ga;l.Uniform=Vd;l.InstancedBufferGeometry=Ee;l.BufferGeometry=D;l.Geometry=G;l.InterleavedBufferAttribute=
-Gc;l.InstancedInterleavedBuffer=Fe;l.InterleavedBuffer=ub;l.InstancedBufferAttribute=Ge;l.Face3=Nb;l.Object3D=E;l.Raycaster=Lf;l.Layers=be;l.EventDispatcher=ka;l.Clock=xe;l.QuaternionLinearInterpolant=Jd;l.LinearInterpolant=fd;l.DiscreteInterpolant=Gd;l.CubicInterpolant=Fd;l.Interpolant=wa;l.Triangle=ua;l.Math=H;l.Spherical=Nf;l.Cylindrical=Of;l.Plane=Sa;l.Frustum=vd;l.Sphere=Ha;l.Ray=tb;l.Matrix4=J;l.Matrix3=pa;l.Box3=Za;l.Box2=Ie;l.Line3=Je;l.Euler=ob;l.Vector4=ba;l.Vector3=n;l.Vector2=B;l.Quaternion=
+Gc;l.InstancedInterleavedBuffer=Fe;l.InterleavedBuffer=ub;l.InstancedBufferAttribute=Ge;l.Face3=Nb;l.Object3D=F;l.Raycaster=Lf;l.Layers=be;l.EventDispatcher=ka;l.Clock=xe;l.QuaternionLinearInterpolant=Jd;l.LinearInterpolant=fd;l.DiscreteInterpolant=Gd;l.CubicInterpolant=Fd;l.Interpolant=wa;l.Triangle=ua;l.Math=H;l.Spherical=Nf;l.Cylindrical=Of;l.Plane=Sa;l.Frustum=vd;l.Sphere=Ha;l.Ray=tb;l.Matrix4=J;l.Matrix3=pa;l.Box3=Za;l.Box2=Ie;l.Line3=Je;l.Euler=ob;l.Vector4=ba;l.Vector3=n;l.Vector2=B;l.Quaternion=
 aa;l.Color=K;l.ImmediateRenderObject=nd;l.VertexNormalsHelper=od;l.SpotLightHelper=nc;l.SkeletonHelper=oc;l.PointLightHelper=pc;l.RectAreaLightHelper=qc;l.HemisphereLightHelper=rc;l.GridHelper=pd;l.PolarGridHelper=Wd;l.PositionalAudioHelper=sc;l.FaceNormalsHelper=qd;l.DirectionalLightHelper=tc;l.CameraHelper=rd;l.BoxHelper=db;l.Box3Helper=sd;l.PlaneHelper=td;l.ArrowHelper=eb;l.AxesHelper=ud;l.Shape=kb;l.Path=Pa;l.ShapePath=ue;l.Font=ve;l.CurvePath=cb;l.Curve=L;l.ImageUtils=lb;l.ShapeUtils=ab;l.WebGLUtils=
 pf;l.WireframeGeometry=Xb;l.ParametricGeometry=Mc;l.ParametricBufferGeometry=Yb;l.TetrahedronGeometry=Oc;l.TetrahedronBufferGeometry=Zb;l.OctahedronGeometry=Pc;l.OctahedronBufferGeometry=vb;l.IcosahedronGeometry=Qc;l.IcosahedronBufferGeometry=$b;l.DodecahedronGeometry=Rc;l.DodecahedronBufferGeometry=ac;l.PolyhedronGeometry=Nc;l.PolyhedronBufferGeometry=Aa;l.TubeGeometry=Sc;l.TubeBufferGeometry=wb;l.TorusKnotGeometry=Tc;l.TorusKnotBufferGeometry=bc;l.TorusGeometry=Uc;l.TorusBufferGeometry=cc;l.TextGeometry=
 Zc;l.TextBufferGeometry=dc;l.SphereGeometry=$c;l.SphereBufferGeometry=zb;l.RingGeometry=ad;l.RingBufferGeometry=ec;l.PlaneGeometry=Cc;l.PlaneBufferGeometry=sb;l.LatheGeometry=bd;l.LatheBufferGeometry=fc;l.ShapeGeometry=Ab;l.ShapeBufferGeometry=Bb;l.ExtrudeGeometry=yb;l.ExtrudeBufferGeometry=Va;l.EdgesGeometry=gc;l.ConeGeometry=cd;l.ConeBufferGeometry=dd;l.CylinderGeometry=Cb;l.CylinderBufferGeometry=bb;l.CircleGeometry=ed;l.CircleBufferGeometry=hc;l.BoxGeometry=Ob;l.CubeGeometry=Ob;l.BoxBufferGeometry=
-rb;l.ShadowMaterial=Db;l.SpriteMaterial=jb;l.RawShaderMaterial=ic;l.ShaderMaterial=Ca;l.PointsMaterial=Ia;l.MeshPhysicalMaterial=Eb;l.MeshStandardMaterial=Wa;l.MeshPhongMaterial=Ja;l.MeshToonMaterial=Fb;l.MeshNormalMaterial=Gb;l.MeshLambertMaterial=Hb;l.MeshDepthMaterial=gb;l.MeshDistanceMaterial=hb;l.MeshBasicMaterial=ya;l.MeshMatcapMaterial=Ib;l.LineDashedMaterial=Jb;l.LineBasicMaterial=R;l.Material=M;l.Float64BufferAttribute=Ac;l.Float32BufferAttribute=F;l.Uint32BufferAttribute=qb;l.Int32BufferAttribute=
+rb;l.ShadowMaterial=Db;l.SpriteMaterial=jb;l.RawShaderMaterial=ic;l.ShaderMaterial=Ca;l.PointsMaterial=Ia;l.MeshPhysicalMaterial=Eb;l.MeshStandardMaterial=Wa;l.MeshPhongMaterial=Ja;l.MeshToonMaterial=Fb;l.MeshNormalMaterial=Gb;l.MeshLambertMaterial=Hb;l.MeshDepthMaterial=gb;l.MeshDistanceMaterial=hb;l.MeshBasicMaterial=ya;l.MeshMatcapMaterial=Ib;l.LineDashedMaterial=Jb;l.LineBasicMaterial=R;l.Material=M;l.Float64BufferAttribute=Ac;l.Float32BufferAttribute=E;l.Uint32BufferAttribute=qb;l.Int32BufferAttribute=
 zc;l.Uint16BufferAttribute=pb;l.Int16BufferAttribute=yc;l.Uint8ClampedBufferAttribute=xc;l.Uint8BufferAttribute=wc;l.Int8BufferAttribute=vc;l.BufferAttribute=P;l.ArcCurve=lc;l.CatmullRomCurve3=oa;l.CubicBezierCurve=La;l.CubicBezierCurve3=Xa;l.EllipseCurve=Ea;l.LineCurve=ja;l.LineCurve3=Ma;l.QuadraticBezierCurve=Na;l.QuadraticBezierCurve3=Ya;l.SplineCurve=Oa;l.REVISION="103dev";l.MOUSE={LEFT:0,MIDDLE:1,RIGHT:2};l.CullFaceNone=0;l.CullFaceBack=1;l.CullFaceFront=2;l.CullFaceFrontBack=3;l.FrontFaceDirectionCW=
 0;l.FrontFaceDirectionCCW=1;l.BasicShadowMap=0;l.PCFShadowMap=1;l.PCFSoftShadowMap=2;l.FrontSide=0;l.BackSide=1;l.DoubleSide=2;l.FlatShading=1;l.SmoothShading=2;l.NoColors=0;l.FaceColors=1;l.VertexColors=2;l.NoBlending=0;l.NormalBlending=1;l.AdditiveBlending=2;l.SubtractiveBlending=3;l.MultiplyBlending=4;l.CustomBlending=5;l.AddEquation=100;l.SubtractEquation=101;l.ReverseSubtractEquation=102;l.MinEquation=103;l.MaxEquation=104;l.ZeroFactor=200;l.OneFactor=201;l.SrcColorFactor=202;l.OneMinusSrcColorFactor=
 203;l.SrcAlphaFactor=204;l.OneMinusSrcAlphaFactor=205;l.DstAlphaFactor=206;l.OneMinusDstAlphaFactor=207;l.DstColorFactor=208;l.OneMinusDstColorFactor=209;l.SrcAlphaSaturateFactor=210;l.NeverDepth=0;l.AlwaysDepth=1;l.LessDepth=2;l.LessEqualDepth=3;l.EqualDepth=4;l.GreaterEqualDepth=5;l.GreaterDepth=6;l.NotEqualDepth=7;l.MultiplyOperation=0;l.MixOperation=1;l.AddOperation=2;l.NoToneMapping=0;l.LinearToneMapping=1;l.ReinhardToneMapping=2;l.Uncharted2ToneMapping=3;l.CineonToneMapping=4;l.ACESFilmicToneMapping=
@@ -966,7 +966,7 @@ a.isMultiMaterial=!0;a.materials=a;a.clone=function(){return a.slice()};return a
 return new Ia(a)};l.ParticleBasicMaterial=function(a){console.warn("THREE.ParticleBasicMaterial has been renamed to THREE.PointsMaterial.");return new Ia(a)};l.ParticleSystemMaterial=function(a){console.warn("THREE.ParticleSystemMaterial has been renamed to THREE.PointsMaterial.");return new Ia(a)};l.Vertex=function(a,b,c){console.warn("THREE.Vertex has been removed. Use THREE.Vector3 instead.");return new n(a,b,c)};l.DynamicBufferAttribute=function(a,b){console.warn("THREE.DynamicBufferAttribute has been removed. Use new THREE.BufferAttribute().setDynamic( true ) instead.");
 return(new P(a,b)).setDynamic(!0)};l.Int8Attribute=function(a,b){console.warn("THREE.Int8Attribute has been removed. Use new THREE.Int8BufferAttribute() instead.");return new vc(a,b)};l.Uint8Attribute=function(a,b){console.warn("THREE.Uint8Attribute has been removed. Use new THREE.Uint8BufferAttribute() instead.");return new wc(a,b)};l.Uint8ClampedAttribute=function(a,b){console.warn("THREE.Uint8ClampedAttribute has been removed. Use new THREE.Uint8ClampedBufferAttribute() instead.");return new xc(a,
 b)};l.Int16Attribute=function(a,b){console.warn("THREE.Int16Attribute has been removed. Use new THREE.Int16BufferAttribute() instead.");return new yc(a,b)};l.Uint16Attribute=function(a,b){console.warn("THREE.Uint16Attribute has been removed. Use new THREE.Uint16BufferAttribute() instead.");return new pb(a,b)};l.Int32Attribute=function(a,b){console.warn("THREE.Int32Attribute has been removed. Use new THREE.Int32BufferAttribute() instead.");return new zc(a,b)};l.Uint32Attribute=function(a,b){console.warn("THREE.Uint32Attribute has been removed. Use new THREE.Uint32BufferAttribute() instead.");
-return new qb(a,b)};l.Float32Attribute=function(a,b){console.warn("THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.");return new F(a,b)};l.Float64Attribute=function(a,b){console.warn("THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.");return new Ac(a,b)};l.ClosedSplineCurve3=Qf;l.SplineCurve3=Rf;l.Spline=Le;l.AxisHelper=function(a){console.warn("THREE.AxisHelper has been renamed to THREE.AxesHelper.");return new ud(a)};
+return new qb(a,b)};l.Float32Attribute=function(a,b){console.warn("THREE.Float32Attribute has been removed. Use new THREE.Float32BufferAttribute() instead.");return new E(a,b)};l.Float64Attribute=function(a,b){console.warn("THREE.Float64Attribute has been removed. Use new THREE.Float64BufferAttribute() instead.");return new Ac(a,b)};l.ClosedSplineCurve3=Qf;l.SplineCurve3=Rf;l.Spline=Le;l.AxisHelper=function(a){console.warn("THREE.AxisHelper has been renamed to THREE.AxesHelper.");return new ud(a)};
 l.BoundingBoxHelper=function(a,b){console.warn("THREE.BoundingBoxHelper has been deprecated. Creating a THREE.BoxHelper instead.");return new db(a,b)};l.EdgesHelper=function(a,b){console.warn("THREE.EdgesHelper has been removed. Use THREE.EdgesGeometry instead.");return new W(new gc(a.geometry),new R({color:void 0!==b?b:16777215}))};l.WireframeHelper=function(a,b){console.warn("THREE.WireframeHelper has been removed. Use THREE.WireframeGeometry instead.");return new W(new Xb(a.geometry),new R({color:void 0!==
 b?b:16777215}))};l.XHRLoader=function(a){console.warn("THREE.XHRLoader has been renamed to THREE.FileLoader.");return new Ka(a)};l.BinaryTextureLoader=function(a){console.warn("THREE.BinaryTextureLoader has been renamed to THREE.DataTextureLoader.");return new oe(a)};l.GeometryUtils={merge:function(a,b,c){console.warn("THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.");if(b.isMesh){b.matrixAutoUpdate&&b.updateMatrix();
 var d=b.matrix;b=b.geometry}a.merge(b,d,c)},center:function(a){console.warn("THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.");return a.center()}};l.Projector=function(){console.error("THREE.Projector has been moved to /examples/js/renderers/Projector.js.");this.projectVector=function(a,b){console.warn("THREE.Projector: .projectVector() is now vector.project().");a.project(b)};this.unprojectVector=function(a,b){console.warn("THREE.Projector: .unprojectVector() is now vector.unproject().");

+ 3 - 3
build/three.module.js

@@ -20209,7 +20209,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
 
-				return useOffscreenCanvas ? canvas.transferToImageBitmap() : canvas;
+				return canvas;
 
 			} else {
 
@@ -34662,7 +34662,7 @@ Object.assign( AnimationLoader.prototype, {
 
 	},
 
-	parse: function ( json, onLoad ) {
+	parse: function ( json ) {
 
 		var animations = [];
 
@@ -34674,7 +34674,7 @@ Object.assign( AnimationLoader.prototype, {
 
 		}
 
-		onLoad( animations );
+		return animations;
 
 	},
 

+ 4 - 5
docs/api/en/loaders/AnimationLoader.html

@@ -65,19 +65,18 @@
 		<p>
 		[page:String url] — the path or URL to the file. This can also be a
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
-		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:Animation animation].<br />
+		[page:Function onLoad] — Will be called when load completes. The argument will be the loaded [page:AnimationClip animation clips].<br />
 		[page:Function onProgress] — Will be called while load progresses. The argument will be the XMLHttpRequest instance, which contains .[page:Integer total] and .[page:Integer loaded] bytes.<br />
 		[page:Function onError] — Will be called if load errors.<br /><br />
 
 		Begin loading from url and pass the loaded animation to onLoad.
 		</p>
 
-		<h3>[method:null parse]( [param:JSON json], [param:Function onLoad] )</h3>
+		<h3>[method:Array parse]( [param:JSON json] )</h3>
 		<p>
-		[page:JSON json] — required<br />
-		[page:Function onLoad] — Will be called when parsing completes. <br /><br />
+		[page:JSON json] — required<br /><br />
 
-		Parse the JSON object and pass the result to onLoad. Individual clips in the object will
+		Parse the JSON object and return an array of animation clips. Individual clips in the object will
 		be parsed with [page:AnimationClip.parse].
 		</p>
 

+ 10 - 0
docs/api/en/loaders/ImageBitmapLoader.html

@@ -16,6 +16,13 @@
 			Unlike [page:FileLoader], [name] does not avoid multiple concurrent requests to the same URL.
 		</p>
 
+		<p>
+			Note that [page:Texture.flipY] and [page:Texture.premultiplyAlpha] with [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] are ignored.
+			[link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] needs these configuration on bitmap creation
+			unlike regular images need them on uploading to GPU. You need to set the equivalent options via [page:ImageBitmapLoader.setOptions]
+			instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.
+		</p>
+
 		<h2>Example</h2>
 
 		<p>
@@ -26,6 +33,9 @@
 		// instantiate a loader
 		var loader = new THREE.ImageBitmapLoader();
 
+		// set options if needed
+		loader.setOptions( { imageOrientation: 'flipY' } );
+
 		// load a image resource
 		loader.load(
 			// resource URL

+ 1 - 1
docs/api/en/loaders/ImageLoader.html

@@ -12,7 +12,7 @@
 
 		<p class="desc">
 			A loader for loading an [page:Image].
-			This uses the [page:FileLoader] internally for loading files, and is used internally by the
+			This is used internally by the
 			[page:CubeTextureLoader], [page:ObjectLoader] and [page:TextureLoader].
 		</p>
 

+ 4 - 7
docs/api/zh/loaders/AnimationLoader.html

@@ -65,20 +65,17 @@
 		<p>
 		[page:String url] — 文件的URL或者路径,也可以为
 			[link:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs Data URI].<br />
-		[page:Function onLoad] — 加载完成时将调用。回调参数为将要加载的[page:Animation animation].<br />
+		[page:Function onLoad] — 加载完成时将调用。回调参数为将要加载的[page:AnimationClip animation clips].<br />
 		[page:Function onProgress] —  将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含[page:Integer total]和[page:Integer loaded]字节。<br />
 		[page:Function onError] — 在加载错误时被调用。<br /><br />
 
             从URL中进行加载并将动画传递给onLoad。
 		</p>
 
-		<h3>[method:null parse]( [param:JSON json], [param:Function onLoad] )</h3>
+		<h3>[method:Array parse]( [param:JSON json] )</h3>
 		<p>
-		[page:JSON json] — 请求<br />
-		[page:Function onLoad] — 当解析完成时,将被调用 <br /><br />
-
-            解析JSON对象并将结果传递给onLoad。对象中的单个片段将
-            用[page [page:AnimationClip.parse]进行解析。
+		[page:JSON json] — 请求 <br /><br />
+			TODO
 		</p>
 
 		<h2>源</h2>

+ 10 - 0
docs/api/zh/loaders/ImageBitmapLoader.html

@@ -16,6 +16,13 @@
 			不像[page:FileLoader], [name]无需避免对同一的URL进行多次请求。
 		</p>
 
+		<p>
+			Note that [page:Texture.flipY] and [page:Texture.premultiplyAlpha] with [link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] are ignored.
+			[link:https://developer.mozilla.org/de/docs/Web/API/ImageBitmap ImageBitmap] needs these configuration on bitmap creation
+			unlike regular images need them on uploading to GPU. You need to set the equivalent options via [page:ImageBitmapLoader.setOptions]
+			instead. Refer to [link:https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.10 WebGL specification] for the detail.
+		</p>
+
 		<h2>例子</h2>
 
 		<p>
@@ -26,6 +33,9 @@
 		// 初始化一个加载器
 		var loader = new THREE.ImageBitmapLoader();
 
+		// set options if needed
+		loader.setOptions( { imageOrientation: 'flipY' } );
+
 		// 加载一个图片资源
 		loader.load(
 			// 资源的URL

+ 3 - 0
docs/examples/loaders/GLTFLoader.html

@@ -58,6 +58,9 @@
 		// Optional: Provide a DRACOLoader instance to decode compressed mesh data
 		THREE.DRACOLoader.setDecoderPath( '/examples/js/libs/draco' );
 		loader.setDRACOLoader( new THREE.DRACOLoader() );
+			
+		// Optional: Pre-fetch Draco WASM/JS module, to save time while parsing.
+		THREE.DRACOLoader.getDecoderModule();
 
 		// Load a glTF resource
 		loader.load(

+ 48 - 0
editor/css/dark.css

@@ -250,3 +250,51 @@ select {
 	.Outliner .option.active {
 		background-color: rgba(21,60,94,1);
 	}
+
+/* */
+
+@media all and ( max-width: 600px ) {
+
+	#menubar .menu .options {
+		max-height: calc(100% - 372px);
+	}
+
+	#menubar .menu.right {
+		display: none;
+	}
+
+	#viewport {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#script {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#player {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#sidebar {
+		left: 0;
+		width: 100%;
+		top: calc(100% - 320px);
+		bottom: 0;
+	}
+
+	#toolbar {
+		left: calc(50% - 140px);
+		width: 280px;
+		top: 52px;
+	}
+
+}

+ 48 - 0
editor/css/light.css

@@ -243,3 +243,51 @@ select {
 	.Outliner .option.active {
 		background-color: rgba(0,0,0,0.04);
 	}
+
+/* */
+
+@media all and ( max-width: 600px ) {
+
+	#menubar .menu .options {
+		max-height: calc(100% - 372px);
+	}
+
+	#menubar .menu.right {
+		display: none;
+	}
+
+	#viewport {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#script {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#player {
+		left: 0;
+		right: 0;
+		top: 32px;
+		height: calc(100% - 352px);
+	}
+
+	#sidebar {
+		left: 0;
+		width: 100%;
+		top: calc(100% - 320px);
+		bottom: 0;
+	}
+
+	#toolbar {
+		left: calc(50% - 140px);
+		width: 280px;
+		top: 52px;
+	}
+
+}

BIN
editor/images/icon.png


BIN
editor/images/icon.xcf


+ 20 - 5
editor/index.html

@@ -6,10 +6,11 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<!-- Origin Trial Token, feature = WebXR Device API (For Chrome M69+), origin = https://threejs.org, expires = 2019-03-06 -->
 		<meta http-equiv="origin-trial" data-feature="WebXR Device API (For Chrome M69+)" data-expires="2019-03-06" content="AvDjbxYpoTgOL1PS0JEra7KFCehfTlKnXpU/ORSwNdCQ35cX70cTUkXOnQ26A5XJi3eXHSKpBPchdt5lbcxDuAIAAABTeyJvcmlnaW4iOiJodHRwczovL3RocmVlanMub3JnOjQ0MyIsImZlYXR1cmUiOiJXZWJYUkRldmljZU02OSIsImV4cGlyeSI6MTU1MTgzMDM5OX0=">
+		<link rel="manifest" href="manifest.json">
 	</head>
 	<body ontouchstart="">
-		<link href="css/main.css" rel="stylesheet" />
-		<link id="theme" href="css/light.css" rel="stylesheet" />
+		<link rel="stylesheet" href="css/main.css">
+		<link rel="stylesheet" id="theme" href="css/light.css">
 
 		<script src="../build/three.js"></script>
 		<script src="../examples/js/libs/system.min.js"></script>
@@ -86,6 +87,9 @@
 		<script src="js/libs/ui.js"></script>
 		<script src="js/libs/ui.three.js"></script>
 
+		<script src="js/libs/html2canvas.js"></script>
+		<script src="js/libs/three.html.js"></script>
+
 		<script src="js/libs/app.js"></script>
 		<script src="js/Player.js"></script>
 		<script src="js/Script.js"></script>
@@ -162,9 +166,6 @@
 		<script src="js/commands/SetMaterialMapCommand.js"></script>
 		<script src="js/commands/SetSceneCommand.js"></script>
 
-		<script src="js/libs/html2canvas.js"></script>
-		<script src="js/libs/three.html.js"></script>
-
 		<script>
 
 			window.URL = window.URL || window.webkitURL;
@@ -329,6 +330,20 @@
 
 			}
 
+			// ServiceWorker
+
+			if ( 'serviceWorker' in navigator ) {
+
+				try {
+
+					navigator.serviceWorker.register( 'sw.js' );
+
+				} catch ( error ) {
+
+				}
+
+			}
+
 			/*
 			window.addEventListener( 'message', function ( event ) {
 

+ 0 - 55
editor/main.js

@@ -1,55 +0,0 @@
-const electron = require( 'electron' );
-const app = electron.app;
-const BrowserWindow = electron.BrowserWindow;
-
-const path = require( 'path' );
-const url = require( 'url' );
-
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow;
-
-function createWindow() {
-
-	mainWindow = new BrowserWindow( { webPreferences: {
-		nodeIntegration: false
-	} } );
-
-	mainWindow.maximize();
-	mainWindow.setMenu( null );
-
-	mainWindow.loadURL( url.format( {
-		pathname: path.join( __dirname, 'index.html' ),
-		protocol: 'file:',
-		slashes: true
-	} ) );
-
-	mainWindow.on( 'closed', function () {
-
-		mainWindow = null;
-
-	} );
-
-}
-
-app.on( 'ready', createWindow );
-
-app.on( 'window-all-closed', function () {
-
-	if ( process.platform !== 'darwin' ) {
-
-		app.quit();
-
-	}
-
-} );
-
-app.on( 'activate', function () {
-
-	if ( mainWindow === null ) {
-
-		createWindow();
-
-	}
-
-} );

+ 13 - 0
editor/manifest.json

@@ -0,0 +1,13 @@
+{
+  "short_name": "Editor",
+  "name": "Three.js Editor",
+  "icons": [
+    {
+      "src": "./images/icon.png",
+      "type": "image/png",
+      "sizes": "144x144"
+    }
+  ],
+  "start_url": ".",
+  "display": "standalone"
+}

+ 197 - 0
editor/sw.js

@@ -0,0 +1,197 @@
+// r102.1
+
+const staticAssets = [
+	'./',
+
+	'../build/three.js',
+	'../examples/js/libs/system.min.js',
+
+	'../examples/js/controls/EditorControls.js',
+	'../examples/js/controls/TransformControls.js',
+
+	'../examples/js/libs/jszip.min.js',
+	'../examples/js/libs/inflate.min.js',
+
+	'../examples/js/loaders/AMFLoader.js',
+	'../examples/js/loaders/AWDLoader.js',
+	'../examples/js/loaders/BabylonLoader.js',
+	'../examples/js/loaders/ColladaLoader.js',
+	'../examples/js/loaders/DRACOLoader.js',
+	'../examples/js/loaders/FBXLoader.js',
+	'../examples/js/loaders/GLTFLoader.js',
+	'../examples/js/loaders/deprecated/LegacyGLTFLoader.js',
+	'../examples/js/loaders/KMZLoader.js',
+	'../examples/js/loaders/MD2Loader.js',
+	'../examples/js/loaders/OBJLoader.js',
+	'../examples/js/loaders/MTLLoader.js',
+	'../examples/js/loaders/PlayCanvasLoader.js',
+	'../examples/js/loaders/PLYLoader.js',
+	'../examples/js/loaders/STLLoader.js',
+	'../examples/js/loaders/SVGLoader.js',
+	'../examples/js/loaders/TGALoader.js',
+	'../examples/js/loaders/TDSLoader.js',
+	'../examples/js/loaders/VRMLLoader.js',
+	'../examples/js/loaders/VTKLoader.js',
+	'../examples/js/loaders/ctm/lzma.js',
+	'../examples/js/loaders/ctm/ctm.js',
+	'../examples/js/loaders/ctm/CTMLoader.js',
+
+	'../examples/js/exporters/ColladaExporter.js',
+	'../examples/js/exporters/GLTFExporter.js',
+	'../examples/js/exporters/OBJExporter.js',
+	'../examples/js/exporters/STLExporter.js',
+
+	'../examples/js/renderers/Projector.js',
+	'../examples/js/renderers/RaytracingRenderer.js',
+	'../examples/js/renderers/SoftwareRenderer.js',
+	'../examples/js/renderers/SVGRenderer.js',
+
+	'./js/libs/codemirror/codemirror.css',
+	'./js/libs/codemirror/theme/monokai.css',
+
+	'./js/libs/codemirror/codemirror.js',
+	'./js/libs/codemirror/mode/javascript.js',
+	'./js/libs/codemirror/mode/glsl.js',
+
+	'./js/libs/esprima.js',
+	'./js/libs/jsonlint.js',
+	'./js/libs/glslprep.min.js',
+
+	'./js/libs/codemirror/addon/dialog.css',
+	'./js/libs/codemirror/addon/show-hint.css',
+	'./js/libs/codemirror/addon/tern.css',
+
+	'./js/libs/codemirror/addon/dialog.js',
+	'./js/libs/codemirror/addon/show-hint.js',
+	'./js/libs/codemirror/addon/tern.js',
+	'./js/libs/acorn/acorn.js',
+	'./js/libs/acorn/acorn_loose.js',
+	'./js/libs/acorn/walk.js',
+	'./js/libs/ternjs/polyfill.js',
+	'./js/libs/ternjs/signal.js',
+	'./js/libs/ternjs/tern.js',
+	'./js/libs/ternjs/def.js',
+	'./js/libs/ternjs/comment.js',
+	'./js/libs/ternjs/infer.js',
+	'./js/libs/ternjs/doc_comment.js',
+	'./js/libs/tern-threejs/threejs.js',
+
+	'./js/libs/signals.min.js',
+	'./js/libs/ui.js',
+	'./js/libs/ui.three.js',
+
+	'./js/libs/html2canvas.js',
+	'./js/libs/three.html.js',
+
+	'./js/libs/app.js',
+	'./js/Player.js',
+	'./js/Script.js',
+
+	'../examples/js/vr/WebVR.js',
+
+	//
+
+	'./css/main.css',
+	'./css/dark.css',
+	'./css/light.css',
+
+	'./js/Storage.js',
+
+	'./js/Editor.js',
+	'./js/Config.js',
+	'./js/History.js',
+	'./js/Loader.js',
+	'./js/Menubar.js',
+	'./js/Menubar.File.js',
+	'./js/Menubar.Edit.js',
+	'./js/Menubar.Add.js',
+	'./js/Menubar.Play.js',
+	// './js/Menubar.View.js',
+	'./js/Menubar.Examples.js',
+	'./js/Menubar.Help.js',
+	'./js/Menubar.Status.js',
+	'./js/Sidebar.js',
+	'./js/Sidebar.Scene.js',
+	'./js/Sidebar.Project.js',
+	'./js/Sidebar.Settings.js',
+	'./js/Sidebar.Settings.Shortcuts.js',
+	'./js/Sidebar.Settings.Viewport.js',
+	'./js/Sidebar.Properties.js',
+	'./js/Sidebar.Object.js',
+	'./js/Sidebar.Geometry.js',
+	'./js/Sidebar.Geometry.Geometry.js',
+	'./js/Sidebar.Geometry.BufferGeometry.js',
+	'./js/Sidebar.Geometry.Modifiers.js',
+	'./js/Sidebar.Geometry.BoxGeometry.js',
+	'./js/Sidebar.Geometry.CircleGeometry.js',
+	'./js/Sidebar.Geometry.CylinderGeometry.js',
+	'./js/Sidebar.Geometry.IcosahedronGeometry.js',
+	'./js/Sidebar.Geometry.PlaneGeometry.js',
+	'./js/Sidebar.Geometry.SphereGeometry.js',
+	'./js/Sidebar.Geometry.TorusGeometry.js',
+	'./js/Sidebar.Geometry.TorusKnotGeometry.js',
+	'./js/Sidebar.Geometry.TubeGeometry.js',
+	'../examples/js/geometries/TeapotBufferGeometry.js',
+	'./js/Sidebar.Geometry.TeapotBufferGeometry.js',
+	'./js/Sidebar.Geometry.LatheGeometry.js',
+	'./js/Sidebar.Material.js',
+	'./js/Sidebar.Animation.js',
+	'./js/Sidebar.Script.js',
+	'./js/Sidebar.History.js',
+	'./js/Strings.js',
+	'./js/Toolbar.js',
+	'./js/Viewport.js',
+	'./js/Viewport.Info.js',
+
+	'./js/Command.js',
+	'./js/commands/AddObjectCommand.js',
+	'./js/commands/RemoveObjectCommand.js',
+	'./js/commands/MoveObjectCommand.js',
+	'./js/commands/SetPositionCommand.js',
+	'./js/commands/SetRotationCommand.js',
+	'./js/commands/SetScaleCommand.js',
+	'./js/commands/SetValueCommand.js',
+	'./js/commands/SetUuidCommand.js',
+	'./js/commands/SetColorCommand.js',
+	'./js/commands/SetGeometryCommand.js',
+	'./js/commands/SetGeometryValueCommand.js',
+	'./js/commands/MultiCmdsCommand.js',
+	'./js/commands/AddScriptCommand.js',
+	'./js/commands/RemoveScriptCommand.js',
+	'./js/commands/SetScriptValueCommand.js',
+	'./js/commands/SetMaterialCommand.js',
+	'./js/commands/SetMaterialValueCommand.js',
+	'./js/commands/SetMaterialColorCommand.js',
+	'./js/commands/SetMaterialMapCommand.js',
+	'./js/commands/SetSceneCommand.js',
+
+	//
+
+	'./examples/arkanoid.app.json',
+	'./examples/camera.app.json',
+	'./examples/particles.app.json',
+	'./examples/pong.app.json',
+	'./examples/shaders.app.json'
+
+];
+
+self.addEventListener( 'install', async function ( event ) {
+
+	const cache = await caches.open( 'threejs-editor' );
+	cache.addAll( staticAssets );
+
+} );
+
+self.addEventListener( 'fetch', async function ( event ) {
+
+	const request = event.request;
+	event.respondWith( cacheFirst( request ) );
+
+} );
+
+async function cacheFirst( request ) {
+
+	const cachedResponse = await caches.match( request );
+	return cachedResponse || fetch( request );
+
+}

+ 73 - 0
examples/js/MarchingCubes.js

@@ -772,6 +772,79 @@ THREE.MarchingCubes = function ( resolution, material, enableUvs, enableColors )
 	// Updates
 	/////////////////////////////////////
 
+	this.setCell = function ( x, y, z, value ) {
+
+		var index = this.size2 * z + this.size * y + x;
+		this.field[ index ] = value;
+
+	};
+
+	this.getCell = function ( x, y, z ) {
+
+		var index = this.size2 * z + this.size * y + x;
+		return this.field[ index ];
+
+	};
+
+	this.blur = function ( intensity ) {
+
+		if ( intensity === undefined ) {
+
+			intensity = 1;
+
+		}
+
+		var field = this.field;
+		var fieldCopy = field.slice();
+		var size = this.size;
+		var size2 = this.size2;
+		for ( var x = 0; x < size; x ++ ) {
+
+			for ( var y = 0; y < size; y ++ ) {
+
+				for ( var z = 0; z < size; z ++ ) {
+
+					var index = size2 * z + size * y + x;
+					var val = fieldCopy[ index ];
+					var count = 1;
+
+					for ( var x2 = - 1; x2 <= 1; x2 += 2 ) {
+
+						var x3 = x2 + x;
+						if ( x3 < 0 || x3 >= size ) continue;
+
+						for ( var y2 = - 1; y2 <= 1; y2 += 2 ) {
+
+							var y3 = y2 + y;
+							if ( y3 < 0 || y3 >= size ) continue;
+
+							for ( var z2 = - 1; z2 <= 1; z2 += 2 ) {
+
+								var z3 = z2 + z;
+								if ( z3 < 0 || z3 >= size ) continue;
+
+								var index2 = size2 * z3 + size * y3 + x3;
+								var val2 = fieldCopy[ index2 ];
+
+								count ++;
+								val += intensity * ( val2 - val ) / count;
+
+							}
+
+						}
+
+					}
+
+					field[ index ] = val;
+
+				}
+
+			}
+
+		}
+
+	};
+
 	this.reset = function () {
 
 		var i;

+ 0 - 1
examples/js/loaders/GLTFLoader.js

@@ -496,7 +496,6 @@ THREE.GLTFLoader = ( function () {
 		this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
 		this.json = json;
 		this.dracoLoader = dracoLoader;
-		THREE.DRACOLoader.getDecoderModule();
 
 	}
 

+ 1 - 1
examples/js/objects/Fire.js

@@ -431,7 +431,7 @@ THREE.Fire = function ( geometry, options ) {
 
 	};
 
-	this.onBeforeRender = function ( renderer, scene, camera ) {
+	this.onBeforeRender = function ( renderer ) {
 
 		var delta = this.clock.getDelta();
 		if ( delta > 0.1 ) {

+ 32 - 34
examples/js/objects/LightningStorm.js

@@ -3,53 +3,53 @@
  *
  * @fileoverview Lightning strike object generator
  *
- * 
+ *
  * Usage
- * 
+ *
  * var myStorm = new THREE.LightningStorm( paramsObject );
  * myStorm.position.set( ... );
  * scene.add( myStorm );
  * ...
  * myStorm.update( currentTime );
- * 
+ *
  * The "currentTime" can only go forwards or be stopped.
- * 
- * 
+ *
+ *
  * LightningStorm parameters:
  *
  * @param {double} size Size of the storm. If no 'onRayPosition' parameter is defined, it means the side of the rectangle the storm covers.
  *
  * @param {double} minHeight Minimum height a ray can start at. If no 'onRayPosition' parameter is defined, it means the height above plane y = 0.
- * 
+ *
  * @param {double} maxHeight Maximum height a ray can start at. If no 'onRayPosition' parameter is defined, it means the height above plane y = 0.
- * 
+ *
  * @param {double} maxSlope The maximum inclination slope of a ray. If no 'onRayPosition' parameter is defined, it means the slope relative to plane y = 0.
- * 
+ *
  * @param {integer} maxLightnings Greater than 0. The maximum number of simultaneous rays.
- * 
+ *
  * @param {double} lightningMinPeriod minimum time between two consecutive rays.
- * 
+ *
  * @param {double} lightningMaxPeriod maximum time between two consecutive rays.
- * 
+ *
  * @param {double} lightningMinDuration The minimum time a ray can last.
- * 
+ *
  * @param {double} lightningMaxDuration The maximum time a ray can last.
- * 
+ *
  * @param {Object} lightningParameters The parameters for created rays. See THREE.LightningStrike (geometry)
- * 
+ *
  * @param {Material} lightningMaterial The THREE.Material used for the created rays.
- * 
+ *
  * @param {function} onRayPosition Optional callback with two Vector3 parameters (source, dest). You can set here the start and end points for each created ray, using the standard size, minHeight, etc parameters and other values in your algorithm.
- * 
+ *
  * @param {function} onLightningDown This optional callback is called with one parameter (lightningStrike) when a ray ends propagating, so it has hit the ground.
- * 
+ *
  *
 */
 
 THREE.LightningStorm = function ( stormParams ) {
 
 	THREE.Object3D.call( this );
-	
+
 	// Parameters
 
 	stormParams = stormParams || {};
@@ -71,21 +71,20 @@ THREE.LightningStorm = function ( stormParams ) {
 	this.lightningParameters = THREE.LightningStrike.copyParameters( stormParams.lightningParameters, stormParams.lightningParameters );
 
 	this.lightningParameters.isEternal = false;
-	
+
 	this.lightningMaterial = stormParams.lightningMaterial !== undefined ? stormParams.lightningMaterial : new THREE.MeshBasicMaterial( { color: 0xB0FFFF } );
 
 	if ( stormParams.onRayPosition !== undefined ) {
 
 		this.onRayPosition = stormParams.onRayPosition;
 
-	}
-	else {
+	} else {
 
-		this.onRayPosition = function( source, dest ) {
+		this.onRayPosition = function ( source, dest ) {
 
 			dest.set( ( Math.random() - 0.5 ) * stormParams.size, 0, ( Math.random() - 0.5 ) * stormParams.size );
-			
-			var height = THREE.Math.lerp( stormParams.minHeight, stormParams.maxHeight, Math.random() );;
+
+			var height = THREE.Math.lerp( stormParams.minHeight, stormParams.maxHeight, Math.random() );
 
 			source.set( stormParams.maxSlope * ( 2 * Math.random() - 1 ), 1, stormParams.maxSlope * ( 2 * Math.random() - 1 ) ).multiplyScalar( height ).add( dest );
 
@@ -102,7 +101,7 @@ THREE.LightningStorm = function ( stormParams ) {
 	this.lightningsMeshes = [];
 	this.deadLightningsMeshes = [];
 
-	for ( var i = 0; i < this.stormParams.maxLightnings; i++ ) {
+	for ( var i = 0; i < this.stormParams.maxLightnings; i ++ ) {
 
 		var lightning = new THREE.LightningStrike( THREE.LightningStrike.copyParameters( {}, this.lightningParameters ) );
 		var mesh = new THREE.Mesh( lightning, this.lightningMaterial );
@@ -155,9 +154,9 @@ THREE.LightningStorm.prototype.update = function ( time ) {
 
 	}
 
-	var i = 0; il = this.lightningsMeshes.length;
+	var i = 0, il = this.lightningsMeshes.length;
 
-	while ( i < il ){
+	while ( i < il ) {
 
 		var mesh = this.lightningsMeshes[ i ];
 
@@ -181,18 +180,17 @@ THREE.LightningStorm.prototype.update = function ( time ) {
 
 			// Lightning is to be destroyed
 
-			this.lightningsMeshes.splice( this.lightningsMeshes.indexOf( mesh ), 1 ); 
+			this.lightningsMeshes.splice( this.lightningsMeshes.indexOf( mesh ), 1 );
 
 			this.deadLightningsMeshes.push( mesh );
 
 			this.remove( mesh );
 
-			il--;
+			il --;
 
-		}
-		else {
+		} else {
 
-			i++;
+			i ++;
 
 		}
 
@@ -207,8 +205,8 @@ THREE.LightningStorm.prototype.getNextLightningTime = function ( currentTime ) {
 };
 
 THREE.LightningStorm.prototype.copy = function ( source ) {
-	
-	Object3D.prototype.copy.call( this, source );
+
+	THREE.Object3D.prototype.copy.call( this, source );
 
 	this.stormParams.size = source.stormParams.size;
 	this.stormParams.minHeight = source.stormParams.minHeight;

+ 1 - 2
examples/js/objects/Sky.js

@@ -133,8 +133,7 @@ THREE.Sky.SkyShader = {
 		'const float pi = 3.141592653589793238462643383279502884197169;',
 
 		'const float n = 1.0003;', // refractive index of air
-		'const float N = 2.545E25;', // number of molecules per unit volume for air at
-									// 288.15K and 1013mb (sea level -45 celsius)
+		'const float N = 2.545E25;', // number of molecules per unit volume for air at 288.15K and 1013mb (sea level -45 celsius)
 
 		// optical length at zenith for molecules
 		'const float rayleighZenithLength = 8.4E3;',

+ 2 - 1
examples/js/renderers/CSS2DRenderer.js

@@ -9,7 +9,7 @@ THREE.CSS2DObject = function ( element ) {
 	this.element = element;
 	this.element.style.position = 'absolute';
 
-	this.addEventListener( 'removed', function ( event ) {
+	this.addEventListener( 'removed', function () {
 
 		if ( this.element.parentNode !== null ) {
 
@@ -82,6 +82,7 @@ THREE.CSS2DRenderer = function () {
 			element.style.MozTransform = style;
 			element.style.oTransform = style;
 			element.style.transform = style;
+			element.style.display = ( vector.z < - 1 || vector.z > 1 ) ? 'none' : '';
 
 			var objectData = {
 				distanceToCameraSquared: getDistanceToSquared( camera, object )

+ 3 - 3
examples/js/renderers/Projector.js

@@ -322,7 +322,7 @@ THREE.Projector = function () {
 
 				_face.material = material;
 
-				if ( material.vertexColors === THREE.FaceColors ||  material.vertexColors === THREE.VertexColors ) {
+				if ( material.vertexColors === THREE.FaceColors || material.vertexColors === THREE.VertexColors ) {
 
 					_face.color.fromArray( colors, a * 3 );
 
@@ -1038,8 +1038,8 @@ THREE.Projector = function () {
 
 		var alpha1 = 0, alpha2 = 1,
 
-		// Calculate the boundary coordinate of each vertex for the near and far clip planes,
-		// Z = -1 and Z = +1, respectively.
+			// Calculate the boundary coordinate of each vertex for the near and far clip planes,
+			// Z = -1 and Z = +1, respectively.
 
 			bc1near = s1.z + s1.w,
 			bc2near = s2.z + s2.w,

+ 24 - 5
examples/jsm/controls/OrbitControls.js

@@ -546,32 +546,44 @@ var OrbitControls = function ( object, domElement ) {
 
 	function handleKeyDown( event ) {
 
-		//console.log( 'handleKeyDown' );
+		// console.log( 'handleKeyDown' );
+
+		var needsUpdate = false;
 
 		switch ( event.keyCode ) {
 
 			case scope.keys.UP:
 				pan( 0, scope.keyPanSpeed );
-				scope.update();
+				needsUpdate = true;
 				break;
 
 			case scope.keys.BOTTOM:
 				pan( 0, - scope.keyPanSpeed );
-				scope.update();
+				needsUpdate = true;
 				break;
 
 			case scope.keys.LEFT:
 				pan( scope.keyPanSpeed, 0 );
-				scope.update();
+				needsUpdate = true;
 				break;
 
 			case scope.keys.RIGHT:
 				pan( - scope.keyPanSpeed, 0 );
-				scope.update();
+				needsUpdate = true;
 				break;
 
 		}
 
+		if ( needsUpdate ) {
+
+			// prevent the browser from scrolling on cursor keys
+			event.preventDefault();
+
+			scope.update();
+
+		}
+
+
 	}
 
 	function handleTouchStartRotate( event ) {
@@ -682,8 +694,15 @@ var OrbitControls = function ( object, domElement ) {
 
 		if ( scope.enabled === false ) return;
 
+		// Prevent the browser from scrolling.
+
 		event.preventDefault();
 
+		// Manually set the focus since calling preventDefault above
+		// prevents the browser from setting it automatically.
+
+		scope.domElement.focus ? scope.domElement.focus() : window.focus();
+
 		switch ( event.button ) {
 
 			case scope.mouseButtons.LEFT:

+ 1 - 1
examples/jsm/controls/TrackballControls.js

@@ -499,7 +499,7 @@ var TrackballControls = function ( object, domElement ) {
 	function touchstart( event ) {
 
 		if ( _this.enabled === false ) return;
-
+		
 		event.preventDefault();
 
 		switch ( event.touches.length ) {

+ 2229 - 0
examples/jsm/exporters/GLTFExporter.js

@@ -0,0 +1,2229 @@
+/**
+ * @author fernandojsg / http://fernandojsg.com
+ * @author Don McCurdy / https://www.donmccurdy.com
+ * @author Takahiro / https://github.com/takahirox
+ */
+
+import {
+  NearestFilter,
+  NearestMipMapNearestFilter,
+  NearestMipMapLinearFilter,
+  LinearFilter,
+  LinearMipMapNearestFilter,
+  LinearMipMapLinearFilter,
+  ClampToEdgeWrapping,
+  RepeatWrapping,
+  MirroredRepeatWrapping,
+	Scene,
+	BufferAttribute,
+	BufferGeometry,
+	TriangleFanDrawMode,
+	TriangleStripDrawMode,
+	RGBAFormat,
+	DoubleSide,
+	PropertyBinding,
+	InterpolateDiscrete,
+	InterpolateLinear,
+	Vector3,
+} from "../../../build/three.module.js";
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+var WEBGL_CONSTANTS = {
+	POINTS: 0x0000,
+	LINES: 0x0001,
+	LINE_LOOP: 0x0002,
+	LINE_STRIP: 0x0003,
+	TRIANGLES: 0x0004,
+	TRIANGLE_STRIP: 0x0005,
+	TRIANGLE_FAN: 0x0006,
+
+	UNSIGNED_BYTE: 0x1401,
+	UNSIGNED_SHORT: 0x1403,
+	FLOAT: 0x1406,
+	UNSIGNED_INT: 0x1405,
+	ARRAY_BUFFER: 0x8892,
+	ELEMENT_ARRAY_BUFFER: 0x8893,
+
+	NEAREST: 0x2600,
+	LINEAR: 0x2601,
+	NEAREST_MIPMAP_NEAREST: 0x2700,
+	LINEAR_MIPMAP_NEAREST: 0x2701,
+	NEAREST_MIPMAP_LINEAR: 0x2702,
+	LINEAR_MIPMAP_LINEAR: 0x2703,
+
+	CLAMP_TO_EDGE: 33071,
+	MIRRORED_REPEAT: 33648,
+	REPEAT: 10497
+};
+
+var THREE_TO_WEBGL = {};
+
+THREE_TO_WEBGL[ NearestFilter ] = WEBGL_CONSTANTS.NEAREST;
+THREE_TO_WEBGL[ NearestMipMapNearestFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
+THREE_TO_WEBGL[ NearestMipMapLinearFilter ] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
+THREE_TO_WEBGL[ LinearFilter ] = WEBGL_CONSTANTS.LINEAR;
+THREE_TO_WEBGL[ LinearMipMapNearestFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
+THREE_TO_WEBGL[ LinearMipMapLinearFilter ] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
+
+THREE_TO_WEBGL[ ClampToEdgeWrapping ] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
+THREE_TO_WEBGL[ RepeatWrapping ] = WEBGL_CONSTANTS.REPEAT;
+THREE_TO_WEBGL[ MirroredRepeatWrapping ] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
+
+var PATH_PROPERTIES = {
+	scale: 'scale',
+	position: 'translation',
+	quaternion: 'rotation',
+	morphTargetInfluences: 'weights'
+};
+
+//------------------------------------------------------------------------------
+// GLTF Exporter
+//------------------------------------------------------------------------------
+var GLTFExporter = ( function () {
+
+	function GLTFExporter() {
+	}
+
+	GLTFExporter.prototype = {
+
+		constructor: GLTFExporter,
+		/**
+		 * Parse scenes and generate GLTF output
+		 * @param	 {Scene or [Scenes]} input	 Scene or Array of Scenes
+		 * @param	 {Function} onDone	Callback on completed
+		 * @param	 {Object} options options
+		 */
+		parse: function ( input, onDone, options ) {
+
+			var DEFAULT_OPTIONS = {
+				binary: false,
+				trs: false,
+				onlyVisible: true,
+				truncateDrawRange: true,
+				embedImages: true,
+				animations: [],
+				forceIndices: false,
+				forcePowerOfTwoTextures: false
+			};
+
+			options = Object.assign( {}, DEFAULT_OPTIONS, options );
+
+			if ( options.animations.length > 0 ) {
+
+				// Only TRS properties, and not matrices, may be targeted by animation.
+				options.trs = true;
+
+			}
+
+			var outputJSON = {
+
+				asset: {
+
+					version: "2.0",
+					generator: "GLTFExporter"
+
+				}
+
+			};
+
+			var byteOffset = 0;
+			var buffers = [];
+			var pending = [];
+			var nodeMap = new Map();
+			var skins = [];
+			var extensionsUsed = {};
+			var cachedData = {
+
+				meshes: new Map(),
+				attributes: new Map(),
+				attributesNormalized: new Map(),
+				materials: new Map(),
+				textures: new Map(),
+				images: new Map()
+
+			};
+
+			var cachedCanvas;
+
+			/**
+			 * Compare two arrays
+			 */
+			/**
+			 * Compare two arrays
+			 * @param	 {Array} array1 Array 1 to compare
+			 * @param	 {Array} array2 Array 2 to compare
+			 * @return {Boolean}				Returns true if both arrays are equal
+			 */
+			function equalArray( array1, array2 ) {
+
+				return ( array1.length === array2.length ) && array1.every( function ( element, index ) {
+
+					return element === array2[ index ];
+
+				} );
+
+			}
+
+			/**
+			 * Converts a string to an ArrayBuffer.
+			 * @param	 {string} text
+			 * @return {ArrayBuffer}
+			 */
+			function stringToArrayBuffer( text ) {
+
+				if ( window.TextEncoder !== undefined ) {
+
+					return new TextEncoder().encode( text ).buffer;
+
+				}
+
+				var array = new Uint8Array( new ArrayBuffer( text.length ) );
+
+				for ( var i = 0, il = text.length; i < il; i ++ ) {
+
+					var value = text.charCodeAt( i );
+
+					// Replacing multi-byte character with space(0x20).
+					array[ i ] = value > 0xFF ? 0x20 : value;
+
+				}
+
+				return array.buffer;
+
+			}
+
+			/**
+			 * Get the min and max vectors from the given attribute
+			 * @param	 {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
+			 * @param	 {Integer} start
+			 * @param	 {Integer} count
+			 * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
+			 */
+			function getMinMax( attribute, start, count ) {
+
+				var output = {
+
+					min: new Array( attribute.itemSize ).fill( Number.POSITIVE_INFINITY ),
+					max: new Array( attribute.itemSize ).fill( Number.NEGATIVE_INFINITY )
+
+				};
+
+				for ( var i = start; i < start + count; i ++ ) {
+
+					for ( var a = 0; a < attribute.itemSize; a ++ ) {
+
+						var value = attribute.array[ i * attribute.itemSize + a ];
+						output.min[ a ] = Math.min( output.min[ a ], value );
+						output.max[ a ] = Math.max( output.max[ a ], value );
+
+					}
+
+				}
+
+				return output;
+
+			}
+
+			/**
+			 * Checks if image size is POT.
+			 *
+			 * @param {Image} image The image to be checked.
+			 * @returns {Boolean} Returns true if image size is POT.
+			 *
+			 */
+			function isPowerOfTwo( image ) {
+
+				return Math.isPowerOfTwo( image.width ) && Math.isPowerOfTwo( image.height );
+
+			}
+
+			/**
+			 * Checks if normal attribute values are normalized.
+			 *
+			 * @param {BufferAttribute} normal
+			 * @returns {Boolean}
+			 *
+			 */
+			function isNormalizedNormalAttribute( normal ) {
+
+				if ( cachedData.attributesNormalized.has( normal ) ) {
+
+					return false;
+
+				}
+
+				var v = new Vector3();
+
+				for ( var i = 0, il = normal.count; i < il; i ++ ) {
+
+					// 0.0005 is from glTF-validator
+					if ( Math.abs( v.fromArray( normal.array, i * 3 ).length() - 1.0 ) > 0.0005 ) return false;
+
+				}
+
+				return true;
+
+			}
+
+			/**
+			 * Creates normalized normal buffer attribute.
+			 *
+			 * @param {BufferAttribute} normal
+			 * @returns {BufferAttribute}
+			 *
+			 */
+			function createNormalizedNormalAttribute( normal ) {
+
+				if ( cachedData.attributesNormalized.has( normal ) ) {
+
+					return cachedData.attributesNormalized.get( normal );
+
+				}
+
+				var attribute = normal.clone();
+
+				var v = new Vector3();
+
+				for ( var i = 0, il = attribute.count; i < il; i ++ ) {
+
+					v.fromArray( attribute.array, i * 3 );
+
+					if ( v.x === 0 && v.y === 0 && v.z === 0 ) {
+
+						// if values can't be normalized set (1, 0, 0)
+						v.setX( 1.0 );
+
+					} else {
+
+						v.normalize();
+
+					}
+
+					v.toArray( attribute.array, i * 3 );
+
+				}
+
+				cachedData.attributesNormalized.set( normal, attribute );
+
+				return attribute;
+
+			}
+
+			/**
+			 * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
+			 * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
+			 *
+			 * @param {Integer} bufferSize The size the original buffer.
+			 * @returns {Integer} new buffer size with required padding.
+			 *
+			 */
+			function getPaddedBufferSize( bufferSize ) {
+
+				return Math.ceil( bufferSize / 4 ) * 4;
+
+			}
+
+			/**
+			 * Returns a buffer aligned to 4-byte boundary.
+			 *
+			 * @param {ArrayBuffer} arrayBuffer Buffer to pad
+			 * @param {Integer} paddingByte (Optional)
+			 * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
+			 */
+			function getPaddedArrayBuffer( arrayBuffer, paddingByte ) {
+
+				paddingByte = paddingByte || 0;
+
+				var paddedLength = getPaddedBufferSize( arrayBuffer.byteLength );
+
+				if ( paddedLength !== arrayBuffer.byteLength ) {
+
+					var array = new Uint8Array( paddedLength );
+					array.set( new Uint8Array( arrayBuffer ) );
+
+					if ( paddingByte !== 0 ) {
+
+						for ( var i = arrayBuffer.byteLength; i < paddedLength; i ++ ) {
+
+							array[ i ] = paddingByte;
+
+						}
+
+					}
+
+					return array.buffer;
+
+				}
+
+				return arrayBuffer;
+
+			}
+
+			/**
+			 * Serializes a userData.
+			 *
+			 * @param {Object3D|Material} object
+			 * @returns {Object}
+			 */
+			function serializeUserData( object ) {
+
+				try {
+
+					return JSON.parse( JSON.stringify( object.userData ) );
+
+				} catch ( error ) {
+
+					console.warn( 'GLTFExporter: userData of \'' + object.name + '\' ' +
+												'won\'t be serialized because of JSON.stringify error - ' + error.message );
+
+					return {};
+
+				}
+
+			}
+
+			/**
+			 * Applies a texture transform, if present, to the map definition. Requires
+			 * the KHR_texture_transform extension.
+			 */
+			function applyTextureTransform( mapDef, texture ) {
+
+				var didTransform = false;
+				var transformDef = {};
+
+				if ( texture.offset.x !== 0 || texture.offset.y !== 0 ) {
+
+					transformDef.offset = texture.offset.toArray();
+					didTransform = true;
+
+				}
+
+				if ( texture.rotation !== 0 ) {
+
+					transformDef.rotation = texture.rotation;
+					didTransform = true;
+
+				}
+
+				if ( texture.repeat.x !== 1 || texture.repeat.y !== 1 ) {
+
+					transformDef.scale = texture.repeat.toArray();
+					didTransform = true;
+
+				}
+
+				if ( didTransform ) {
+
+					mapDef.extensions = mapDef.extensions || {};
+					mapDef.extensions[ 'KHR_texture_transform' ] = transformDef;
+					extensionsUsed[ 'KHR_texture_transform' ] = true;
+
+				}
+
+			}
+
+			/**
+			 * Process a buffer to append to the default one.
+			 * @param	 {ArrayBuffer} buffer
+			 * @return {Integer}
+			 */
+			function processBuffer( buffer ) {
+
+				if ( ! outputJSON.buffers ) {
+
+					outputJSON.buffers = [ { byteLength: 0 } ];
+
+				}
+
+				// All buffers are merged before export.
+				buffers.push( buffer );
+
+				return 0;
+
+			}
+
+			/**
+			 * Process and generate a BufferView
+			 * @param	 {BufferAttribute} attribute
+			 * @param	 {number} componentType
+			 * @param	 {number} start
+			 * @param	 {number} count
+			 * @param	 {number} target (Optional) Target usage of the BufferView
+			 * @return {Object}
+			 */
+			function processBufferView( attribute, componentType, start, count, target ) {
+
+				if ( ! outputJSON.bufferViews ) {
+
+					outputJSON.bufferViews = [];
+
+				}
+
+				// Create a new dataview and dump the attribute's array into it
+
+				var componentSize;
+
+				if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
+
+					componentSize = 1;
+
+				} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) {
+
+					componentSize = 2;
+
+				} else {
+
+					componentSize = 4;
+
+				}
+
+				var byteLength = getPaddedBufferSize( count * attribute.itemSize * componentSize );
+				var dataView = new DataView( new ArrayBuffer( byteLength ) );
+				var offset = 0;
+
+				for ( var i = start; i < start + count; i ++ ) {
+
+					for ( var a = 0; a < attribute.itemSize; a ++ ) {
+
+						// @TODO Fails on InterleavedBufferAttribute, and could probably be
+						// optimized for normal BufferAttribute.
+						var value = attribute.array[ i * attribute.itemSize + a ];
+
+						if ( componentType === WEBGL_CONSTANTS.FLOAT ) {
+
+							dataView.setFloat32( offset, value, true );
+
+						} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_INT ) {
+
+							dataView.setUint32( offset, value, true );
+
+						} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT ) {
+
+							dataView.setUint16( offset, value, true );
+
+						} else if ( componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE ) {
+
+							dataView.setUint8( offset, value );
+
+						}
+
+						offset += componentSize;
+
+					}
+
+				}
+
+				var gltfBufferView = {
+
+					buffer: processBuffer( dataView.buffer ),
+					byteOffset: byteOffset,
+					byteLength: byteLength
+
+				};
+
+				if ( target !== undefined ) gltfBufferView.target = target;
+
+				if ( target === WEBGL_CONSTANTS.ARRAY_BUFFER ) {
+
+					// Only define byteStride for vertex attributes.
+					gltfBufferView.byteStride = attribute.itemSize * componentSize;
+
+				}
+
+				byteOffset += byteLength;
+
+				outputJSON.bufferViews.push( gltfBufferView );
+
+				// @TODO Merge bufferViews where possible.
+				var output = {
+
+					id: outputJSON.bufferViews.length - 1,
+					byteLength: 0
+
+				};
+
+				return output;
+
+			}
+
+			/**
+			 * Process and generate a BufferView from an image Blob.
+			 * @param {Blob} blob
+			 * @return {Promise<Integer>}
+			 */
+			function processBufferViewImage( blob ) {
+
+				if ( ! outputJSON.bufferViews ) {
+
+					outputJSON.bufferViews = [];
+
+				}
+
+				return new Promise( function ( resolve ) {
+
+					var reader = new window.FileReader();
+					reader.readAsArrayBuffer( blob );
+					reader.onloadend = function () {
+
+						var buffer = getPaddedArrayBuffer( reader.result );
+
+						var bufferView = {
+							buffer: processBuffer( buffer ),
+							byteOffset: byteOffset,
+							byteLength: buffer.byteLength
+						};
+
+						byteOffset += buffer.byteLength;
+
+						outputJSON.bufferViews.push( bufferView );
+
+						resolve( outputJSON.bufferViews.length - 1 );
+
+					};
+
+				} );
+
+			}
+
+			/**
+			 * Process attribute to generate an accessor
+			 * @param	 {BufferAttribute} attribute Attribute to process
+			 * @param	 {BufferGeometry} geometry (Optional) Geometry used for truncated draw range
+			 * @param	 {Integer} start (Optional)
+			 * @param	 {Integer} count (Optional)
+			 * @return {Integer}					 Index of the processed accessor on the "accessors" array
+			 */
+			function processAccessor( attribute, geometry, start, count ) {
+
+				var types = {
+
+					1: 'SCALAR',
+					2: 'VEC2',
+					3: 'VEC3',
+					4: 'VEC4',
+					16: 'MAT4'
+
+				};
+
+				var componentType;
+
+				// Detect the component type of the attribute array (float, uint or ushort)
+				if ( attribute.array.constructor === Float32Array ) {
+
+					componentType = WEBGL_CONSTANTS.FLOAT;
+
+				} else if ( attribute.array.constructor === Uint32Array ) {
+
+					componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
+
+				} else if ( attribute.array.constructor === Uint16Array ) {
+
+					componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
+
+				} else if ( attribute.array.constructor === Uint8Array ) {
+
+					componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
+
+				} else {
+
+					throw new Error( 'GLTFExporter: Unsupported bufferAttribute component type.' );
+
+				}
+
+				if ( start === undefined ) start = 0;
+				if ( count === undefined ) count = attribute.count;
+
+				// @TODO Indexed buffer geometry with drawRange not supported yet
+				if ( options.truncateDrawRange && geometry !== undefined && geometry.index === null ) {
+
+					var end = start + count;
+					var end2 = geometry.drawRange.count === Infinity
+							? attribute.count
+							: geometry.drawRange.start + geometry.drawRange.count;
+
+					start = Math.max( start, geometry.drawRange.start );
+					count = Math.min( end, end2 ) - start;
+
+					if ( count < 0 ) count = 0;
+
+				}
+
+				// Skip creating an accessor if the attribute doesn't have data to export
+				if ( count === 0 ) {
+
+					return null;
+
+				}
+
+				var minMax = getMinMax( attribute, start, count );
+
+				var bufferViewTarget;
+
+				// If geometry isn't provided, don't infer the target usage of the bufferView. For
+				// animation samplers, target must not be set.
+				if ( geometry !== undefined ) {
+
+					bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
+
+				}
+
+				var bufferView = processBufferView( attribute, componentType, start, count, bufferViewTarget );
+
+				var gltfAccessor = {
+
+					bufferView: bufferView.id,
+					byteOffset: bufferView.byteOffset,
+					componentType: componentType,
+					count: count,
+					max: minMax.max,
+					min: minMax.min,
+					type: types[ attribute.itemSize ]
+
+				};
+
+				if ( ! outputJSON.accessors ) {
+
+					outputJSON.accessors = [];
+
+				}
+
+				outputJSON.accessors.push( gltfAccessor );
+
+				return outputJSON.accessors.length - 1;
+
+			}
+
+			/**
+			 * Process image
+			 * @param	 {Image} image to process
+			 * @param	 {Integer} format of the image (e.g. RGBFormat, RGBAFormat etc)
+			 * @param	 {Boolean} flipY before writing out the image
+			 * @return {Integer}		 Index of the processed texture in the "images" array
+			 */
+			function processImage( image, format, flipY ) {
+
+				if ( ! cachedData.images.has( image ) ) {
+
+					cachedData.images.set( image, {} );
+
+				}
+
+				var cachedImages = cachedData.images.get( image );
+				var mimeType = format === RGBAFormat ? 'image/png' : 'image/jpeg';
+				var key = mimeType + ":flipY/" + flipY.toString();
+
+				if ( cachedImages[ key ] !== undefined ) {
+
+					return cachedImages[ key ];
+
+				}
+
+				if ( ! outputJSON.images ) {
+
+					outputJSON.images = [];
+
+				}
+
+				var gltfImage = { mimeType: mimeType };
+
+				if ( options.embedImages ) {
+
+					var canvas = cachedCanvas = cachedCanvas || document.createElement( 'canvas' );
+
+					canvas.width = image.width;
+					canvas.height = image.height;
+
+					if ( options.forcePowerOfTwoTextures && ! isPowerOfTwo( image ) ) {
+
+						console.warn( 'GLTFExporter: Resized non-power-of-two image.', image );
+
+						canvas.width = Math.floorPowerOfTwo( canvas.width );
+						canvas.height = Math.floorPowerOfTwo( canvas.height );
+
+					}
+
+					var ctx = canvas.getContext( '2d' );
+
+					if ( flipY === true ) {
+
+						ctx.translate( 0, canvas.height );
+						ctx.scale( 1, - 1 );
+
+					}
+
+					ctx.drawImage( image, 0, 0, canvas.width, canvas.height );
+
+					if ( options.binary === true ) {
+
+						pending.push( new Promise( function ( resolve ) {
+
+							canvas.toBlob( function ( blob ) {
+
+								processBufferViewImage( blob ).then( function ( bufferViewIndex ) {
+
+									gltfImage.bufferView = bufferViewIndex;
+
+									resolve();
+
+								} );
+
+							}, mimeType );
+
+						} ) );
+
+					} else {
+
+						gltfImage.uri = canvas.toDataURL( mimeType );
+
+					}
+
+				} else {
+
+					gltfImage.uri = image.src;
+
+				}
+
+				outputJSON.images.push( gltfImage );
+
+				var index = outputJSON.images.length - 1;
+				cachedImages[ key ] = index;
+
+				return index;
+
+			}
+
+			/**
+			 * Process sampler
+			 * @param	 {Texture} map Texture to process
+			 * @return {Integer}		 Index of the processed texture in the "samplers" array
+			 */
+			function processSampler( map ) {
+
+				if ( ! outputJSON.samplers ) {
+
+					outputJSON.samplers = [];
+
+				}
+
+				var gltfSampler = {
+
+					magFilter: THREE_TO_WEBGL[ map.magFilter ],
+					minFilter: THREE_TO_WEBGL[ map.minFilter ],
+					wrapS: THREE_TO_WEBGL[ map.wrapS ],
+					wrapT: THREE_TO_WEBGL[ map.wrapT ]
+
+				};
+
+				outputJSON.samplers.push( gltfSampler );
+
+				return outputJSON.samplers.length - 1;
+
+			}
+
+			/**
+			 * Process texture
+			 * @param	 {Texture} map Map to process
+			 * @return {Integer}		 Index of the processed texture in the "textures" array
+			 */
+			function processTexture( map ) {
+
+				if ( cachedData.textures.has( map ) ) {
+
+					return cachedData.textures.get( map );
+
+				}
+
+				if ( ! outputJSON.textures ) {
+
+					outputJSON.textures = [];
+
+				}
+
+				var gltfTexture = {
+
+					sampler: processSampler( map ),
+					source: processImage( map.image, map.format, map.flipY )
+
+				};
+
+				outputJSON.textures.push( gltfTexture );
+
+				var index = outputJSON.textures.length - 1;
+				cachedData.textures.set( map, index );
+
+				return index;
+
+			}
+
+			/**
+			 * Process material
+			 * @param	 {Material} material Material to process
+			 * @return {Integer}			Index of the processed material in the "materials" array
+			 */
+			function processMaterial( material ) {
+
+				if ( cachedData.materials.has( material ) ) {
+
+					return cachedData.materials.get( material );
+
+				}
+
+				if ( ! outputJSON.materials ) {
+
+					outputJSON.materials = [];
+
+				}
+
+				if ( material.isShaderMaterial ) {
+
+					console.warn( 'GLTFExporter: ShaderMaterial not supported.' );
+					return null;
+
+				}
+
+				// @QUESTION Should we avoid including any attribute that has the default value?
+				var gltfMaterial = {
+
+					pbrMetallicRoughness: {}
+
+				};
+
+				if ( material.isMeshBasicMaterial ) {
+
+					gltfMaterial.extensions = { KHR_materials_unlit: {} };
+
+					extensionsUsed[ 'KHR_materials_unlit' ] = true;
+
+				} else if ( ! material.isMeshStandardMaterial ) {
+
+					console.warn( 'GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.' );
+
+				}
+
+				// pbrMetallicRoughness.baseColorFactor
+				var color = material.color.toArray().concat( [ material.opacity ] );
+
+				if ( ! equalArray( color, [ 1, 1, 1, 1 ] ) ) {
+
+					gltfMaterial.pbrMetallicRoughness.baseColorFactor = color;
+
+				}
+
+				if ( material.isMeshStandardMaterial ) {
+
+					gltfMaterial.pbrMetallicRoughness.metallicFactor = material.metalness;
+					gltfMaterial.pbrMetallicRoughness.roughnessFactor = material.roughness;
+
+				} else if ( material.isMeshBasicMaterial ) {
+
+					gltfMaterial.pbrMetallicRoughness.metallicFactor = 0.0;
+					gltfMaterial.pbrMetallicRoughness.roughnessFactor = 0.9;
+
+				} else {
+
+					gltfMaterial.pbrMetallicRoughness.metallicFactor = 0.5;
+					gltfMaterial.pbrMetallicRoughness.roughnessFactor = 0.5;
+
+				}
+
+				// pbrMetallicRoughness.metallicRoughnessTexture
+				if ( material.metalnessMap || material.roughnessMap ) {
+
+					if ( material.metalnessMap === material.roughnessMap ) {
+
+						var metalRoughMapDef = { index: processTexture( material.metalnessMap ) };
+						applyTextureTransform( metalRoughMapDef, material.metalnessMap );
+						gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
+
+					} else {
+
+						console.warn( 'GLTFExporter: Ignoring metalnessMap and roughnessMap because they are not the same Texture.' );
+
+					}
+
+				}
+
+				// pbrMetallicRoughness.baseColorTexture
+				if ( material.map ) {
+
+					var baseColorMapDef = { index: processTexture( material.map ) };
+					applyTextureTransform( baseColorMapDef, material.map );
+					gltfMaterial.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
+
+				}
+
+				if ( material.isMeshBasicMaterial ||
+						 material.isLineBasicMaterial ||
+						 material.isPointsMaterial ) {
+
+				} else {
+
+					// emissiveFactor
+					var emissive = material.emissive.clone().multiplyScalar( material.emissiveIntensity ).toArray();
+
+					if ( ! equalArray( emissive, [ 0, 0, 0 ] ) ) {
+
+						gltfMaterial.emissiveFactor = emissive;
+
+					}
+
+					// emissiveTexture
+					if ( material.emissiveMap ) {
+
+						var emissiveMapDef = { index: processTexture( material.emissiveMap ) };
+						applyTextureTransform( emissiveMapDef, material.emissiveMap );
+						gltfMaterial.emissiveTexture = emissiveMapDef;
+
+					}
+
+				}
+
+				// normalTexture
+				if ( material.normalMap ) {
+
+					var normalMapDef = { index: processTexture( material.normalMap ) };
+
+					if ( material.normalScale.x !== - 1 ) {
+
+						if ( material.normalScale.x !== material.normalScale.y ) {
+
+							console.warn( 'GLTFExporter: Normal scale components are different, ignoring Y and exporting X.' );
+
+						}
+
+						normalMapDef.scale = material.normalScale.x;
+
+					}
+
+					applyTextureTransform( normalMapDef, material.normalMap );
+
+					gltfMaterial.normalTexture = normalMapDef;
+
+				}
+
+				// occlusionTexture
+				if ( material.aoMap ) {
+
+					var occlusionMapDef = {
+						index: processTexture( material.aoMap ),
+						texCoord: 1
+					};
+
+					if ( material.aoMapIntensity !== 1.0 ) {
+
+						occlusionMapDef.strength = material.aoMapIntensity;
+
+					}
+
+					applyTextureTransform( occlusionMapDef, material.aoMap );
+
+					gltfMaterial.occlusionTexture = occlusionMapDef;
+
+				}
+
+				// alphaMode
+				if ( material.transparent || material.alphaTest > 0.0 ) {
+
+					gltfMaterial.alphaMode = material.opacity < 1.0 ? 'BLEND' : 'MASK';
+
+					// Write alphaCutoff if it's non-zero and different from the default (0.5).
+					if ( material.alphaTest > 0.0 && material.alphaTest !== 0.5 ) {
+
+						gltfMaterial.alphaCutoff = material.alphaTest;
+
+					}
+
+				}
+
+				// doubleSided
+				if ( material.side === DoubleSide ) {
+
+					gltfMaterial.doubleSided = true;
+
+				}
+
+				if ( material.name !== '' ) {
+
+					gltfMaterial.name = material.name;
+
+				}
+
+				if ( Object.keys( material.userData ).length > 0 ) {
+
+					gltfMaterial.extras = serializeUserData( material );
+
+				}
+
+				outputJSON.materials.push( gltfMaterial );
+
+				var index = outputJSON.materials.length - 1;
+				cachedData.materials.set( material, index );
+
+				return index;
+
+			}
+
+			/**
+			 * Process mesh
+			 * @param	 {Mesh} mesh Mesh to process
+			 * @return {Integer}			Index of the processed mesh in the "meshes" array
+			 */
+			function processMesh( mesh ) {
+
+				var cacheKey = mesh.geometry.uuid + ':' + mesh.material.uuid;
+				if ( cachedData.meshes.has( cacheKey ) ) {
+
+					return cachedData.meshes.get( cacheKey );
+
+				}
+
+				var geometry = mesh.geometry;
+
+				var mode;
+
+				// Use the correct mode
+				if ( mesh.isLineSegments ) {
+
+					mode = WEBGL_CONSTANTS.LINES;
+
+				} else if ( mesh.isLineLoop ) {
+
+					mode = WEBGL_CONSTANTS.LINE_LOOP;
+
+				} else if ( mesh.isLine ) {
+
+					mode = WEBGL_CONSTANTS.LINE_STRIP;
+
+				} else if ( mesh.isPoints ) {
+
+					mode = WEBGL_CONSTANTS.POINTS;
+
+				} else {
+
+					if ( ! geometry.isBufferGeometry ) {
+
+						console.warn( 'GLTFExporter: Exporting Geometry will increase file size. Use BufferGeometry instead.' );
+
+						var geometryTemp = new BufferGeometry();
+						geometryTemp.fromGeometry( geometry );
+						geometry = geometryTemp;
+
+					}
+
+					if ( mesh.drawMode === TriangleFanDrawMode ) {
+
+						console.warn( 'GLTFExporter: TriangleFanDrawMode and wireframe incompatible.' );
+						mode = WEBGL_CONSTANTS.TRIANGLE_FAN;
+
+					} else if ( mesh.drawMode === TriangleStripDrawMode ) {
+
+						mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINE_STRIP : WEBGL_CONSTANTS.TRIANGLE_STRIP;
+
+					} else {
+
+						mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
+
+					}
+
+				}
+
+				var gltfMesh = {};
+
+				var attributes = {};
+				var primitives = [];
+				var targets = [];
+
+				// Conversion between attributes names in threejs and gltf spec
+				var nameConversion = {
+
+					uv: 'TEXCOORD_0',
+					uv2: 'TEXCOORD_1',
+					color: 'COLOR_0',
+					skinWeight: 'WEIGHTS_0',
+					skinIndex: 'JOINTS_0'
+
+				};
+
+				var originalNormal = geometry.getAttribute( 'normal' );
+
+				if ( originalNormal !== undefined && ! isNormalizedNormalAttribute( originalNormal ) ) {
+
+					console.warn( 'GLTFExporter: Creating normalized normal attribute from the non-normalized one.' );
+
+					geometry.addAttribute( 'normal', createNormalizedNormalAttribute( originalNormal ) );
+
+				}
+
+				// @QUESTION Detect if .vertexColors = VertexColors?
+				// For every attribute create an accessor
+				var modifiedAttribute = null;
+				for ( var attributeName in geometry.attributes ) {
+
+					var attribute = geometry.attributes[ attributeName ];
+					attributeName = nameConversion[ attributeName ] || attributeName.toUpperCase();
+					if (attributeName == 'PRIMITIVEID')
+						continue;
+
+					if ( cachedData.attributes.has( attribute ) ) {
+
+						attributes[ attributeName ] = cachedData.attributes.get( attribute );
+						continue;
+
+					}
+
+					// JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT.
+					modifiedAttribute = null;
+					var array = attribute.array;
+					if ( attributeName === 'JOINTS_0' &&
+							 ! ( array instanceof Uint16Array ) &&
+							 ! ( array instanceof Uint8Array ) ) {
+
+						console.warn( 'GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.' );
+						modifiedAttribute = new BufferAttribute( new Uint16Array( array ), attribute.itemSize, attribute.normalized );
+
+					}
+
+					if ( attributeName.substr( 0, 5 ) !== 'MORPH' ) {
+
+						var accessor = processAccessor( modifiedAttribute || attribute, geometry );
+						if ( accessor !== null ) {
+
+							attributes[ attributeName ] = accessor;
+							cachedData.attributes.set( attribute, accessor );
+
+						}
+
+					}
+
+				}
+
+				if ( originalNormal !== undefined ) geometry.addAttribute( 'normal', originalNormal );
+
+				// Skip if no exportable attributes found
+				if ( Object.keys( attributes ).length === 0 ) {
+
+					return null;
+
+				}
+
+				// Morph targets
+				if ( mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0 ) {
+
+					var weights = [];
+					var targetNames = [];
+					var reverseDictionary = {};
+
+					if ( mesh.morphTargetDictionary !== undefined ) {
+
+						for ( var key in mesh.morphTargetDictionary ) {
+
+							reverseDictionary[ mesh.morphTargetDictionary[ key ] ] = key;
+
+						}
+
+					}
+
+					for ( var i = 0; i < mesh.morphTargetInfluences.length; ++ i ) {
+
+						var target = {};
+
+						var warned = false;
+
+						for ( var attributeName in geometry.morphAttributes ) {
+
+							// glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
+							// Three.js doesn't support TANGENT yet.
+
+							if ( attributeName !== 'position' && attributeName !== 'normal' ) {
+
+								if ( ! warned ) {
+
+									console.warn( 'GLTFExporter: Only POSITION and NORMAL morph are supported.' );
+									warned = true;
+
+								}
+
+								continue;
+
+							}
+
+							var attribute = geometry.morphAttributes[ attributeName ][ i ];
+							var gltfAttributeName = attributeName.toUpperCase();
+
+							// Three.js morph attribute has absolute values while the one of glTF has relative values.
+							//
+							// glTF 2.0 Specification:
+							// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
+
+							var baseAttribute = geometry.attributes[ attributeName ];
+
+							if ( cachedData.attributes.has( attribute ) ) {
+
+								target[ gltfAttributeName ] = cachedData.attributes.get( attribute );
+								continue;
+
+							}
+
+							// Clones attribute not to override
+							var relativeAttribute = attribute.clone();
+
+							for ( var j = 0, jl = attribute.count; j < jl; j ++ ) {
+
+								relativeAttribute.setXYZ(
+									j,
+									attribute.getX( j ) - baseAttribute.getX( j ),
+									attribute.getY( j ) - baseAttribute.getY( j ),
+									attribute.getZ( j ) - baseAttribute.getZ( j )
+								);
+
+							}
+
+							target[ gltfAttributeName ] = processAccessor( relativeAttribute, geometry );
+							cachedData.attributes.set( baseAttribute, target[ gltfAttributeName ] );
+
+						}
+
+						targets.push( target );
+
+						weights.push( mesh.morphTargetInfluences[ i ] );
+						if ( mesh.morphTargetDictionary !== undefined ) targetNames.push( reverseDictionary[ i ] );
+
+					}
+
+					gltfMesh.weights = weights;
+
+					if ( targetNames.length > 0 ) {
+
+						gltfMesh.extras = {};
+						gltfMesh.extras.targetNames = targetNames;
+
+					}
+
+				}
+
+				var extras = ( Object.keys( geometry.userData ).length > 0 ) ? serializeUserData( geometry ) : undefined;
+
+				var forceIndices = options.forceIndices;
+				var isMultiMaterial = Array.isArray( mesh.material );
+
+				if ( isMultiMaterial && geometry.groups.length === 0 ) return null;
+
+				if ( ! forceIndices && geometry.index === null && isMultiMaterial ) {
+
+					// temporal workaround.
+					console.warn( 'GLTFExporter: Creating index for non-indexed multi-material mesh.' );
+					forceIndices = true;
+
+				}
+
+				var didForceIndices = false;
+
+				if ( geometry.index === null && forceIndices ) {
+
+					var indices = [];
+
+					for ( var i = 0, il = geometry.attributes.position.count; i < il; i ++ ) {
+
+						indices[ i ] = i;
+
+					}
+
+					geometry.setIndex( indices );
+
+					didForceIndices = true;
+
+				}
+
+				var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
+				var groups = isMultiMaterial ? geometry.groups : [ { materialIndex: 0, start: undefined, count: undefined } ];
+
+				for ( var i = 0, il = groups.length; i < il; i ++ ) {
+
+					var primitive = {
+						mode: mode,
+						attributes: attributes,
+					};
+
+					if ( extras ) primitive.extras = extras;
+
+					if ( targets.length > 0 ) primitive.targets = targets;
+
+					if ( geometry.index !== null ) {
+
+						if ( cachedData.attributes.has( geometry.index ) ) {
+
+							primitive.indices = cachedData.attributes.get( geometry.index );
+						} else {
+
+							primitive.indices = processAccessor( geometry.index, geometry, groups[ i ].start, groups[ i ].count );
+							cachedData.attributes.set( geometry.index, primitive.indices );
+						}
+						if (primitive.indices === null)
+							delete primitive.indices
+					}
+
+					var material = processMaterial( materials[ groups[ i ].materialIndex ] );
+
+					if ( material !== null ) {
+
+						primitive.material = material;
+
+					}
+
+					primitives.push( primitive );
+
+				}
+
+				if ( didForceIndices ) {
+
+					geometry.setIndex( null );
+
+				}
+
+				gltfMesh.primitives = primitives;
+
+				if ( ! outputJSON.meshes ) {
+
+					outputJSON.meshes = [];
+
+				}
+
+				outputJSON.meshes.push( gltfMesh );
+
+				var index = outputJSON.meshes.length - 1;
+				cachedData.meshes.set( cacheKey, index );
+
+				return index;
+
+			}
+
+			/**
+			 * Process camera
+			 * @param	 {Camera} camera Camera to process
+			 * @return {Integer}			Index of the processed mesh in the "camera" array
+			 */
+			function processCamera( camera ) {
+
+				if ( ! outputJSON.cameras ) {
+
+					outputJSON.cameras = [];
+
+				}
+
+				var isOrtho = camera.isOrthographicCamera;
+
+				var gltfCamera = {
+
+					type: isOrtho ? 'orthographic' : 'perspective'
+
+				};
+
+				if ( isOrtho ) {
+
+					gltfCamera.orthographic = {
+
+						xmag: camera.right * 2,
+						ymag: camera.top * 2,
+						zfar: camera.far <= 0 ? 0.001 : camera.far,
+						znear: camera.near < 0 ? 0 : camera.near
+
+					};
+
+				} else {
+
+					gltfCamera.perspective = {
+
+						aspectRatio: camera.aspect,
+						yfov: Math.degToRad( camera.fov ),
+						zfar: camera.far <= 0 ? 0.001 : camera.far,
+						znear: camera.near < 0 ? 0 : camera.near
+
+					};
+
+				}
+
+				if ( camera.name !== '' ) {
+
+					gltfCamera.name = camera.type;
+
+				}
+
+				outputJSON.cameras.push( gltfCamera );
+
+				return outputJSON.cameras.length - 1;
+
+			}
+
+			/**
+			 * Creates glTF animation entry from AnimationClip object.
+			 *
+			 * Status:
+			 * - Only properties listed in PATH_PROPERTIES may be animated.
+			 *
+			 * @param {AnimationClip} clip
+			 * @param {Object3D} root
+			 * @return {number}
+			 */
+			function processAnimation( clip, root ) {
+
+				if ( ! outputJSON.animations ) {
+
+					outputJSON.animations = [];
+
+				}
+
+				clip = GLTFExporter.Utils.mergeMorphTargetTracks( clip.clone(), root );
+
+				var tracks = clip.tracks;
+				var channels = [];
+				var samplers = [];
+
+				for ( var i = 0; i < tracks.length; ++ i ) {
+
+					var track = tracks[ i ];
+					var trackBinding = PropertyBinding.parseTrackName( track.name );
+					var trackNode = PropertyBinding.findNode( root, trackBinding.nodeName );
+					var trackProperty = PATH_PROPERTIES[ trackBinding.propertyName ];
+
+					if ( trackBinding.objectName === 'bones' ) {
+
+						if ( trackNode.isSkinnedMesh === true ) {
+
+							trackNode = trackNode.skeleton.getBoneByName( trackBinding.objectIndex );
+
+						} else {
+
+							trackNode = undefined;
+
+						}
+
+					}
+
+					if ( ! trackNode || ! trackProperty ) {
+
+						console.warn( 'GLTFExporter: Could not export animation track "%s".', track.name );
+						return null;
+
+					}
+
+					var inputItemSize = 1;
+					var outputItemSize = track.values.length / track.times.length;
+
+					if ( trackProperty === PATH_PROPERTIES.morphTargetInfluences ) {
+
+						outputItemSize /= trackNode.morphTargetInfluences.length;
+
+					}
+
+					var interpolation;
+
+					// @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
+
+					// Detecting glTF cubic spline interpolant by checking factory method's special property
+					// GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
+					// valid value from .getInterpolation().
+					if ( track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true ) {
+
+						interpolation = 'CUBICSPLINE';
+
+						// itemSize of CUBICSPLINE keyframe is 9
+						// (VEC3 * 3: inTangent, splineVertex, and outTangent)
+						// but needs to be stored as VEC3 so dividing by 3 here.
+						outputItemSize /= 3;
+
+					} else if ( track.getInterpolation() === InterpolateDiscrete ) {
+
+						interpolation = 'STEP';
+
+					} else {
+
+						interpolation = 'LINEAR';
+
+					}
+
+					samplers.push( {
+
+						input: processAccessor( new BufferAttribute( track.times, inputItemSize ) ),
+						output: processAccessor( new BufferAttribute( track.values, outputItemSize ) ),
+						interpolation: interpolation
+
+					} );
+
+					channels.push( {
+
+						sampler: samplers.length - 1,
+						target: {
+							node: nodeMap.get( trackNode ),
+							path: trackProperty
+						}
+
+					} );
+
+				}
+
+				outputJSON.animations.push( {
+
+					name: clip.name || 'clip_' + outputJSON.animations.length,
+					samplers: samplers,
+					channels: channels
+
+				} );
+
+				return outputJSON.animations.length - 1;
+
+			}
+
+			function processSkin( object ) {
+
+				var node = outputJSON.nodes[ nodeMap.get( object ) ];
+
+				var skeleton = object.skeleton;
+				var rootJoint = object.skeleton.bones[ 0 ];
+
+				if ( rootJoint === undefined ) return null;
+
+				var joints = [];
+				var inverseBindMatrices = new Float32Array( skeleton.bones.length * 16 );
+
+				for ( var i = 0; i < skeleton.bones.length; ++ i ) {
+
+					joints.push( nodeMap.get( skeleton.bones[ i ] ) );
+
+					skeleton.boneInverses[ i ].toArray( inverseBindMatrices, i * 16 );
+
+				}
+
+				if ( outputJSON.skins === undefined ) {
+
+					outputJSON.skins = [];
+
+				}
+
+				outputJSON.skins.push( {
+
+					inverseBindMatrices: processAccessor( new BufferAttribute( inverseBindMatrices, 16 ) ),
+					joints: joints,
+					skeleton: nodeMap.get( rootJoint )
+
+				} );
+
+				var skinIndex = node.skin = outputJSON.skins.length - 1;
+
+				return skinIndex;
+
+			}
+
+			function processLight( light ) {
+
+				var lightDef = {};
+
+				if ( light.name ) lightDef.name = light.name;
+
+				lightDef.color = light.color.toArray();
+
+				lightDef.intensity = light.intensity;
+
+				if ( light.isDirectionalLight ) {
+
+					lightDef.type = 'directional';
+
+				} else if ( light.isPointLight ) {
+
+					lightDef.type = 'point';
+					if ( light.distance > 0 ) lightDef.range = light.distance;
+
+				} else if ( light.isSpotLight ) {
+
+					lightDef.type = 'spot';
+					if ( light.distance > 0 ) lightDef.range = light.distance;
+					lightDef.spot = {};
+					lightDef.spot.innerConeAngle = ( light.penumbra - 1.0 ) * light.angle * - 1.0;
+					lightDef.spot.outerConeAngle = light.angle;
+
+				}
+
+				if ( light.decay !== undefined && light.decay !== 2 ) {
+
+					console.warn( 'GLTFExporter: Light decay may be lost. glTF is physically-based, '
+												+ 'and expects light.decay=2.' );
+
+				}
+
+				if ( light.target
+						 && ( light.target.parent !== light
+									|| light.target.position.x !== 0
+									|| light.target.position.y !== 0
+									|| light.target.position.z !== - 1 ) ) {
+
+					console.warn( 'GLTFExporter: Light direction may be lost. For best results, '
+												+ 'make light.target a child of the light with position 0,0,-1.' );
+
+				}
+
+				var lights = outputJSON.extensions[ 'KHR_lights_punctual' ].lights;
+				lights.push( lightDef );
+				return lights.length - 1;
+
+			}
+
+			/**
+			 * Process Object3D node
+			 * @param	 {Object3D} node Object3D to processNode
+			 * @return {Integer}			Index of the node in the nodes list
+			 */
+			function processNode( object ) {
+
+				if ( ! outputJSON.nodes ) {
+
+					outputJSON.nodes = [];
+
+				}
+
+				var gltfNode = {};
+
+				if ( options.trs ) {
+
+					var rotation = object.quaternion.toArray();
+					var position = object.position.toArray();
+					var scale = object.scale.toArray();
+
+					if ( ! equalArray( rotation, [ 0, 0, 0, 1 ] ) ) {
+
+						gltfNode.rotation = rotation;
+
+					}
+
+					if ( ! equalArray( position, [ 0, 0, 0 ] ) ) {
+
+						gltfNode.translation = position;
+
+					}
+
+					if ( ! equalArray( scale, [ 1, 1, 1 ] ) ) {
+
+						gltfNode.scale = scale;
+
+					}
+
+				} else {
+
+					object.updateMatrix();
+					if ( ! equalArray( object.matrix.elements, [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ] ) ) {
+
+						gltfNode.matrix = object.matrix.elements;
+
+					}
+
+				}
+
+				// We don't export empty strings name because it represents no-name in Three.js.
+				if ( object.name !== '' ) {
+
+					gltfNode.name = String( object.name );
+
+				}
+
+				if ( object.userData && Object.keys( object.userData ).length > 0 ) {
+
+					gltfNode.extras = serializeUserData( object );
+
+				}
+
+				if ( object.isMesh || object.isLine || object.isPoints ) {
+
+					var mesh = processMesh( object );
+
+					if ( mesh !== null ) {
+
+						gltfNode.mesh = mesh;
+
+					}
+
+				} else if ( object.isCamera ) {
+
+					gltfNode.camera = processCamera( object );
+
+				} else if ( object.isDirectionalLight || object.isPointLight || object.isSpotLight ) {
+
+					if ( ! extensionsUsed[ 'KHR_lights_punctual' ] ) {
+
+						outputJSON.extensions = outputJSON.extensions || {};
+						outputJSON.extensions[ 'KHR_lights_punctual' ] = { lights: [] };
+						extensionsUsed[ 'KHR_lights_punctual' ] = true;
+
+					}
+
+					gltfNode.extensions = gltfNode.extensions || {};
+					gltfNode.extensions[ 'KHR_lights_punctual' ] = { light: processLight( object ) };
+
+				} else if ( object.isLight ) {
+
+					console.warn( `GLTFExporter: light ${object.name} of type ${object.constructor.name}: Only directional, point, and spot lights are supported.` );
+					return null;
+
+				}
+
+				if ( object.isSkinnedMesh ) {
+
+					skins.push( object );
+
+				}
+
+				if ( object.children.length > 0 ) {
+
+					var children = [];
+
+					for ( var i = 0, l = object.children.length; i < l; i ++ ) {
+
+						var child = object.children[ i ];
+
+						if ( child.visible || options.onlyVisible === false ) {
+
+							var node = processNode( child );
+
+							if ( node !== null ) {
+
+								children.push( node );
+
+							}
+
+						}
+
+					}
+
+					if ( children.length > 0 ) {
+
+						gltfNode.children = children;
+
+					}
+
+
+				}
+
+				outputJSON.nodes.push( gltfNode );
+
+				var nodeIndex = outputJSON.nodes.length - 1;
+				nodeMap.set( object, nodeIndex );
+
+				return nodeIndex;
+
+			}
+
+			/**
+			 * Process Scene
+			 * @param	 {Scene} node Scene to process
+			 */
+			function processScene( scene ) {
+
+				if ( ! outputJSON.scenes ) {
+
+					outputJSON.scenes = [];
+					outputJSON.scene = 0;
+
+				}
+
+				var gltfScene = {
+
+					nodes: []
+
+				};
+
+				if ( scene.name !== '' ) {
+
+					gltfScene.name = scene.name;
+
+				}
+
+				if ( scene.userData && Object.keys( scene.userData ).length > 0 ) {
+
+					gltfScene.extras = serializeUserData( scene );
+
+				}
+
+				outputJSON.scenes.push( gltfScene );
+
+				var nodes = [];
+
+				for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
+
+					var child = scene.children[ i ];
+
+					if ( child.visible || options.onlyVisible === false ) {
+
+						var node = processNode( child );
+
+						if ( node !== null ) {
+
+							nodes.push( node );
+
+						}
+
+					}
+
+				}
+
+				if ( nodes.length > 0 ) {
+
+					gltfScene.nodes = nodes;
+
+				}
+
+			}
+
+			/**
+			 * Creates a Scene to hold a list of objects and parse it
+			 * @param	 {Array} objects List of objects to process
+			 */
+			function processObjects( objects ) {
+
+				var scene = new Scene();
+				scene.name = 'AuxScene';
+
+				for ( var i = 0; i < objects.length; i ++ ) {
+
+					// We push directly to children instead of calling `add` to prevent
+					// modify the .parent and break its original scene and hierarchy
+					scene.children.push( objects[ i ] );
+
+				}
+
+				processScene( scene );
+
+			}
+
+			function processInput( input ) {
+
+				input = input instanceof Array ? input : [ input ];
+
+				var objectsWithoutScene = [];
+
+				for ( var i = 0; i < input.length; i ++ ) {
+
+					if ( input[ i ] instanceof Scene ) {
+
+						processScene( input[ i ] );
+
+					} else {
+
+						objectsWithoutScene.push( input[ i ] );
+
+					}
+
+				}
+
+				if ( objectsWithoutScene.length > 0 ) {
+
+					processObjects( objectsWithoutScene );
+
+				}
+
+				for ( var i = 0; i < skins.length; ++ i ) {
+
+					processSkin( skins[ i ] );
+
+				}
+
+				for ( var i = 0; i < options.animations.length; ++ i ) {
+
+					processAnimation( options.animations[ i ], input[ 0 ] );
+
+				}
+
+			}
+
+			processInput( input );
+
+			Promise.all( pending ).then( function () {
+
+				// Merge buffers.
+				var blob = new Blob( buffers, { type: 'application/octet-stream' } );
+
+				// Declare extensions.
+				var extensionsUsedList = Object.keys( extensionsUsed );
+				if ( extensionsUsedList.length > 0 ) outputJSON.extensionsUsed = extensionsUsedList;
+
+				if ( outputJSON.buffers && outputJSON.buffers.length > 0 ) {
+
+					// Update bytelength of the single buffer.
+					outputJSON.buffers[ 0 ].byteLength = blob.size;
+
+					var reader = new window.FileReader();
+
+					if ( options.binary === true ) {
+
+						// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
+
+						var GLB_HEADER_BYTES = 12;
+						var GLB_HEADER_MAGIC = 0x46546C67;
+						var GLB_VERSION = 2;
+
+						var GLB_CHUNK_PREFIX_BYTES = 8;
+						var GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
+						var GLB_CHUNK_TYPE_BIN = 0x004E4942;
+
+						reader.readAsArrayBuffer( blob );
+						reader.onloadend = function () {
+
+							// Binary chunk.
+							var binaryChunk = getPaddedArrayBuffer( reader.result );
+							var binaryChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
+							binaryChunkPrefix.setUint32( 0, binaryChunk.byteLength, true );
+							binaryChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_BIN, true );
+
+							// JSON chunk.
+							var jsonChunk = getPaddedArrayBuffer( stringToArrayBuffer( JSON.stringify( outputJSON ) ), 0x20 );
+							var jsonChunkPrefix = new DataView( new ArrayBuffer( GLB_CHUNK_PREFIX_BYTES ) );
+							jsonChunkPrefix.setUint32( 0, jsonChunk.byteLength, true );
+							jsonChunkPrefix.setUint32( 4, GLB_CHUNK_TYPE_JSON, true );
+
+							// GLB header.
+							var header = new ArrayBuffer( GLB_HEADER_BYTES );
+							var headerView = new DataView( header );
+							headerView.setUint32( 0, GLB_HEADER_MAGIC, true );
+							headerView.setUint32( 4, GLB_VERSION, true );
+							var totalByteLength = GLB_HEADER_BYTES
+									+ jsonChunkPrefix.byteLength + jsonChunk.byteLength
+									+ binaryChunkPrefix.byteLength + binaryChunk.byteLength;
+							headerView.setUint32( 8, totalByteLength, true );
+
+							var glbBlob = new Blob( [
+								header,
+								jsonChunkPrefix,
+								jsonChunk,
+								binaryChunkPrefix,
+								binaryChunk
+							], { type: 'application/octet-stream' } );
+
+							var glbReader = new window.FileReader();
+							glbReader.readAsArrayBuffer( glbBlob );
+							glbReader.onloadend = function () {
+
+								onDone( glbReader.result );
+
+							};
+
+						};
+
+					} else {
+
+						reader.readAsDataURL( blob );
+						reader.onloadend = function () {
+
+							var base64data = reader.result;
+							outputJSON.buffers[ 0 ].uri = base64data;
+							onDone( outputJSON );
+
+						};
+
+					}
+
+				} else {
+
+					onDone( outputJSON );
+
+				}
+
+			} );
+
+		}
+
+	};
+
+	GLTFExporter.Utils = {
+
+		insertKeyframe: function ( track, time ) {
+
+			var tolerance = 0.001; // 1ms
+			var valueSize = track.getValueSize();
+
+			var times = new track.TimeBufferType( track.times.length + 1 );
+			var values = new track.ValueBufferType( track.values.length + valueSize );
+			var interpolant = track.createInterpolant( new track.ValueBufferType( valueSize ) );
+
+			var index;
+
+			if ( track.times.length === 0 ) {
+
+				times[ 0 ] = time;
+
+				for ( var i = 0; i < valueSize; i ++ ) {
+
+					values[ i ] = 0;
+
+				}
+
+				index = 0;
+
+			} else if ( time < track.times[ 0 ] ) {
+
+				if ( Math.abs( track.times[ 0 ] - time ) < tolerance ) return 0;
+
+				times[ 0 ] = time;
+				times.set( track.times, 1 );
+
+				values.set( interpolant.evaluate( time ), 0 );
+				values.set( track.values, valueSize );
+
+				index = 0;
+
+			} else if ( time > track.times[ track.times.length - 1 ] ) {
+
+				if ( Math.abs( track.times[ track.times.length - 1 ] - time ) < tolerance ) {
+
+					return track.times.length - 1;
+
+				}
+
+				times[ times.length - 1 ] = time;
+				times.set( track.times, 0 );
+
+				values.set( track.values, 0 );
+				values.set( interpolant.evaluate( time ), track.values.length );
+
+				index = times.length - 1;
+
+			} else {
+
+				for ( var i = 0; i < track.times.length; i ++ ) {
+
+					if ( Math.abs( track.times[ i ] - time ) < tolerance ) return i;
+
+					if ( track.times[ i ] < time && track.times[ i + 1 ] > time ) {
+
+						times.set( track.times.slice( 0, i + 1 ), 0 );
+						times[ i + 1 ] = time;
+						times.set( track.times.slice( i + 1 ), i + 2 );
+
+						values.set( track.values.slice( 0, ( i + 1 ) * valueSize ), 0 );
+						values.set( interpolant.evaluate( time ), ( i + 1 ) * valueSize );
+						values.set( track.values.slice( ( i + 1 ) * valueSize ), ( i + 2 ) * valueSize );
+
+						index = i + 1;
+
+						break;
+
+					}
+
+				}
+
+			}
+
+			track.times = times;
+			track.values = values;
+
+			return index;
+
+		},
+
+		mergeMorphTargetTracks: function ( clip, root ) {
+
+			var tracks = [];
+			var mergedTracks = {};
+			var sourceTracks = clip.tracks;
+
+			for ( var i = 0; i < sourceTracks.length; ++ i ) {
+
+				var sourceTrack = sourceTracks[ i ];
+				var sourceTrackBinding = PropertyBinding.parseTrackName( sourceTrack.name );
+				var sourceTrackNode = PropertyBinding.findNode( root, sourceTrackBinding.nodeName );
+
+				if ( sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined ) {
+
+					// Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
+					tracks.push( sourceTrack );
+					continue;
+
+				}
+
+				if ( sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete
+						 && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear ) {
+
+					if ( sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline ) {
+
+						// This should never happen, because glTF morph target animations
+						// affect all targets already.
+						throw new Error( 'GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.' );
+
+					}
+
+					console.warn( 'GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.' );
+
+					sourceTrack = sourceTrack.clone();
+					sourceTrack.setInterpolation( InterpolateLinear );
+
+				}
+
+				var targetCount = sourceTrackNode.morphTargetInfluences.length;
+				var targetIndex = sourceTrackNode.morphTargetDictionary[ sourceTrackBinding.propertyIndex ];
+
+				if ( targetIndex === undefined ) {
+
+					throw new Error( 'GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex );
+
+				}
+
+				var mergedTrack;
+
+				// If this is the first time we've seen this object, create a new
+				// track to store merged keyframe data for each morph target.
+				if ( mergedTracks[ sourceTrackNode.uuid ] === undefined ) {
+
+					mergedTrack = sourceTrack.clone();
+
+					var values = new mergedTrack.ValueBufferType( targetCount * mergedTrack.times.length );
+
+					for ( var j = 0; j < mergedTrack.times.length; j ++ ) {
+
+						values[ j * targetCount + targetIndex ] = mergedTrack.values[ j ];
+
+					}
+
+					mergedTrack.name = '.morphTargetInfluences';
+					mergedTrack.values = values;
+
+					mergedTracks[ sourceTrackNode.uuid ] = mergedTrack;
+					tracks.push( mergedTrack );
+
+					continue;
+
+				}
+
+				var mergedKeyframeIndex = 0;
+				var sourceKeyframeIndex = 0;
+				var sourceInterpolant = sourceTrack.createInterpolant( new sourceTrack.ValueBufferType( 1 ) );
+
+				mergedTrack = mergedTracks[ sourceTrackNode.uuid ];
+
+				// For every existing keyframe of the merged track, write a (possibly
+				// interpolated) value from the source track.
+				for ( var j = 0; j < mergedTrack.times.length; j ++ ) {
+
+					mergedTrack.values[ j * targetCount + targetIndex ] = sourceInterpolant.evaluate( mergedTrack.times[ j ] );
+
+				}
+
+				// For every existing keyframe of the source track, write a (possibly
+				// new) keyframe to the merged track. Values from the previous loop may
+				// be written again, but keyframes are de-duplicated.
+				for ( var j = 0; j < sourceTrack.times.length; j ++ ) {
+
+					var keyframeIndex = this.insertKeyframe( mergedTrack, sourceTrack.times[ j ] );
+					mergedTrack.values[ keyframeIndex * targetCount + targetIndex ] = sourceTrack.values[ j ];
+
+				}
+
+			}
+
+			clip.tracks = tracks;
+
+			return clip;
+
+		}
+
+	};
+	return GLTFExporter;
+} )();
+
+export { GLTFExporter };

+ 222 - 444
examples/jsm/loaders/GLTFLoader.js

@@ -10,7 +10,6 @@ import {
 	AddEquation,
 	AlwaysDepth,
 	AnimationClip,
-	AnimationUtils,
 	BackSide,
 	Bone,
 	BufferAttribute,
@@ -33,7 +32,6 @@ import {
 	Interpolant,
 	InterpolateDiscrete,
 	InterpolateLinear,
-	InterpolateSmooth,
 	LessDepth,
 	LessEqualDepth,
 	Line,
@@ -283,7 +281,7 @@ var GLTFLoader = ( function () {
 							break;
 
 						case EXTENSIONS.MSFT_TEXTURE_DDS:
-							extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension( json );
+							extensions[ EXTENSIONS.MSFT_TEXTURE_DDS ] = new GLTFTextureDDSExtension();
 							break;
 
 						case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
@@ -312,23 +310,7 @@ var GLTFLoader = ( function () {
 
 			} );
 
-			parser.parse( function ( scene, scenes, cameras, animations, json ) {
-
-				var glTF = {
-					scene: scene,
-					scenes: scenes,
-					cameras: cameras,
-					animations: animations,
-					asset: json.asset,
-					parser: parser,
-					userData: {}
-				};
-
-				addUnknownExtensionsToUserData( extensions, glTF, json );
-
-				onLoad( glTF );
-
-			}, onError );
+			parser.parse( onLoad, onError );
 
 		}
 
@@ -459,6 +441,10 @@ var GLTFLoader = ( function () {
 
 		}
 
+		// Some lights (e.g. spot) default to a position other than the origin. Reset the position
+		// here, because node-level parsing will only override position if explicitly specified.
+		lightNode.position.set( 0, 0, 0 );
+
 		lightNode.decay = 2;
 
 		if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
@@ -602,7 +588,6 @@ var GLTFLoader = ( function () {
 		this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
 		this.json = json;
 		this.dracoLoader = dracoLoader;
-		THREE.DRACOLoader.getDecoderModule();
 
 	}
 
@@ -618,21 +603,23 @@ var GLTFLoader = ( function () {
 
 		for ( var attributeName in gltfAttributeMap ) {
 
-			if ( ! ( attributeName in ATTRIBUTES ) ) continue;
+			var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
 
-			threeAttributeMap[ ATTRIBUTES[ attributeName ] ] = gltfAttributeMap[ attributeName ];
+			threeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];
 
 		}
 
 		for ( attributeName in primitive.attributes ) {
 
-			if ( ATTRIBUTES[ attributeName ] !== undefined && gltfAttributeMap[ attributeName ] !== undefined ) {
+			var threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
+
+			if ( gltfAttributeMap[ attributeName ] !== undefined ) {
 
 				var accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
 				var componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
 
-				attributeTypeMap[ ATTRIBUTES[ attributeName ] ] = componentType;
-				attributeNormalizedMap[ ATTRIBUTES[ attributeName ] ] = accessorDef.normalized === true;
+				attributeTypeMap[ threeAttributeName ] = componentType;
+				attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;
 
 			}
 
@@ -1292,6 +1279,7 @@ var GLTFLoader = ( function () {
 	var ATTRIBUTES = {
 		POSITION: 'position',
 		NORMAL: 'normal',
+		TANGENT: 'tangent',
 		TEXCOORD_0: 'uv',
 		TEXCOORD_1: 'uv2',
 		COLOR_0: 'color',
@@ -1307,10 +1295,8 @@ var GLTFLoader = ( function () {
 	};
 
 	var INTERPOLATION = {
-		CUBICSPLINE: InterpolateSmooth, // We use custom interpolation GLTFCubicSplineInterpolation for CUBICSPLINE.
-		                                      // KeyframeTrack.optimize() can't handle glTF Cubic Spline output values layout,
-		                                      // using InterpolateSmooth for KeyframeTrack instantiation to prevent optimization.
-		                                      // See KeyframeTrack.optimize() for the detail.
+		CUBICSPLINE: undefined, // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
+		                        // keyframe track will be initialized with a default interpolation type, then modified.
 		LINEAR: InterpolateLinear,
 		STEP: InterpolateDiscrete
 	};
@@ -1356,12 +1342,14 @@ var GLTFLoader = ( function () {
 
 	}
 
+	var defaultMaterial;
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
 	 */
 	function createDefaultMaterial() {
 
-		return new MeshStandardMaterial( {
+		defaultMaterial = defaultMaterial || new MeshStandardMaterial( {
 			color: 0xFFFFFF,
 			emissive: 0x000000,
 			metalness: 1,
@@ -1371,6 +1359,8 @@ var GLTFLoader = ( function () {
 			side: FrontSide
 		} );
 
+		return defaultMaterial;
+
 	}
 
 	function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {
@@ -1447,34 +1437,21 @@ var GLTFLoader = ( function () {
 
 			if ( hasMorphPosition ) {
 
-				// TODO: Error-prone use of a callback inside a loop.
-				var accessor = target.POSITION !== undefined
+				var pendingAccessor = target.POSITION !== undefined
 					? parser.getDependency( 'accessor', target.POSITION )
-						.then( function ( accessor ) {
-
-							// Cloning not to pollute original accessor below
-							return cloneBufferAttribute( accessor );
-
-						} )
 					: geometry.attributes.position;
 
-				pendingPositionAccessors.push( accessor );
+				pendingPositionAccessors.push( pendingAccessor );
 
 			}
 
 			if ( hasMorphNormal ) {
 
-				// TODO: Error-prone use of a callback inside a loop.
-				var accessor = target.NORMAL !== undefined
+				var pendingAccessor = target.NORMAL !== undefined
 					? parser.getDependency( 'accessor', target.NORMAL )
-						.then( function ( accessor ) {
-
-							return cloneBufferAttribute( accessor );
-
-						} )
 					: geometry.attributes.normal;
 
-				pendingNormalAccessors.push( accessor );
+				pendingNormalAccessors.push( pendingAccessor );
 
 			}
 
@@ -1488,6 +1465,24 @@ var GLTFLoader = ( function () {
 			var morphPositions = accessors[ 0 ];
 			var morphNormals = accessors[ 1 ];
 
+			// Clone morph target accessors before modifying them.
+
+			for ( var i = 0, il = morphPositions.length; i < il; i ++ ) {
+
+				if ( geometry.attributes.position === morphPositions[ i ] ) continue;
+
+				morphPositions[ i ] = cloneBufferAttribute( morphPositions[ i ] );
+
+			}
+
+			for ( var i = 0, il = morphNormals.length; i < il; i ++ ) {
+
+				if ( geometry.attributes.normal === morphNormals[ i ] ) continue;
+
+				morphNormals[ i ] = cloneBufferAttribute( morphNormals[ i ] );
+
+			}
+
 			for ( var i = 0, il = targets.length; i < il; i ++ ) {
 
 				var target = targets[ i ];
@@ -1608,30 +1603,6 @@ var GLTFLoader = ( function () {
 		}
 
 	}
-
-	function isPrimitiveEqual( a, b ) {
-
-		var dracoExtA = a.extensions ? a.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
-		var dracoExtB = b.extensions ? b.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] : undefined;
-
-		if ( dracoExtA && dracoExtB ) {
-
-			if ( dracoExtA.bufferView !== dracoExtB.bufferView ) return false;
-
-			return isObjectEqual( dracoExtA.attributes, dracoExtB.attributes );
-
-		}
-
-		if ( a.indices !== b.indices ) {
-
-			return false;
-
-		}
-
-		return isObjectEqual( a.attributes, b.attributes );
-
-	}
-
 	function isObjectEqual( a, b ) {
 
 		if ( Object.keys( a ).length !== Object.keys( b ).length ) return false;
@@ -1646,59 +1617,40 @@ var GLTFLoader = ( function () {
 
 	}
 
-	function isArrayEqual( a, b ) {
+	function createPrimitiveKey( primitiveDef ) {
 
-		if ( a.length !== b.length ) return false;
+		var dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
+		var geometryKey;
 
-		for ( var i = 0, il = a.length; i < il; i ++ ) {
+		if ( dracoExtension ) {
 
-			if ( a[ i ] !== b[ i ] ) return false;
-
-		}
-
-		return true;
-
-	}
+			geometryKey = 'draco:' + dracoExtension.bufferView
+				+ ':' + dracoExtension.indices
+				+ ':' + createAttributesKey( dracoExtension.attributes );
 
-	function getCachedGeometry( cache, newPrimitive ) {
-
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
-
-			var cached = cache[ i ];
+		} else {
 
-			if ( isPrimitiveEqual( cached.primitive, newPrimitive ) ) return cached.promise;
+			geometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;
 
 		}
 
-		return null;
+		return geometryKey;
 
 	}
 
-	function getCachedCombinedGeometry( cache, geometries ) {
-
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
-
-			var cached = cache[ i ];
-
-			if ( isArrayEqual( geometries, cached.baseGeometries ) ) return cached.geometry;
-
-		}
-
-		return null;
-
-	}
+	function createAttributesKey( attributes ) {
 
-	function getCachedMultiPassGeometry( cache, geometry, primitives ) {
+		var attributesKey = '';
 
-		for ( var i = 0, il = cache.length; i < il; i ++ ) {
+		var keys = Object.keys( attributes ).sort();
 
-			var cached = cache[ i ];
+		for ( var i = 0, il = keys.length; i < il; i ++ ) {
 
-			if ( geometry === cached.baseGeometry && isArrayEqual( primitives, cached.primitives ) ) return cached.geometry;
+			attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';
 
 		}
 
-		return null;
+		return attributesKey;
 
 	}
 
@@ -1727,48 +1679,6 @@ var GLTFLoader = ( function () {
 
 	}
 
-	/**
-	 * Checks if we can build a single Mesh with MultiMaterial from multiple primitives.
-	 * Returns true if all primitives use the same attributes/morphAttributes/mode
-	 * and also have index. Otherwise returns false.
-	 *
-	 * @param {Array<GLTF.Primitive>} primitives
-	 * @return {Boolean}
-	 */
-	function isMultiPassGeometry( primitives ) {
-
-		if ( primitives.length < 2 ) return false;
-
-		var primitive0 = primitives[ 0 ];
-		var targets0 = primitive0.targets || [];
-
-		if ( primitive0.indices === undefined ) return false;
-
-		for ( var i = 1, il = primitives.length; i < il; i ++ ) {
-
-			var primitive = primitives[ i ];
-
-			if ( primitive0.mode !== primitive.mode ) return false;
-			if ( primitive.indices === undefined ) return false;
-			if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) return false;
-			if ( ! isObjectEqual( primitive0.attributes, primitive.attributes ) ) return false;
-
-			var targets = primitive.targets || [];
-
-			if ( targets0.length !== targets.length ) return false;
-
-			for ( var j = 0, jl = targets0.length; j < jl; j ++ ) {
-
-				if ( ! isObjectEqual( targets0[ j ], targets[ j ] ) ) return false;
-
-			}
-
-		}
-
-		return true;
-
-	}
-
 	/* GLTF PARSER */
 
 	function GLTFParser( json, extensions, options ) {
@@ -1781,9 +1691,7 @@ var GLTFLoader = ( function () {
 		this.cache = new GLTFRegistry();
 
 		// BufferGeometry caching
-		this.primitiveCache = [];
-		this.multiplePrimitivesCache = [];
-		this.multiPassGeometryCache = [];
+		this.primitiveCache = {};
 
 		this.textureLoader = new TextureLoader( this.options.manager );
 		this.textureLoader.setCrossOrigin( this.options.crossOrigin );
@@ -1795,7 +1703,9 @@ var GLTFLoader = ( function () {
 
 	GLTFParser.prototype.parse = function ( onLoad, onError ) {
 
+		var parser = this;
 		var json = this.json;
+		var extensions = this.extensions;
 
 		// Clear the loader cache
 		this.cache.removeAll();
@@ -1803,21 +1713,27 @@ var GLTFLoader = ( function () {
 		// Mark the special nodes/meshes in json for efficient parse
 		this.markDefs();
 
-		// Fire the callback on complete
-		this.getMultiDependencies( [
+		Promise.all( [
 
-			'scene',
-			'animation',
-			'camera'
+			this.getDependencies( 'scene' ),
+			this.getDependencies( 'animation' ),
+			this.getDependencies( 'camera' ),
 
 		] ).then( function ( dependencies ) {
 
-			var scenes = dependencies.scenes || [];
-			var scene = scenes[ json.scene || 0 ];
-			var animations = dependencies.animations || [];
-			var cameras = dependencies.cameras || [];
+			var result = {
+				scene: dependencies[ 0 ][ json.scene || 0 ],
+				scenes: dependencies[ 0 ],
+				animations: dependencies[ 1 ],
+				cameras: dependencies[ 2 ],
+				asset: json.asset,
+				parser: parser,
+				userData: {}
+			};
+
+			addUnknownExtensionsToUserData( extensions, result, json );
 
-			onLoad( scene, scenes, cameras, animations, json );
+			onLoad( result );
 
 		} ).catch( onError );
 
@@ -1990,40 +1906,6 @@ var GLTFLoader = ( function () {
 
 	};
 
-	/**
-	 * Requests all multiple dependencies of the specified types asynchronously, with caching.
-	 * @param {Array<string>} types
-	 * @return {Promise<Object<Array<Object>>>}
-	 */
-	GLTFParser.prototype.getMultiDependencies = function ( types ) {
-
-		var results = {};
-		var pending = [];
-
-		for ( var i = 0, il = types.length; i < il; i ++ ) {
-
-			var type = types[ i ];
-			var value = this.getDependencies( type );
-
-			// TODO: Error-prone use of a callback inside a loop.
-			value = value.then( function ( key, value ) {
-
-				results[ key ] = value;
-
-			}.bind( this, type + ( type === 'mesh' ? 'es' : 's' ) ) );
-
-			pending.push( value );
-
-		}
-
-		return Promise.all( pending ).then( function () {
-
-			return results;
-
-		} );
-
-	};
-
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
 	 * @param {number} bufferIndex
@@ -2326,6 +2208,18 @@ var GLTFLoader = ( function () {
 
 		return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
 
+			switch ( mapName ) {
+
+				case 'aoMap':
+				case 'emissiveMap':
+				case 'metalnessMap':
+				case 'normalMap':
+				case 'roughnessMap':
+					texture.format = RGBFormat;
+					break;
+
+			}
+
 			if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
 
 				var transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
@@ -2344,6 +2238,124 @@ var GLTFLoader = ( function () {
 
 	};
 
+	/**
+	 * Assigns final material to a Mesh, Line, or Points instance. The instance
+	 * already has a material (generated from the glTF material options alone)
+	 * but reuse of the same glTF material may require multiple threejs materials
+	 * to accomodate different primitive types, defines, etc. New materials will
+	 * be created if necessary, and reused from a cache.
+	 * @param  {Object3D} mesh Mesh, Line, or Points instance.
+	 */
+	GLTFParser.prototype.assignFinalMaterial = function ( mesh ) {
+
+		var geometry = mesh.geometry;
+		var material = mesh.material;
+		var extensions = this.extensions;
+
+		var useVertexTangents = geometry.attributes.tangent !== undefined;
+		var useVertexColors = geometry.attributes.color !== undefined;
+		var useFlatShading = geometry.attributes.normal === undefined;
+		var useSkinning = mesh.isSkinnedMesh === true;
+		var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
+		var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
+
+		if ( mesh.isPoints ) {
+
+			var cacheKey = 'PointsMaterial:' + material.uuid;
+
+			var pointsMaterial = this.cache.get( cacheKey );
+
+			if ( ! pointsMaterial ) {
+
+				pointsMaterial = new PointsMaterial();
+				Material.prototype.copy.call( pointsMaterial, material );
+				pointsMaterial.color.copy( material.color );
+				pointsMaterial.map = material.map;
+				pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
+
+				this.cache.add( cacheKey, pointsMaterial );
+
+			}
+
+			material = pointsMaterial;
+
+		} else if ( mesh.isLine ) {
+
+			var cacheKey = 'LineBasicMaterial:' + material.uuid;
+
+			var lineMaterial = this.cache.get( cacheKey );
+
+			if ( ! lineMaterial ) {
+
+				lineMaterial = new LineBasicMaterial();
+				Material.prototype.copy.call( lineMaterial, material );
+				lineMaterial.color.copy( material.color );
+				lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
+
+				this.cache.add( cacheKey, lineMaterial );
+
+			}
+
+			material = lineMaterial;
+
+		}
+
+		// Clone the material if it will be modified
+		if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
+
+			var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
+
+			if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
+			if ( useSkinning ) cacheKey += 'skinning:';
+			if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
+			if ( useVertexColors ) cacheKey += 'vertex-colors:';
+			if ( useFlatShading ) cacheKey += 'flat-shading:';
+			if ( useMorphTargets ) cacheKey += 'morph-targets:';
+			if ( useMorphNormals ) cacheKey += 'morph-normals:';
+
+			var cachedMaterial = this.cache.get( cacheKey );
+
+			if ( ! cachedMaterial ) {
+
+				cachedMaterial = material.isGLTFSpecularGlossinessMaterial
+					? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
+					: material.clone();
+
+				if ( useSkinning ) cachedMaterial.skinning = true;
+				if ( useVertexTangents ) cachedMaterial.vertexTangents = true;
+				if ( useVertexColors ) cachedMaterial.vertexColors = VertexColors;
+				if ( useFlatShading ) cachedMaterial.flatShading = true;
+				if ( useMorphTargets ) cachedMaterial.morphTargets = true;
+				if ( useMorphNormals ) cachedMaterial.morphNormals = true;
+
+				this.cache.add( cacheKey, cachedMaterial );
+
+			}
+
+			material = cachedMaterial;
+
+		}
+
+		// workarounds for mesh and geometry
+
+		if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
+
+			console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
+			geometry.addAttribute( 'uv2', new BufferAttribute( geometry.attributes.uv.array, 2 ) );
+
+		}
+
+		if ( material.isGLTFSpecularGlossinessMaterial ) {
+
+			// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
+			mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
+
+		}
+
+		mesh.material = material;
+
+	};
+
 	/**
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
 	 * @param {number} materialIndex
@@ -2491,14 +2503,6 @@ var GLTFLoader = ( function () {
 
 			if ( materialDef.name !== undefined ) material.name = materialDef.name;
 
-			// Normal map textures use OpenGL conventions:
-			// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#materialnormaltexture
-			if ( material.normalScale ) {
-
-				material.normalScale.y = - material.normalScale.y;
-
-			}
-
 			// baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
 			if ( material.map ) material.map.encoding = sRGBEncoding;
 			if ( material.emissiveMap ) material.emissiveMap.encoding = sRGBEncoding;
@@ -2539,9 +2543,7 @@ var GLTFLoader = ( function () {
 
 		for ( var gltfAttributeName in attributes ) {
 
-			var threeAttributeName = ATTRIBUTES[ gltfAttributeName ];
-
-			if ( ! threeAttributeName ) continue;
+			var threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase();
 
 			// Skip attributes already provided by e.g. Draco extension.
 			if ( threeAttributeName in geometry.attributes ) continue;
@@ -2578,8 +2580,6 @@ var GLTFLoader = ( function () {
 	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
 	 *
 	 * Creates BufferGeometries from primitives.
-	 * If we can build a single BufferGeometry with .groups from multiple primitives, returns one BufferGeometry.
-	 * Otherwise, returns BufferGeometries without .groups as many as primitives.
 	 *
 	 * @param {Array<GLTF.Primitive>} primitives
 	 * @return {Promise<Array<BufferGeometry>>}
@@ -2590,22 +2590,6 @@ var GLTFLoader = ( function () {
 		var extensions = this.extensions;
 		var cache = this.primitiveCache;
 
-		var isMultiPass = isMultiPassGeometry( primitives );
-		var originalPrimitives;
-
-		if ( isMultiPass ) {
-
-			originalPrimitives = primitives; // save original primitives and use later
-
-			// We build a single BufferGeometry with .groups from multiple primitives
-			// because all primitives share the same attributes/morph/mode and have indices.
-
-			primitives = [ primitives[ 0 ] ];
-
-			// Sets .groups and combined indices to a geometry later in this method.
-
-		}
-
 		function createDracoPrimitive( primitive ) {
 
 			return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ]
@@ -2623,14 +2607,15 @@ var GLTFLoader = ( function () {
 		for ( var i = 0, il = primitives.length; i < il; i ++ ) {
 
 			var primitive = primitives[ i ];
+			var cacheKey = createPrimitiveKey( primitive );
 
 			// See if we've already created this geometry
-			var cached = getCachedGeometry( cache, primitive );
+			var cached = cache[ cacheKey ];
 
 			if ( cached ) {
 
 				// Use the cached geometry if it exists
-				pending.push( cached );
+				pending.push( cached.promise );
 
 			} else {
 
@@ -2649,7 +2634,7 @@ var GLTFLoader = ( function () {
 				}
 
 				// Cache this geometry
-				cache.push( { primitive: primitive, promise: geometryPromise } );
+				cache[ cacheKey ] = { primitive: primitive, promise: geometryPromise };
 
 				pending.push( geometryPromise );
 
@@ -2657,95 +2642,7 @@ var GLTFLoader = ( function () {
 
 		}
 
-		return Promise.all( pending ).then( function ( geometries ) {
-
-			if ( isMultiPass ) {
-
-				var baseGeometry = geometries[ 0 ];
-
-				// See if we've already created this combined geometry
-				var cache = parser.multiPassGeometryCache;
-				var cached = getCachedMultiPassGeometry( cache, baseGeometry, originalPrimitives );
-
-				if ( cached !== null ) return [ cached.geometry ];
-
-				// Cloning geometry because of index override.
-				// Attributes can be reused so cloning by myself here.
-				var geometry = new BufferGeometry();
-
-				geometry.name = baseGeometry.name;
-				geometry.userData = baseGeometry.userData;
-
-				for ( var key in baseGeometry.attributes ) geometry.addAttribute( key, baseGeometry.attributes[ key ] );
-				for ( var key in baseGeometry.morphAttributes ) geometry.morphAttributes[ key ] = baseGeometry.morphAttributes[ key ];
-
-				var pendingIndices = [];
-
-				for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
-
-					pendingIndices.push( parser.getDependency( 'accessor', originalPrimitives[ i ].indices ) );
-
-				}
-
-				return Promise.all( pendingIndices ).then( function ( accessors ) {
-
-					var indices = [];
-					var offset = 0;
-
-					for ( var i = 0, il = originalPrimitives.length; i < il; i ++ ) {
-
-						var accessor = accessors[ i ];
-
-						for ( var j = 0, jl = accessor.count; j < jl; j ++ ) indices.push( accessor.array[ j ] );
-
-						geometry.addGroup( offset, accessor.count, i );
-
-						offset += accessor.count;
-
-					}
-
-					geometry.setIndex( indices );
-
-					cache.push( { geometry: geometry, baseGeometry: baseGeometry, primitives: originalPrimitives } );
-
-					return [ geometry ];
-
-				} );
-
-			} else if ( geometries.length > 1 && THREE.BufferGeometryUtils !== undefined ) {
-
-				// Tries to merge geometries with BufferGeometryUtils if possible
-
-				for ( var i = 1, il = primitives.length; i < il; i ++ ) {
-
-					// can't merge if draw mode is different
-					if ( primitives[ 0 ].mode !== primitives[ i ].mode ) return geometries;
-
-				}
-
-				// See if we've already created this combined geometry
-				var cache = parser.multiplePrimitivesCache;
-				var cached = getCachedCombinedGeometry( cache, geometries );
-
-				if ( cached ) {
-
-					if ( cached.geometry !== null ) return [ cached.geometry ];
-
-				} else {
-
-					var geometry = THREE.BufferGeometryUtils.mergeBufferGeometries( geometries, true );
-
-					cache.push( { geometry: geometry, baseGeometries: geometries } );
-
-					if ( geometry !== null ) return [ geometry ];
-
-				}
-
-			}
-
-			return geometries;
-
-		} );
+		return Promise.all( pending );
 
 	};
 
@@ -2779,8 +2676,6 @@ var GLTFLoader = ( function () {
 
 			return parser.loadGeometries( primitives ).then( function ( geometries ) {
 
-				var isMultiMaterial = geometries.length === 1 && geometries[ 0 ].groups.length > 0;
-
 				var meshes = [];
 
 				for ( var i = 0, il = geometries.length; i < il; i ++ ) {
@@ -2792,7 +2687,7 @@ var GLTFLoader = ( function () {
 
 					var mesh;
 
-					var material = isMultiMaterial ? originalMaterials : originalMaterials[ i ];
+					var material = originalMaterials[ i ];
 
 					if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
 						primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
@@ -2850,118 +2745,9 @@ var GLTFLoader = ( function () {
 
 					assignExtrasToUserData( mesh, meshDef );
 
-					meshes.push( mesh );
-
-					// 2. update Material depending on Mesh and BufferGeometry
-
-					var materials = isMultiMaterial ? mesh.material : [ mesh.material ];
-
-					var useVertexColors = geometry.attributes.color !== undefined;
-					var useFlatShading = geometry.attributes.normal === undefined;
-					var useSkinning = mesh.isSkinnedMesh === true;
-					var useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
-					var useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
-
-					for ( var j = 0, jl = materials.length; j < jl; j ++ ) {
-
-						var material = materials[ j ];
-
-						if ( mesh.isPoints ) {
-
-							var cacheKey = 'PointsMaterial:' + material.uuid;
-
-							var pointsMaterial = parser.cache.get( cacheKey );
-
-							if ( ! pointsMaterial ) {
-
-								pointsMaterial = new PointsMaterial();
-								Material.prototype.copy.call( pointsMaterial, material );
-								pointsMaterial.color.copy( material.color );
-								pointsMaterial.map = material.map;
-								pointsMaterial.lights = false; // PointsMaterial doesn't support lights yet
-
-								parser.cache.add( cacheKey, pointsMaterial );
-
-							}
-
-							material = pointsMaterial;
-
-						} else if ( mesh.isLine ) {
-
-							var cacheKey = 'LineBasicMaterial:' + material.uuid;
-
-							var lineMaterial = parser.cache.get( cacheKey );
-
-							if ( ! lineMaterial ) {
+					parser.assignFinalMaterial( mesh );
 
-								lineMaterial = new LineBasicMaterial();
-								Material.prototype.copy.call( lineMaterial, material );
-								lineMaterial.color.copy( material.color );
-								lineMaterial.lights = false; // LineBasicMaterial doesn't support lights yet
-
-								parser.cache.add( cacheKey, lineMaterial );
-
-							}
-
-							material = lineMaterial;
-
-						}
-
-						// Clone the material if it will be modified
-						if ( useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
-
-							var cacheKey = 'ClonedMaterial:' + material.uuid + ':';
-
-							if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
-							if ( useSkinning ) cacheKey += 'skinning:';
-							if ( useVertexColors ) cacheKey += 'vertex-colors:';
-							if ( useFlatShading ) cacheKey += 'flat-shading:';
-							if ( useMorphTargets ) cacheKey += 'morph-targets:';
-							if ( useMorphNormals ) cacheKey += 'morph-normals:';
-
-							var cachedMaterial = parser.cache.get( cacheKey );
-
-							if ( ! cachedMaterial ) {
-
-								cachedMaterial = material.isGLTFSpecularGlossinessMaterial
-									? extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].cloneMaterial( material )
-									: material.clone();
-
-								if ( useSkinning ) cachedMaterial.skinning = true;
-								if ( useVertexColors ) cachedMaterial.vertexColors = VertexColors;
-								if ( useFlatShading ) cachedMaterial.flatShading = true;
-								if ( useMorphTargets ) cachedMaterial.morphTargets = true;
-								if ( useMorphNormals ) cachedMaterial.morphNormals = true;
-
-								parser.cache.add( cacheKey, cachedMaterial );
-
-							}
-
-							material = cachedMaterial;
-
-						}
-
-						materials[ j ] = material;
-
-						// workarounds for mesh and geometry
-
-						if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
-
-							console.log( 'THREE.GLTFLoader: Duplicating UVs to support aoMap.' );
-							geometry.addAttribute( 'uv2', new BufferAttribute( geometry.attributes.uv.array, 2 ) );
-
-						}
-
-						if ( material.isGLTFSpecularGlossinessMaterial ) {
-
-							// for GLTFSpecularGlossinessMaterial(ShaderMaterial) uniforms runtime update
-							mesh.onBeforeRender = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].refreshUniforms;
-
-						}
-
-					}
-
-					mesh.material = isMultiMaterial ? materials : materials[ 0 ];
+					meshes.push( mesh );
 
 				}
 
@@ -3146,10 +2932,7 @@ var GLTFLoader = ( function () {
 
 				if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
 
-					// node can be Group here but
-					// PATH_PROPERTIES.weights(morphTargetInfluences) should be
-					// the property of a mesh object under group.
-
+					// Node may be a Group (glTF mesh with several primitives) or a Mesh.
 					node.traverse( function ( object ) {
 
 						if ( object.isMesh === true && object.morphTargetInfluences ) {
@@ -3166,20 +2949,16 @@ var GLTFLoader = ( function () {
 
 				}
 
-				// KeyframeTrack.optimize() will modify given 'times' and 'values'
-				// buffers before creating a truncated copy to keep. Because buffers may
-				// be reused by other tracks, make copies here.
 				for ( var j = 0, jl = targetNames.length; j < jl; j ++ ) {
 
 					var track = new TypedKeyframeTrack(
 						targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ],
-						AnimationUtils.arraySlice( inputAccessor.array, 0 ),
-						AnimationUtils.arraySlice( outputAccessor.array, 0 ),
+						inputAccessor.array,
+						outputAccessor.array,
 						interpolation
 					);
 
-					// Here is the trick to enable custom interpolation.
-					// Overrides .createInterpolant in a factory method which creates custom interpolation.
+					// Override interpolation with custom factory method.
 					if ( sampler.interpolation === 'CUBICSPLINE' ) {
 
 						track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
@@ -3192,8 +2971,7 @@ var GLTFLoader = ( function () {
 
 						};
 
-						// Workaround, provide an alternate way to know if the interpolant type is cubis spline to track.
-						// track.getInterpolation() doesn't return valid value for custom interpolant.
+						// Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
 						track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
 
 					}

+ 24 - 46
examples/webgl2_sandbox.html

@@ -6,11 +6,14 @@
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
 			body {
-				background:#000;
-				padding:0;
-				margin:0;
+				background: #000;
+				padding: 0;
+				margin: 0;
 				font-weight: bold;
-				overflow:hidden;
+			}
+
+			canvas {
+				display: block;
 			}
 
 			#info {
@@ -18,10 +21,9 @@
 				top: 0px; width: 100%;
 				color: #ffffff;
 				padding: 5px;
-				font-family:Monospace;
-				font-size:13px;
-				text-align:center;
-				z-index:1000;
+				font-family: Monospace;
+				font-size: 13px;
+				text-align: center;
 			}
 
 			a {
@@ -46,40 +48,38 @@
 			import { Scene } from '../src/scenes/Scene.js';
 			import { WebGLRenderer } from '../src/renderers/WebGLRenderer.js';
 
+			import { OrbitControls } from './jsm/controls/OrbitControls.js';
+
 			//
 
 			var camera, scene, renderer;
-
-			var mouseX = 0, mouseY = 0;
-
-			var windowHalfX = window.innerWidth / 2;
-			var windowHalfY = window.innerHeight / 2;
+			var controls;
 
 			init();
-			animate();
+			render();
 
 			function init() {
 
-				camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 20000 );
-				camera.position.z = 3200;
+				camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 100 );
+				camera.position.z = 3;
 
 				scene = new Scene();
 				scene.background = new Color( 0, 0, 0.5 );
-				scene.fog = new Fog( 0x000000, 1, 20000 );
+				scene.fog = new Fog( 0x000000, 0.1, 3 );
 
 				var light = new PointLight( 0xffffff );
 				scene.add( light );
 
-				var geometry = new SphereBufferGeometry( 50, 32, 16 );
+				var geometry = new SphereBufferGeometry( 0.05, 32, 16 );
 				var material = new MeshNormalMaterial();
 
 				for ( var i = 0; i < 5000; i ++ ) {
 
 					var mesh = new Mesh( geometry, material );
 
-					mesh.position.x = Math.random() * 10000 - 5000;
-					mesh.position.y = Math.random() * 10000 - 5000;
-					mesh.position.z = Math.random() * 10000 - 5000;
+					mesh.position.x = Math.random() * 10 - 5;
+					mesh.position.y = Math.random() * 10 - 5;
+					mesh.position.z = Math.random() * 10 - 5;
 
 					mesh.rotation.y = Math.random() * 2 * Math.PI;
 
@@ -97,19 +97,17 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				document.body.appendChild( renderer.domElement );
 
-				document.addEventListener( 'mousemove', onDocumentMouseMove, false );
+				window.addEventListener( 'resize', onWindowResize, false );
 
 				//
 
-				window.addEventListener( 'resize', onWindowResize, false );
+				controls = new OrbitControls( camera, renderer.domElement );
+				controls.addEventListener( 'change', render );
 
 			}
 
 			function onWindowResize() {
 
-				windowHalfX = window.innerWidth / 2;
-				windowHalfY = window.innerHeight / 2;
-
 				camera.aspect = window.innerWidth / window.innerHeight;
 				camera.updateProjectionMatrix();
 
@@ -117,30 +115,10 @@
 
 			}
 
-			function onDocumentMouseMove( event ) {
-
-				mouseX = ( event.clientX - windowHalfX ) * 10;
-				mouseY = ( event.clientY - windowHalfY ) * 10;
-
-			}
-
 			//
 
-			function animate() {
-
-				requestAnimationFrame( animate );
-
-				render();
-
-			}
-
 			function render() {
 
-				camera.position.x += ( mouseX - camera.position.x ) * .05;
-				camera.position.y += ( - mouseY - camera.position.y ) * .05;
-
-				camera.lookAt( scene.position );
-
 				renderer.render( scene, camera );
 
 			}

+ 6 - 6
examples/webgl_gpgpu_birds.html

@@ -365,9 +365,9 @@
 
 						vertices.array[ v ++ ] = arguments[ i ];
 
-		}
+					}
 
-	}
+				}
 
 				var wingsSpan = 20;
 
@@ -442,8 +442,7 @@
 				location.reload();
 				return false;
 
-}
-
+			}
 
 			var options = '';
 			for ( i = 1; i < 7; i ++ ) {
@@ -451,7 +450,8 @@
 				var j = Math.pow( 2, i );
 				options += '<a href="#" onclick="return change(' + j + ')">' + ( j * j ) + '</a> ';
 
-}
+			}
+
 			document.getElementById( 'options' ).innerHTML = options;
 
 			var last = performance.now();
@@ -569,7 +569,7 @@
 
 				    console.error( error );
 
-	}
+				}
 
 			}
 

File diff suppressed because it is too large
+ 4 - 694
package-lock.json


+ 1 - 3
package.json

@@ -40,8 +40,7 @@
     "start": "npm run dev",
     "lint": "eslint src",
     "test": "npm run build-test && qunit test/unit/three.source.unit.js",
-    "travis": "npm run lint && npm test",
-    "editor": "electron ./editor/main.js"
+    "travis": "npm run lint && npm test"
   },
   "keywords": [
     "three",
@@ -57,7 +56,6 @@
   "homepage": "https://threejs.org/",
   "devDependencies": {
     "concurrently": "^4.1.0",
-    "electron": "^4.0.6",
     "eslint": "^5.15.0",
     "eslint-config-mdcs": "^4.2.3",
     "eslint-plugin-html": "^5.0.3",

+ 80 - 17
src/core/BufferGeometry.js

@@ -601,35 +601,59 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 
 	computeBoundingBox: function () {
 
-		if ( this.boundingBox === null ) {
+		var box = new Box3();
 
-			this.boundingBox = new Box3();
+		return function computeBoundingBox() {
 
-		}
+			if ( this.boundingBox === null ) {
 
-		var position = this.attributes.position;
+				this.boundingBox = new Box3();
 
-		if ( position !== undefined ) {
+			}
+
+			var position = this.attributes.position;
+			var morphAttributesPosition = this.morphAttributes.position;
 
-			this.boundingBox.setFromBufferAttribute( position );
+			if ( position !== undefined ) {
 
-		} else {
+				this.boundingBox.setFromBufferAttribute( position );
 
-			this.boundingBox.makeEmpty();
+				// process morph attributes if present
 
-		}
+				if ( morphAttributesPosition ) {
 
-		if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
+					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
 
-			console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
+						var morphAttribute = morphAttributesPosition[ i ];
+						box.setFromBufferAttribute( morphAttribute );
 
-		}
+						this.boundingBox.expandByPoint( box.min );
+						this.boundingBox.expandByPoint( box.max );
 
-	},
+					}
+
+				}
+
+			} else {
+
+				this.boundingBox.makeEmpty();
+
+			}
+
+			if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) {
+
+				console.error( 'THREE.BufferGeometry.computeBoundingBox: Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this );
+
+			}
+
+		};
+
+	}(),
 
 	computeBoundingSphere: function () {
 
 		var box = new Box3();
+		var boxMorphTargets = new Box3();
 		var vector = new Vector3();
 
 		return function computeBoundingSphere() {
@@ -641,28 +665,67 @@ BufferGeometry.prototype = Object.assign( Object.create( EventDispatcher.prototy
 			}
 
 			var position = this.attributes.position;
+			var morphAttributesPosition = this.morphAttributes.position;
 
 			if ( position ) {
 
+				// first, find the center of the bounding sphere
+
 				var center = this.boundingSphere.center;
 
 				box.setFromBufferAttribute( position );
+
+				// process morph attributes if present
+
+				if ( morphAttributesPosition ) {
+
+					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
+
+						var morphAttribute = morphAttributesPosition[ i ];
+						boxMorphTargets.setFromBufferAttribute( morphAttribute );
+
+						box.expandByPoint( boxMorphTargets.min );
+						box.expandByPoint( boxMorphTargets.max );
+
+					}
+
+				}
+
 				box.getCenter( center );
 
-				// hoping to find a boundingSphere with a radius smaller than the
+				// second, try to find a boundingSphere with a radius smaller than the
 				// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
 
 				var maxRadiusSq = 0;
 
 				for ( var i = 0, il = position.count; i < il; i ++ ) {
 
-					vector.x = position.getX( i );
-					vector.y = position.getY( i );
-					vector.z = position.getZ( i );
+					vector.fromBufferAttribute( position, i );
+
 					maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
 
 				}
 
+				// process morph attributes if present
+
+				if ( morphAttributesPosition ) {
+
+					for ( var i = 0, il = morphAttributesPosition.length; i < il; i ++ ) {
+
+						var morphAttribute = morphAttributesPosition[ i ];
+
+						for ( var j = 0, jl = morphAttribute.count; j < jl; j ++ ) {
+
+							vector.fromBufferAttribute( morphAttribute, i );
+
+							maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( vector ) );
+
+						}
+
+					}
+
+				}
+
 				this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
 
 				if ( isNaN( this.boundingSphere.radius ) ) {

+ 2 - 1
src/core/InstancedBufferAttribute.d.ts

@@ -37,8 +37,9 @@ export namespace GeometryUtils {
  */
 export class InstancedBufferAttribute extends BufferAttribute {
   constructor(
-    data: ArrayLike<number>,
+    array: ArrayLike<number>,
     itemSize: number,
+    normalized?: boolean,
     meshPerAttribute?: number
   );
 

+ 2 - 1
src/loaders/AnimationLoader.d.ts

@@ -1,4 +1,5 @@
 import { LoadingManager } from './LoadingManager';
+import { AnimationClip } from './../animation/AnimationClip';
 
 export class AnimationLoader {
   constructor(manager?: LoadingManager);
@@ -11,6 +12,6 @@ export class AnimationLoader {
     onProgress?: (request: ProgressEvent) => void,
     onError?: (event: ErrorEvent) => void
   ): any;
-  parse(json: any, onLoad: (response: string | ArrayBuffer) => void): void;
+  parse(json: any): AnimationClip[];
   setPath(path: string): AnimationLoader;
 }

+ 2 - 2
src/loaders/AnimationLoader.js

@@ -28,7 +28,7 @@ Object.assign( AnimationLoader.prototype, {
 
 	},
 
-	parse: function ( json, onLoad ) {
+	parse: function ( json ) {
 
 		var animations = [];
 
@@ -40,7 +40,7 @@ Object.assign( AnimationLoader.prototype, {
 
 		}
 
-		onLoad( animations );
+		return animations;
 
 	},
 

+ 1 - 1
src/renderers/webgl/WebGLTextures.js

@@ -65,7 +65,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 				console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
 
-				return useOffscreenCanvas ? canvas.transferToImageBitmap() : canvas;
+				return canvas;
 
 			} else {
 

+ 4 - 3
utils/modularize.js

@@ -44,9 +44,10 @@ function convert( path, ignoreList ) {
 
 	} );
 
-	contents = contents.replace( /THREE\.([a-zA-Z0-9]+)\./g, function ( match, p1 ) {
+	contents = contents.replace( /(\'?)THREE\.([a-zA-Z0-9]+)(\.{0,1})/g, function ( match, p1, p2, p3 ) {
 
-		if ( p1 === className ) return `${p1}.`;
+		if ( p1 === '\'' ) return match; // Inside a string
+		if ( p2 === className ) return `${p2}${p3}`;
 
 		return match;
 
@@ -83,7 +84,7 @@ function convert( path, ignoreList ) {
 
 	var keys = Object.keys( dependencies ).sort().map( value => '\n\t' + value ).toString();
 	var imports = `import {${keys}\n} from "../../../build/three.module.js";`;
-	var exports = `export { ${className} }`;
+	var exports = `export { ${className} };\n`;
 
 	var output = contents.replace( '_IMPORTS_', imports ) + '\n' + exports;
 

Some files were not shown because too many files changed in this diff