PageSourceSearch

https://cornelsen.group/wp-content/plugins/explorexr/assets/js/model-viewer-umd.js?ver=4.1.0

js cornelsen.group collected 2026-10-07 07:20:15 UTC 2,288,562 bytes, 51,086 lines download raw bytes

vendor: 14,402 bytes, lines 1-397
1(function (global, factory) {
2	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3	typeof define === 'function' && define.amd ? define(['exports'], factory) :
4	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ModelViewerElement = {}));
5})(this, (function (exports) { 'use strict';
6
7	/**
8	 * @license
9	 * Copyright 2019 Google LLC
10	 * SPDX-License-Identifier: BSD-3-Clause
11	 */ const t$2 = globalThis, e$2 = t$2.ShadowRoot && (void 0 === t$2.ShadyCSS || t$2.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, s$1 = Symbol(), o$3 = new WeakMap;
12	let n$4 = class n {
13	    get styleSheet() {
14	        let t = this.o;
15	        const s = this.t;
16	        if (e$2 && void 0 === t) {
17	            const e = void 0 !== s && 1 === s.length;
18	            e && (t = o$3.get(s)), void 0 === t && ((this.o = t = new CSSStyleSheet).replaceSync(this.cssText), e && o$3.set(s, t));
19	        }
20	        return t;
21	    }
22	    toString() {
23	        return this.cssText;
24	    }
25	    constructor(t, e, o){
26	        if (this._$cssResult$ = true, o !== s$1) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
27	        this.cssText = t, this.t = e;
28	    }
29	};
30	const r$4 = (t)=>new n$4("string" == typeof t ? t : t + "", void 0, s$1), S$1 = (s, o)=>{
31	    if (e$2) s.adoptedStyleSheets = o.map((t)=>t instanceof CSSStyleSheet ? t : t.styleSheet);
32	    else for (const e of o){
33	        const o = document.createElement("style"), n = t$2.litNonce;
34	        void 0 !== n && o.setAttribute("nonce", n), o.textContent = e.cssText, s.appendChild(o);
35	    }
36	}, c$3 = e$2 ? (t)=>t : (t)=>t instanceof CSSStyleSheet ? ((t)=>{
37	        let e = "";
38	        for (const s of t.cssRules)e += s.cssText;
39	        return r$4(e);
40	    })(t) : t;
41
42	var _Symbol, _a$a, _a1;
43	/**
44	 * @license
45	 * Copyright 2017 Google LLC
46	 * SPDX-License-Identifier: BSD-3-Clause
47	 */ const { is: i$3, defineProperty: e$1, getOwnPropertyDescriptor: r$3, getOwnPropertyNames: h$1, getOwnPropertySymbols: o$2, getPrototypeOf: n$3 } = Object, a$2 = globalThis, c$2 = a$2.trustedTypes, l$1 = c$2 ? c$2.emptyScript : "", p$1 = a$2.reactiveElementPolyfillSupport, d$1 = (t, s)=>t, u$2 = {
48	    toAttribute (t, s) {
49	        switch(s){
50	            case Boolean:
51	                t = t ? l$1 : null;
52	                break;
53	            case Object:
54	            case Array:
55	                t = null == t ? t : JSON.stringify(t);
56	        }
57	        return t;
58	    },
59	    fromAttribute (t, s) {
60	        let i = t;
61	        switch(s){
62	            case Boolean:
63	                i = null !== t;
64	                break;
65	            case Number:
66	                i = null === t ? null : Number(t);
67	                break;
68	            case Object:
69	            case Array:
70	                try {
71	                    i = JSON.parse(t);
72	                } catch (t) {
73	                    i = null;
74	                }
75	        }
76	        return i;
77	    }
78	}, f$1 = (t, s)=>!i$3(t, s), y$1 = {
79	    attribute: true,
80	    type: String,
81	    converter: u$2,
82	    reflect: false,
83	    hasChanged: f$1
84	};
85	(_Symbol = Symbol).metadata ?? (_Symbol.metadata = Symbol("metadata")), (_a$a = a$2).litPropertyMetadata ?? (_a$a.litPropertyMetadata = new WeakMap);
86	let b$1 = class b extends HTMLElement {
87	    static addInitializer(t) {
88	        this._$Ei(), (this.l ?? (this.l = [])).push(t);
89	    }
90	    static get observedAttributes() {
91	        return this.finalize(), this._$Eh && [
92	            ...this._$Eh.keys()
93	        ];
94	    }
95	    static createProperty(t, s = y$1) {
96	        if (s.state && (s.attribute = false), this._$Ei(), this.elementProperties.set(t, s), !s.noAccessor) {
97	            const i = Symbol(), r = this.getPropertyDescriptor(t, i, s);
98	            void 0 !== r && e$1(this.prototype, t, r);
99	        }
100	    }
101	    static getPropertyDescriptor(t, s, i) {
102	        const { get: e, set: h } = r$3(this.prototype, t) ?? {
103	            get () {
104	                return this[s];
105	            },
106	            set (t) {
107	                this[s] = t;
108	            }
109	        };
110	        return {
111	            get () {
112	                return e?.call(this);
113	            },
114	            set (s) {
115	                const r = e?.call(this);
116	                h.call(this, s), this.requestUpdate(t, r, i);
117	            },
118	            configurable: true,
119	            enumerable: true
120	        };
121	    }
122	    static getPropertyOptions(t) {
123	        return this.elementProperties.get(t) ?? y$1;
124	    }
125	    static _$Ei() {
126	        if (this.hasOwnProperty(d$1("elementProperties"))) return;
127	        const t = n$3(this);
128	        t.finalize(), void 0 !== t.l && (this.l = [
129	            ...t.l
130	        ]), this.elementProperties = new Map(t.elementProperties);
131	    }
132	    static finalize() {
133	        if (this.hasOwnProperty(d$1("finalized"))) return;
134	        if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d$1("properties"))) {
135	            const t = this.properties, s = [
136	                ...h$1(t),
137	                ...o$2(t)
138	            ];
139	            for (const i of s)this.createProperty(i, t[i]);
140	        }
141	        const t = this[Symbol.metadata];
142	        if (null !== t) {
143	            const s = litPropertyMetadata.get(t);
144	            if (void 0 !== s) for (const [t, i] of s)this.elementProperties.set(t, i);
145	        }
146	        this._$Eh = new Map;
147	        for (const [t, s] of this.elementProperties){
148	            const i = this._$Eu(t, s);
149	            void 0 !== i && this._$Eh.set(i, t);
150	        }
151	        this.elementStyles = this.finalizeStyles(this.styles);
152	    }
153	    static finalizeStyles(s) {
154	        const i = [];
155	        if (Array.isArray(s)) {
156	            const e = new Set(s.flat(1 / 0).reverse());
157	            for (const s of e)i.unshift(c$3(s));
158	        } else void 0 !== s && i.push(c$3(s));
159	        return i;
160	    }
161	    static _$Eu(t, s) {
162	        const i = s.attribute;
163	        return false === i ? void 0 : "string" == typeof i ? i : "string" == typeof t ? t.toLowerCase() : void 0;
164	    }
165	    _$Ev() {
166	        this._$ES = new Promise((t)=>this.enableUpdating = t), this._$AL = new Map, this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t)=>t(this));
167	    }
168	    addController(t) {
169	        (this._$EO ?? (this._$EO = new Set)).add(t), void 0 !== this.renderRoot && this.isConnected && t.hostConnected?.();
170	    }
171	    removeController(t) {
172	        this._$EO?.delete(t);
173	    }
174	    _$E_() {
175	        const t = new Map, s = this.constructor.elementProperties;
176	        for (const i of s.keys())this.hasOwnProperty(i) && (t.set(i, this[i]), delete this[i]);
177	        t.size > 0 && (this._$Ep = t);
178	    }
179	    createRenderRoot() {
180	        const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
181	        return S$1(t, this.constructor.elementStyles), t;
182	    }
183	    connectedCallback() {
184	        this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this.enableUpdating(true), this._$EO?.forEach((t)=>t.hostConnected?.());
185	    }
186	    enableUpdating(t) {}
187	    disconnectedCallback() {
188	        this._$EO?.forEach((t)=>t.hostDisconnected?.());
189	    }
190	    attributeChangedCallback(t, s, i) {
191	        this._$AK(t, i);
192	    }
193	    _$EC(t, s) {
194	        const i = this.constructor.elementProperties.get(t), e = this.constructor._$Eu(t, i);
195	        if (void 0 !== e && true === i.reflect) {
196	            const r = (void 0 !== i.converter?.toAttribute ? i.converter : u$2).toAttribute(s, i.type);
197	            this._$Em = t, null == r ? this.removeAttribute(e) : this.setAttribute(e, r), this._$Em = null;
198	        }
199	    }
200	    _$AK(t, s) {
201	        const i = this.constructor, e = i._$Eh.get(t);
202	        if (void 0 !== e && this._$Em !== e) {
203	            const t = i.getPropertyOptions(e), r = "function" == typeof t.converter ? {
204	                fromAttribute: t.converter
205	            } : void 0 !== t.converter?.fromAttribute ? t.converter : u$2;
206	            this._$Em = e, this[e] = r.fromAttribute(s, t.type), this._$Em = null;
207	        }
208	    }
209	    requestUpdate(t, s, i) {
210	        if (void 0 !== t) {
211	            if (i ?? (i = this.constructor.getPropertyOptions(t)), !(i.hasChanged ?? f$1)(this[t], s)) return;
212	            this.P(t, s, i);
213	        }
214	        false === this.isUpdatePending && (this._$ES = this._$ET());
215	    }
216	    P(t, s, i) {
217	        this._$AL.has(t) || this._$AL.set(t, s), true === i.reflect && this._$Em !== t && (this._$Ej ?? (this._$Ej = new Set)).add(t);
218	    }
219	    async _$ET() {
220	        this.isUpdatePending = true;
221	        try {
222	            await this._$ES;
223	        } catch (t) {
224	            Promise.reject(t);
225	        }
226	        const t = this.scheduleUpdate();
227	        return null != t && await t, !this.isUpdatePending;
228	    }
229	    scheduleUpdate() {
230	        return this.performUpdate();
231	    }
232	    performUpdate() {
233	        if (!this.isUpdatePending) return;
234	        if (!this.hasUpdated) {
235	            if (this.renderRoot ?? (this.renderRoot = this.createRenderRoot()), this._$Ep) {
236	                for (const [t, s] of this._$Ep)this[t] = s;
237	                this._$Ep = void 0;
238	            }
239	            const t = this.constructor.elementProperties;
240	            if (t.size > 0) for (const [s, i] of t) true !== i.wrapped || this._$AL.has(s) || void 0 === this[s] || this.P(s, this[s], i);
241	        }
242	        let t = false;
243	        const s = this._$AL;
244	        try {
245	            t = this.shouldUpdate(s), t ? (this.willUpdate(s), this._$EO?.forEach((t)=>t.hostUpdate?.()), this.update(s)) : this._$EU();
246	        } catch (s) {
247	            throw t = false, this._$EU(), s;
248	        }
249	        t && this._$AE(s);
250	    }
251	    willUpdate(t) {}
252	    _$AE(t) {
253	        this._$EO?.forEach((t)=>t.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t)), this.updated(t);
254	    }
255	    _$EU() {
256	        this._$AL = new Map, this.isUpdatePending = false;
257	    }
258	    get updateComplete() {
259	        return this.getUpdateComplete();
260	    }
261	    getUpdateComplete() {
262	        return this._$ES;
263	    }
264	    shouldUpdate(t) {
265	        return true;
266	    }
267	    update(t) {
268	        this._$Ej && (this._$Ej = this._$Ej.forEach((t)=>this._$EC(t, this[t]))), this._$EU();
269	    }
270	    updated(t) {}
271	    firstUpdated(t) {}
272	    constructor(){
273	        super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev();
274	    }
275	};
276	b$1.elementStyles = [], b$1.shadowRootOptions = {
277	    mode: "open"
278	}, b$1[d$1("elementProperties")] = new Map, b$1[d$1("finalized")] = new Map, p$1?.({
279	    ReactiveElement: b$1
280	}), ((_a1 = a$2).reactiveElementVersions ?? (_a1.reactiveElementVersions = [])).push("2.0.4");
281
282	/**
283	 * @license
284	 * Copyright 2017 Google LLC
285	 * SPDX-License-Identifier: BSD-3-Clause
286	 */ const o$1 = {
287	    attribute: true,
288	    type: String,
289	    converter: u$2,
290	    reflect: false,
291	    hasChanged: f$1
292	}, r$2 = (t = o$1, e, r)=>{
293	    const { kind: n, metadata: i } = r;
294	    let s = globalThis.litPropertyMetadata.get(i);
295	    if (void 0 === s && globalThis.litPropertyMetadata.set(i, s = new Map), s.set(r.name, t), "accessor" === n) {
296	        const { name: o } = r;
297	        return {
298	            set (r) {
299	                const n = e.get.call(this);
300	                e.set.call(this, r), this.requestUpdate(o, n, t);
301	            },
302	            init (e) {
303	                return void 0 !== e && this.P(o, void 0, t), e;
304	            }
305	        };
306	    }
307	    if ("setter" === n) {
308	        const { name: o } = r;
309	        return function(r) {
310	            const n = this[o];
311	            e.call(this, r), this.requestUpdate(o, n, t);
312	        };
313	    }
314	    throw Error("Unsupported decorator location: " + n);
315	};
316	function n$2(t) {
317	    return (e, o)=>"object" == typeof o ? r$2(t, e, o) : ((t, e, o)=>{
318	            const r = e.hasOwnProperty(o);
319	            return e.constructor.createProperty(o, r ? {
320	                ...t,
321	                wrapped: true
322	            } : t), r ? Object.getOwnPropertyDescriptor(e, o) : void 0;
323	        })(t, e, o);
324	}
325
326	/**
327	 * @license
328	 * Copyright 2010-2025 Three.js Authors
329	 * SPDX-License-Identifier: MIT
330	 */ const REVISION = '174';
331	const CullFaceNone = 0;
332	const CullFaceBack = 1;
333	const CullFaceFront = 2;
334	const PCFShadowMap = 1;
335	const PCFSoftShadowMap = 2;
336	const VSMShadowMap = 3;
337	const FrontSide = 0;
338	const BackSide = 1;
339	const DoubleSide = 2;
340	const NoBlending = 0;
341	const NormalBlending = 1;
342	const AdditiveBlending = 2;
343	const SubtractiveBlending = 3;
344	const MultiplyBlending = 4;
345	const CustomBlending = 5;
346	const AddEquation = 100;
347	const SubtractEquation = 101;
348	const ReverseSubtractEquation = 102;
349	const MinEquation = 103;
350	const MaxEquation = 104;
351	const ZeroFactor = 200;
352	const OneFactor = 201;
353	const SrcColorFactor = 202;
354	const OneMinusSrcColorFactor = 203;
355	const SrcAlphaFactor = 204;
356	const OneMinusSrcAlphaFactor = 205;
357	const DstAlphaFactor = 206;
358	const OneMinusDstAlphaFactor = 207;
359	const DstColorFactor = 208;
360	const OneMinusDstColorFactor = 209;
361	const SrcAlphaSaturateFactor = 210;
362	const ConstantColorFactor = 211;
363	const OneMinusConstantColorFactor = 212;
364	const ConstantAlphaFactor = 213;
365	const OneMinusConstantAlphaFactor = 214;
366	const NeverDepth = 0;
367	const AlwaysDepth = 1;
368	const LessDepth = 2;
369	const LessEqualDepth = 3;
370	const EqualDepth = 4;
371	const GreaterEqualDepth = 5;
372	const GreaterDepth = 6;
373	const NotEqualDepth = 7;
374	const MultiplyOperation = 0;
375	const MixOperation = 1;
376	const AddOperation = 2;
377	const NoToneMapping = 0;
378	const LinearToneMapping = 1;
379	const ReinhardToneMapping = 2;
380	const CineonToneMapping = 3;
381	const ACESFilmicToneMapping = 4;
382	const CustomToneMapping = 5;
383	const AgXToneMapping = 6;
384	const NeutralToneMapping = 7;
385	const AttachedBindMode = 'attached';
386	const DetachedBindMode = 'detached';
387	const UVMapping = 300;
388	const CubeReflectionMapping = 301;
389	const CubeRefractionMapping = 302;
390	const EquirectangularReflectionMapping = 303;
391	const EquirectangularRefractionMapping = 304;
392	const CubeUVReflectionMapping = 306;
393	const RepeatWrapping = 1000;
394	const ClampToEdgeWrapping = 1001;
395	const MirroredRepeatWrapping = 1002;
396	const NearestFilter = 1003;
397	const NearestMipmapNearestFilter = 1004;
vendor: 10,977 bytes, lines 398-876
398	const NearestMipmapLinearFilter = 1005;
399	const LinearFilter = 1006;
400	const LinearMipmapNearestFilter = 1007;
401	const LinearMipmapLinearFilter = 1008;
402	const LinearMipMapLinearFilter = 1008;
403	const UnsignedByteType = 1009;
404	const ByteType = 1010;
405	const ShortType = 1011;
406	const UnsignedShortType = 1012;
407	const IntType = 1013;
408	const UnsignedIntType = 1014;
409	const FloatType = 1015;
410	const HalfFloatType = 1016;
411	const UnsignedShort4444Type = 1017;
412	const UnsignedShort5551Type = 1018;
413	const UnsignedInt248Type = 1020;
414	const UnsignedInt5999Type = 35902;
415	const AlphaFormat = 1021;
416	const RGBFormat = 1022;
417	const RGBAFormat = 1023;
418	const LuminanceFormat = 1024;
419	const LuminanceAlphaFormat = 1025;
420	const DepthFormat = 1026;
421	const DepthStencilFormat = 1027;
422	const RedFormat = 1028;
423	const RedIntegerFormat = 1029;
424	const RGFormat = 1030;
425	const RGIntegerFormat = 1031;
426	const RGBAIntegerFormat = 1033;
427	const RGB_S3TC_DXT1_Format = 33776;
428	const RGBA_S3TC_DXT1_Format = 33777;
429	const RGBA_S3TC_DXT3_Format = 33778;
430	const RGBA_S3TC_DXT5_Format = 33779;
431	const RGB_PVRTC_4BPPV1_Format = 35840;
432	const RGB_PVRTC_2BPPV1_Format = 35841;
433	const RGBA_PVRTC_4BPPV1_Format = 35842;
434	const RGBA_PVRTC_2BPPV1_Format = 35843;
435	const RGB_ETC1_Format = 36196;
436	const RGB_ETC2_Format = 37492;
437	const RGBA_ETC2_EAC_Format = 37496;
438	const RGBA_ASTC_4x4_Format = 37808;
439	const RGBA_ASTC_5x4_Format = 37809;
440	const RGBA_ASTC_5x5_Format = 37810;
441	const RGBA_ASTC_6x5_Format = 37811;
442	const RGBA_ASTC_6x6_Format = 37812;
443	const RGBA_ASTC_8x5_Format = 37813;
444	const RGBA_ASTC_8x6_Format = 37814;
445	const RGBA_ASTC_8x8_Format = 37815;
446	const RGBA_ASTC_10x5_Format = 37816;
447	const RGBA_ASTC_10x6_Format = 37817;
448	const RGBA_ASTC_10x8_Format = 37818;
449	const RGBA_ASTC_10x10_Format = 37819;
450	const RGBA_ASTC_12x10_Format = 37820;
451	const RGBA_ASTC_12x12_Format = 37821;
452	const RGBA_BPTC_Format = 36492;
453	const RGB_BPTC_SIGNED_Format = 36494;
454	const RGB_BPTC_UNSIGNED_Format = 36495;
455	const RED_RGTC1_Format = 36283;
456	const SIGNED_RED_RGTC1_Format = 36284;
457	const RED_GREEN_RGTC2_Format = 36285;
458	const SIGNED_RED_GREEN_RGTC2_Format = 36286;
459	const LoopOnce = 2200;
460	const LoopRepeat = 2201;
461	const LoopPingPong = 2202;
462	const InterpolateDiscrete = 2300;
463	const InterpolateLinear = 2301;
464	const InterpolateSmooth = 2302;
465	const ZeroCurvatureEnding = 2400;
466	const ZeroSlopeEnding = 2401;
467	const WrapAroundEnding = 2402;
468	const NormalAnimationBlendMode = 2500;
469	const AdditiveAnimationBlendMode = 2501;
470	const TrianglesDrawMode = 0;
471	const TriangleStripDrawMode = 1;
472	const TriangleFanDrawMode = 2;
473	const BasicDepthPacking = 3200;
474	const RGBADepthPacking = 3201;
475	const TangentSpaceNormalMap = 0;
476	const ObjectSpaceNormalMap = 1;
477	// Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.
478	const NoColorSpace = '';
479	const SRGBColorSpace = 'srgb';
480	const LinearSRGBColorSpace = 'srgb-linear';
481	const LinearTransfer = 'linear';
482	const SRGBTransfer = 'srgb';
483	const KeepStencilOp = 7680;
484	const AlwaysStencilFunc = 519;
485	const NeverCompare = 512;
486	const LessCompare = 513;
487	const EqualCompare = 514;
488	const LessEqualCompare = 515;
489	const GreaterCompare = 516;
490	const NotEqualCompare = 517;
491	const GreaterEqualCompare = 518;
492	const AlwaysCompare = 519;
493	const StaticDrawUsage = 35044;
494	const GLSL3 = '300 es';
495	const WebGLCoordinateSystem = 2000;
496	const WebGPUCoordinateSystem = 2001;
497	/**
498	 * This modules allows to dispatch event objects on custom JavaScript objects.
499	 *
500	 * Main repository: [eventdispatcher.js]{@link https://github.com/mrdoob/eventdispatcher.js/}
501	 *
502	 * Code Example:
503	 * ```js
504	 * class Car extends EventDispatcher {
505	 * 	start() {
506	 *		this.dispatchEvent( { type: 'start', message: 'vroom vroom!' } );
507	 *	}
508	 *};
509	 *
510	 * // Using events with the custom object
511	 * const car = new Car();
512	 * car.addEventListener( 'start', function ( event ) {
513	 * 	alert( event.message );
514	 * } );
515	 *
516	 * car.start();
517	 * ```
518	 */ class EventDispatcher {
519	    /**
520		 * Adds the given event listener to the given event type.
521		 *
522		 * @param {string} type - The type of event to listen to.
523		 * @param {Function} listener - The function that gets called when the event is fired.
524		 */ addEventListener(type, listener) {
525	        if (this._listeners === undefined) this._listeners = {};
526	        const listeners = this._listeners;
527	        if (listeners[type] === undefined) {
528	            listeners[type] = [];
529	        }
530	        if (listeners[type].indexOf(listener) === -1) {
531	            listeners[type].push(listener);
532	        }
533	    }
534	    /**
535		 * Returns `true` if the given event listener has been added to the given event type.
536		 *
537		 * @param {string} type - The type of event.
538		 * @param {Function} listener - The listener to check.
539		 * @return {boolean} Whether the given event listener has been added to the given event type.
540		 */ hasEventListener(type, listener) {
541	        const listeners = this._listeners;
542	        if (listeners === undefined) return false;
543	        return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1;
544	    }
545	    /**
546		 * Removes the given event listener from the given event type.
547		 *
548		 * @param {string} type - The type of event.
549		 * @param {Function} listener - The listener to remove.
550		 */ removeEventListener(type, listener) {
551	        const listeners = this._listeners;
552	        if (listeners === undefined) return;
553	        const listenerArray = listeners[type];
554	        if (listenerArray !== undefined) {
555	            const index = listenerArray.indexOf(listener);
556	            if (index !== -1) {
557	                listenerArray.splice(index, 1);
558	            }
559	        }
560	    }
561	    /**
562		 * Dispatches an event object.
563		 *
564		 * @param {Object} event - The event that gets fired.
565		 */ dispatchEvent(event) {
566	        const listeners = this._listeners;
567	        if (listeners === undefined) return;
568	        const listenerArray = listeners[event.type];
569	        if (listenerArray !== undefined) {
570	            event.target = this;
571	            // Make a copy, in case listeners are removed while iterating.
572	            const array = listenerArray.slice(0);
573	            for(let i = 0, l = array.length; i < l; i++){
574	                array[i].call(this, event);
575	            }
576	            event.target = null;
577	        }
578	    }
579	}
580	const _lut = [
581	    '00',
582	    '01',
583	    '02',
584	    '03',
585	    '04',
586	    '05',
587	    '06',
588	    '07',
589	    '08',
590	    '09',
591	    '0a',
592	    '0b',
593	    '0c',
594	    '0d',
595	    '0e',
596	    '0f',
597	    '10',
598	    '11',
599	    '12',
600	    '13',
601	    '14',
602	    '15',
603	    '16',
604	    '17',
605	    '18',
606	    '19',
607	    '1a',
608	    '1b',
609	    '1c',
610	    '1d',
611	    '1e',
612	    '1f',
613	    '20',
614	    '21',
615	    '22',
616	    '23',
617	    '24',
618	    '25',
619	    '26',
620	    '27',
621	    '28',
622	    '29',
623	    '2a',
624	    '2b',
625	    '2c',
626	    '2d',
627	    '2e',
628	    '2f',
629	    '30',
630	    '31',
631	    '32',
632	    '33',
633	    '34',
634	    '35',
635	    '36',
636	    '37',
637	    '38',
638	    '39',
639	    '3a',
640	    '3b',
641	    '3c',
642	    '3d',
643	    '3e',
644	    '3f',
645	    '40',
646	    '41',
647	    '42',
648	    '43',
649	    '44',
650	    '45',
651	    '46',
652	    '47',
653	    '48',
654	    '49',
655	    '4a',
656	    '4b',
657	    '4c',
658	    '4d',
659	    '4e',
660	    '4f',
661	    '50',
662	    '51',
663	    '52',
664	    '53',
665	    '54',
666	    '55',
667	    '56',
668	    '57',
669	    '58',
670	    '59',
671	    '5a',
672	    '5b',
673	    '5c',
674	    '5d',
675	    '5e',
676	    '5f',
677	    '60',
678	    '61',
679	    '62',
680	    '63',
681	    '64',
682	    '65',
683	    '66',
684	    '67',
685	    '68',
686	    '69',
687	    '6a',
688	    '6b',
689	    '6c',
690	    '6d',
691	    '6e',
692	    '6f',
693	    '70',
694	    '71',
695	    '72',
696	    '73',
697	    '74',
698	    '75',
699	    '76',
700	    '77',
701	    '78',
702	    '79',
703	    '7a',
704	    '7b',
705	    '7c',
706	    '7d',
707	    '7e',
708	    '7f',
709	    '80',
710	    '81',
711	    '82',
712	    '83',
713	    '84',
714	    '85',
715	    '86',
716	    '87',
717	    '88',
718	    '89',
719	    '8a',
720	    '8b',
721	    '8c',
722	    '8d',
723	    '8e',
724	    '8f',
725	    '90',
726	    '91',
727	    '92',
728	    '93',
729	    '94',
730	    '95',
731	    '96',
732	    '97',
733	    '98',
734	    '99',
735	    '9a',
736	    '9b',
737	    '9c',
738	    '9d',
739	    '9e',
740	    '9f',
741	    'a0',
742	    'a1',
743	    'a2',
744	    'a3',
745	    'a4',
746	    'a5',
747	    'a6',
748	    'a7',
749	    'a8',
750	    'a9',
751	    'aa',
752	    'ab',
753	    'ac',
754	    'ad',
755	    'ae',
756	    'af',
757	    'b0',
758	    'b1',
759	    'b2',
760	    'b3',
761	    'b4',
762	    'b5',
763	    'b6',
764	    'b7',
765	    'b8',
766	    'b9',
767	    'ba',
768	    'bb',
769	    'bc',
770	    'bd',
771	    'be',
772	    'bf',
773	    'c0',
774	    'c1',
775	    'c2',
776	    'c3',
777	    'c4',
778	    'c5',
779	    'c6',
780	    'c7',
781	    'c8',
782	    'c9',
783	    'ca',
784	    'cb',
785	    'cc',
786	    'cd',
787	    'ce',
788	    'cf',
789	    'd0',
790	    'd1',
791	    'd2',
792	    'd3',
793	    'd4',
794	    'd5',
795	    'd6',
796	    'd7',
797	    'd8',
798	    'd9',
799	    'da',
800	    'db',
801	    'dc',
802	    'dd',
803	    'de',
804	    'df',
805	    'e0',
806	    'e1',
807	    'e2',
808	    'e3',
809	    'e4',
810	    'e5',
811	    'e6',
812	    'e7',
813	    'e8',
814	    'e9',
815	    'ea',
816	    'eb',
817	    'ec',
818	    'ed',
819	    'ee',
820	    'ef',
821	    'f0',
822	    'f1',
823	    'f2',
824	    'f3',
825	    'f4',
826	    'f5',
827	    'f6',
828	    'f7',
829	    'f8',
830	    'f9',
831	    'fa',
832	    'fb',
833	    'fc',
834	    'fd',
835	    'fe',
836	    'ff'
837	];
838	let _seed = 1234567;
839	const DEG2RAD = Math.PI / 180;
840	const RAD2DEG = 180 / Math.PI;
841	/**
842	 * Generate a [UUID]{@link https://en.wikipedia.org/wiki/Universally_unique_identifier}
843	 * (universally unique identifier).
844	 *
845	 * @return {string} The UUID.
846	 */ function generateUUID() {
847	    // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
848	    const d0 = Math.random() * 0xffffffff | 0;
849	    const d1 = Math.random() * 0xffffffff | 0;
850	    const d2 = Math.random() * 0xffffffff | 0;
851	    const d3 = Math.random() * 0xffffffff | 0;
852	    const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff];
853	    // .toLowerCase() here flattens concatenated strings to save heap memory space.
854	    return uuid.toLowerCase();
855	}
856	/**
857	 * Clamps the given value between min and max.
858	 *
859	 * @param {number} value - The value to clamp.
860	 * @param {number} min - The min value.
861	 * @param {number} max - The max value.
862	 * @return {number} The clamped value.
863	 */ function clamp$1(value, min, max) {
864	    return Math.max(min, Math.min(max, value));
865	}
866	/**
867	 * Computes the Euclidean modulo of the given parameters that
868	 * is `( ( n % m ) + m ) % m`.
869	 *
870	 * @param {number} n - The first parameter.
871	 * @param {number} m - The second parameter.
872	 * @return {number} The Euclidean modulo.
873	 */ function euclideanModulo(n, m) {
874	    // https://en.wikipedia.org/wiki/Modulo_operation
875	    return (n % m + m) % m;
876	}
vendor: 5,793 bytes, lines 877-1026
877	/**
878	 * Performs a linear mapping from range `<a1, a2>` to range `<b1, b2>`
879	 * for the given value.
880	 *
881	 * @param {number} x - The value to be mapped.
882	 * @param {number} a1 - Minimum value for range A.
883	 * @param {number} a2 - Maximum value for range A.
884	 * @param {number} b1 - Minimum value for range B.
885	 * @param {number} b2 - Maximum value for range B.
886	 * @return {number} The mapped value.
887	 */ function mapLinear(x, a1, a2, b1, b2) {
888	    return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
889	}
890	/**
891	 * Returns the percentage in the closed interval `[0, 1]` of the given value
892	 * between the start and end point.
893	 *
894	 * @param {number} x - The start point
895	 * @param {number} y - The end point.
896	 * @param {number} value - A value between start and end.
897	 * @return {number} The interpolation factor.
898	 */ function inverseLerp(x, y, value) {
899	    // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/
900	    if (x !== y) {
901	        return (value - x) / (y - x);
902	    } else {
903	        return 0;
904	    }
905	}
906	/**
907	 * Returns a value linearly interpolated from two known points based on the given interval -
908	 * `t = 0` will return `x` and `t = 1` will return `y`.
909	 *
910	 * @param {number} x - The start point
911	 * @param {number} y - The end point.
912	 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
913	 * @return {number} The interpolated value.
914	 */ function lerp$1(x, y, t) {
915	    return (1 - t) * x + t * y;
916	}
917	/**
918	 * Smoothly interpolate a number from `x` to `y` in  a spring-like manner using a delta
919	 * time to maintain frame rate independent movement. For details, see
920	 * [Frame rate independent damping using lerp]{@link http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/}.
921	 *
922	 * @param {number} x - The current point.
923	 * @param {number} y - The target point.
924	 * @param {number} lambda - A higher lambda value will make the movement more sudden,
925	 * and a lower value will make the movement more gradual.
926	 * @param {number} dt - Delta time in seconds.
927	 * @return {number} The interpolated value.
928	 */ function damp(x, y, lambda, dt) {
929	    return lerp$1(x, y, 1 - Math.exp(-lambda * dt));
930	}
931	/**
932	 * Returns a value that alternates between `0` and the given `length` parameter.
933	 *
934	 * @param {number} x - The value to pingpong.
935	 * @param {number} [length=1] - The positive value the function will pingpong to.
936	 * @return {number} The alternated value.
937	 */ function pingpong(x, length = 1) {
938	    // https://www.desmos.com/calculator/vcsjnyz7x4
939	    return length - Math.abs(euclideanModulo(x, length * 2) - length);
940	}
941	/**
942	 * Returns a value in the range `[0,1]` that represents the percentage that `x` has
943	 * moved between `min` and `max`, but smoothed or slowed down the closer `x` is to
944	 * the `min` and `max`.
945	 *
946	 * See [Smoothstep]{@link http://en.wikipedia.org/wiki/Smoothstep} for more details.
947	 *
948	 * @param {number} x - The value to evaluate based on its position between min and max.
949	 * @param {number} min - The min value. Any x value below min will be `0`.
950	 * @param {number} max - The max value. Any x value above max will be `1`.
951	 * @return {number} The alternated value.
952	 */ function smoothstep(x, min, max) {
953	    if (x <= min) return 0;
954	    if (x >= max) return 1;
955	    x = (x - min) / (max - min);
956	    return x * x * (3 - 2 * x);
957	}
958	/**
959	 * A [variation on smoothstep]{@link https://en.wikipedia.org/wiki/Smoothstep#Variations}
960	 * that has zero 1st and 2nd order derivatives at x=0 and x=1.
961	 *
962	 * @param {number} x - The value to evaluate based on its position between min and max.
963	 * @param {number} min - The min value. Any x value below min will be `0`.
964	 * @param {number} max - The max value. Any x value above max will be `1`.
965	 * @return {number} The alternated value.
966	 */ function smootherstep(x, min, max) {
967	    if (x <= min) return 0;
968	    if (x >= max) return 1;
969	    x = (x - min) / (max - min);
970	    return x * x * x * (x * (x * 6 - 15) + 10);
971	}
972	/**
973	 * Returns a random integer from `<low, high>` interval.
974	 *
975	 * @param {number} low - The lower value boundary.
976	 * @param {number} high - The upper value boundary
977	 * @return {number} A random integer.
978	 */ function randInt(low, high) {
979	    return low + Math.floor(Math.random() * (high - low + 1));
980	}
981	/**
982	 * Returns a random float from `<low, high>` interval.
983	 *
984	 * @param {number} low - The lower value boundary.
985	 * @param {number} high - The upper value boundary
986	 * @return {number} A random float.
987	 */ function randFloat(low, high) {
988	    return low + Math.random() * (high - low);
989	}
990	/**
991	 * Returns a random integer from `<-range/2, range/2>` interval.
992	 *
993	 * @param {number} range - Defines the value range.
994	 * @return {number} A random float.
995	 */ function randFloatSpread(range) {
996	    return range * (0.5 - Math.random());
997	}
998	/**
999	 * Returns a deterministic pseudo-random float in the interval `[0, 1]`.
1000	 *
1001	 * @param {number} [s] - The integer seed.
1002	 * @return {number} A random float.
1003	 */ function seededRandom(s) {
1004	    if (s !== undefined) _seed = s;
1005	    // Mulberry32 generator
1006	    let t = _seed += 0x6D2B79F5;
1007	    t = Math.imul(t ^ t >>> 15, t | 1);
1008	    t ^= t + Math.imul(t ^ t >>> 7, t | 61);
1009	    return ((t ^ t >>> 14) >>> 0) / 4294967296;
1010	}
1011	/**
1012	 * Converts degrees to radians.
1013	 *
1014	 * @param {number} degrees - A value in degrees.
1015	 * @return {number} The converted value in radians.
1016	 */ function degToRad(degrees) {
1017	    return degrees * DEG2RAD;
1018	}
1019	/**
1020	 * Converts radians to degrees.
1021	 *
1022	 * @param {number} radians - A value in radians.
1023	 * @return {number} The converted value in degrees.
1024	 */ function radToDeg(radians) {
1025	    return radians * RAD2DEG;
1026	}
vendor: 39,990 bytes, lines 1027-2191
1027	/**
1028	 * Returns `true` if the given number is a power of two.
1029	 *
1030	 * @param {number} value - The value to check.
1031	 * @return {boolean} Whether the given number is a power of two or not.
1032	 */ function isPowerOfTwo(value) {
1033	    return (value & value - 1) === 0 && value !== 0;
1034	}
1035	/**
1036	 * Returns the smallest power of two that is greater than or equal to the given number.
1037	 *
1038	 * @param {number} value - The value to find a POT for.
1039	 * @return {number} The smallest power of two that is greater than or equal to the given number.
1040	 */ function ceilPowerOfTwo(value) {
1041	    return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
1042	}
1043	/**
1044	 * Returns the largest power of two that is less than or equal to the given number.
1045	 *
1046	 * @param {number} value - The value to find a POT for.
1047	 * @return {number} The largest power of two that is less than or equal to the given number.
1048	 */ function floorPowerOfTwo(value) {
1049	    return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
1050	}
1051	/**
1052	 * Sets the given quaternion from the [Intrinsic Proper Euler Angles]{@link https://en.wikipedia.org/wiki/Euler_angles}
1053	 * defined by the given angles and order.
1054	 *
1055	 * Rotations are applied to the axes in the order specified by order:
1056	 * rotation by angle `a` is applied first, then by angle `b`, then by angle `c`.
1057	 *
1058	 * @param {Quaternion} q - The quaternion to set.
1059	 * @param {number} a - The rotation applied to the first axis, in radians.
1060	 * @param {number} b - The rotation applied to the second axis, in radians.
1061	 * @param {number} c - The rotation applied to the third axis, in radians.
1062	 * @param {('XYX'|'XZX'|'YXY'|'YZY'|'ZXZ'|'ZYZ')} order - A string specifying the axes order.
1063	 */ function setQuaternionFromProperEuler(q, a, b, c, order) {
1064	    const cos = Math.cos;
1065	    const sin = Math.sin;
1066	    const c2 = cos(b / 2);
1067	    const s2 = sin(b / 2);
1068	    const c13 = cos((a + c) / 2);
1069	    const s13 = sin((a + c) / 2);
1070	    const c1_3 = cos((a - c) / 2);
1071	    const s1_3 = sin((a - c) / 2);
1072	    const c3_1 = cos((c - a) / 2);
1073	    const s3_1 = sin((c - a) / 2);
1074	    switch(order){
1075	        case 'XYX':
1076	            q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13);
1077	            break;
1078	        case 'YZY':
1079	            q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13);
1080	            break;
1081	        case 'ZXZ':
1082	            q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13);
1083	            break;
1084	        case 'XZX':
1085	            q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13);
1086	            break;
1087	        case 'YXY':
1088	            q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13);
1089	            break;
1090	        case 'ZYZ':
1091	            q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13);
1092	            break;
1093	        default:
1094	            console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order);
1095	    }
1096	}
1097	/**
1098	 * Denormalizes the given value according to the given typed array.
1099	 *
1100	 * @param {number} value - The value to denormalize.
1101	 * @param {TypedArray} array - The typed array that defines the data type of the value.
1102	 * @return {number} The denormalize (float) value in the range `[0,1]`.
1103	 */ function denormalize(value, array) {
1104	    switch(array.constructor){
1105	        case Float32Array:
1106	            return value;
1107	        case Uint32Array:
1108	            return value / 4294967295.0;
1109	        case Uint16Array:
1110	            return value / 65535.0;
1111	        case Uint8Array:
1112	            return value / 255.0;
1113	        case Int32Array:
1114	            return Math.max(value / 2147483647.0, -1);
1115	        case Int16Array:
1116	            return Math.max(value / 32767.0, -1);
1117	        case Int8Array:
1118	            return Math.max(value / 127.0, -1);
1119	        default:
1120	            throw new Error('Invalid component type.');
1121	    }
1122	}
1123	/**
1124	 * Normalizes the given value according to the given typed array.
1125	 *
1126	 * @param {number} value - The float value in the range `[0,1]` to normalize.
1127	 * @param {TypedArray} array - The typed array that defines the data type of the value.
1128	 * @return {number} The normalize value.
1129	 */ function normalize(value, array) {
1130	    switch(array.constructor){
1131	        case Float32Array:
1132	            return value;
1133	        case Uint32Array:
1134	            return Math.round(value * 4294967295.0);
1135	        case Uint16Array:
1136	            return Math.round(value * 65535.0);
1137	        case Uint8Array:
1138	            return Math.round(value * 255.0);
1139	        case Int32Array:
1140	            return Math.round(value * 2147483647.0);
1141	        case Int16Array:
1142	            return Math.round(value * 32767.0);
1143	        case Int8Array:
1144	            return Math.round(value * 127.0);
1145	        default:
1146	            throw new Error('Invalid component type.');
1147	    }
1148	}
1149	const MathUtils = {
1150	    DEG2RAD: DEG2RAD,
1151	    RAD2DEG: RAD2DEG,
1152	    generateUUID: generateUUID,
1153	    clamp: clamp$1,
1154	    euclideanModulo: euclideanModulo,
1155	    mapLinear: mapLinear,
1156	    inverseLerp: inverseLerp,
1157	    lerp: lerp$1,
1158	    damp: damp,
1159	    pingpong: pingpong,
1160	    smoothstep: smoothstep,
1161	    smootherstep: smootherstep,
1162	    randInt: randInt,
1163	    randFloat: randFloat,
1164	    randFloatSpread: randFloatSpread,
1165	    seededRandom: seededRandom,
1166	    degToRad: degToRad,
1167	    radToDeg: radToDeg,
1168	    isPowerOfTwo: isPowerOfTwo,
1169	    ceilPowerOfTwo: ceilPowerOfTwo,
1170	    floorPowerOfTwo: floorPowerOfTwo,
1171	    setQuaternionFromProperEuler: setQuaternionFromProperEuler,
1172	    normalize: normalize,
1173	    denormalize: denormalize
1174	};
1175	/**
1176	 * Class representing a 2D vector. A 2D vector is an ordered pair of numbers
1177	 * (labeled x and y), which can be used to represent a number of things, such as:
1178	 *
1179	 * - A point in 2D space (i.e. a position on a plane).
1180	 * - A direction and length across a plane. In three.js the length will
1181	 * always be the Euclidean distance(straight-line distance) from `(0, 0)` to `(x, y)`
1182	 * and the direction is also measured from `(0, 0)` towards `(x, y)`.
1183	 * - Any arbitrary ordered pair of numbers.
1184	 *
1185	 * There are other things a 2D vector can be used to represent, such as
1186	 * momentum vectors, complex numbers and so on, however these are the most
1187	 * common uses in three.js.
1188	 *
1189	 * Iterating through a vector instance will yield its components `(x, y)` in
1190	 * the corresponding order.
1191	 * ```js
1192	 * const a = new THREE.Vector2( 0, 1 );
1193	 *
1194	 * //no arguments; will be initialised to (0, 0)
1195	 * const b = new THREE.Vector2( );
1196	 *
1197	 * const d = a.distanceTo( b );
1198	 * ```
1199	 */ class Vector2 {
1200	    /**
1201		 * Alias for {@link Vector2#x}.
1202		 *
1203		 * @type {number}
1204		 */ get width() {
1205	        return this.x;
1206	    }
1207	    set width(value) {
1208	        this.x = value;
1209	    }
1210	    /**
1211		 * Alias for {@link Vector2#y}.
1212		 *
1213		 * @type {number}
1214		 */ get height() {
1215	        return this.y;
1216	    }
1217	    set height(value) {
1218	        this.y = value;
1219	    }
1220	    /**
1221		 * Sets the vector components.
1222		 *
1223		 * @param {number} x - The value of the x component.
1224		 * @param {number} y - The value of the y component.
1225		 * @return {Vector2} A reference to this vector.
1226		 */ set(x, y) {
1227	        this.x = x;
1228	        this.y = y;
1229	        return this;
1230	    }
1231	    /**
1232		 * Sets the vector components to the same value.
1233		 *
1234		 * @param {number} scalar - The value to set for all vector components.
1235		 * @return {Vector2} A reference to this vector.
1236		 */ setScalar(scalar) {
1237	        this.x = scalar;
1238	        this.y = scalar;
1239	        return this;
1240	    }
1241	    /**
1242		 * Sets the vector's x component to the given value
1243		 *
1244		 * @param {number} x - The value to set.
1245		 * @return {Vector2} A reference to this vector.
1246		 */ setX(x) {
1247	        this.x = x;
1248	        return this;
1249	    }
1250	    /**
1251		 * Sets the vector's y component to the given value
1252		 *
1253		 * @param {number} y - The value to set.
1254		 * @return {Vector2} A reference to this vector.
1255		 */ setY(y) {
1256	        this.y = y;
1257	        return this;
1258	    }
1259	    /**
1260		 * Allows to set a vector component with an index.
1261		 *
1262		 * @param {number} index - The component index. `0` equals to x, `1` equals to y.
1263		 * @param {number} value - The value to set.
1264		 * @return {Vector2} A reference to this vector.
1265		 */ setComponent(index, value) {
1266	        switch(index){
1267	            case 0:
1268	                this.x = value;
1269	                break;
1270	            case 1:
1271	                this.y = value;
1272	                break;
1273	            default:
1274	                throw new Error('index is out of range: ' + index);
1275	        }
1276	        return this;
1277	    }
1278	    /**
1279		 * Returns the value of the vector component which matches the given index.
1280		 *
1281		 * @param {number} index - The component index. `0` equals to x, `1` equals to y.
1282		 * @return {number} A vector component value.
1283		 */ getComponent(index) {
1284	        switch(index){
1285	            case 0:
1286	                return this.x;
1287	            case 1:
1288	                return this.y;
1289	            default:
1290	                throw new Error('index is out of range: ' + index);
1291	        }
1292	    }
1293	    /**
1294		 * Returns a new vector with copied values from this instance.
1295		 *
1296		 * @return {Vector2} A clone of this instance.
1297		 */ clone() {
1298	        return new this.constructor(this.x, this.y);
1299	    }
1300	    /**
1301		 * Copies the values of the given vector to this instance.
1302		 *
1303		 * @param {Vector2} v - The vector to copy.
1304		 * @return {Vector2} A reference to this vector.
1305		 */ copy(v) {
1306	        this.x = v.x;
1307	        this.y = v.y;
1308	        return this;
1309	    }
1310	    /**
1311		 * Adds the given vector to this instance.
1312		 *
1313		 * @param {Vector2} v - The vector to add.
1314		 * @return {Vector2} A reference to this vector.
1315		 */ add(v) {
1316	        this.x += v.x;
1317	        this.y += v.y;
1318	        return this;
1319	    }
1320	    /**
1321		 * Adds the given scalar value to all components of this instance.
1322		 *
1323		 * @param {number} s - The scalar to add.
1324		 * @return {Vector2} A reference to this vector.
1325		 */ addScalar(s) {
1326	        this.x += s;
1327	        this.y += s;
1328	        return this;
1329	    }
1330	    /**
1331		 * Adds the given vectors and stores the result in this instance.
1332		 *
1333		 * @param {Vector2} a - The first vector.
1334		 * @param {Vector2} b - The second vector.
1335		 * @return {Vector2} A reference to this vector.
1336		 */ addVectors(a, b) {
1337	        this.x = a.x + b.x;
1338	        this.y = a.y + b.y;
1339	        return this;
1340	    }
1341	    /**
1342		 * Adds the given vector scaled by the given factor to this instance.
1343		 *
1344		 * @param {Vector2} v - The vector.
1345		 * @param {number} s - The factor that scales `v`.
1346		 * @return {Vector2} A reference to this vector.
1347		 */ addScaledVector(v, s) {
1348	        this.x += v.x * s;
1349	        this.y += v.y * s;
1350	        return this;
1351	    }
1352	    /**
1353		 * Subtracts the given vector from this instance.
1354		 *
1355		 * @param {Vector2} v - The vector to subtract.
1356		 * @return {Vector2} A reference to this vector.
1357		 */ sub(v) {
1358	        this.x -= v.x;
1359	        this.y -= v.y;
1360	        return this;
1361	    }
1362	    /**
1363		 * Subtracts the given scalar value from all components of this instance.
1364		 *
1365		 * @param {number} s - The scalar to subtract.
1366		 * @return {Vector2} A reference to this vector.
1367		 */ subScalar(s) {
1368	        this.x -= s;
1369	        this.y -= s;
1370	        return this;
1371	    }
1372	    /**
1373		 * Subtracts the given vectors and stores the result in this instance.
1374		 *
1375		 * @param {Vector2} a - The first vector.
1376		 * @param {Vector2} b - The second vector.
1377		 * @return {Vector2} A reference to this vector.
1378		 */ subVectors(a, b) {
1379	        this.x = a.x - b.x;
1380	        this.y = a.y - b.y;
1381	        return this;
1382	    }
1383	    /**
1384		 * Multiplies the given vector with this instance.
1385		 *
1386		 * @param {Vector2} v - The vector to multiply.
1387		 * @return {Vector2} A reference to this vector.
1388		 */ multiply(v) {
1389	        this.x *= v.x;
1390	        this.y *= v.y;
1391	        return this;
1392	    }
1393	    /**
1394		 * Multiplies the given scalar value with all components of this instance.
1395		 *
1396		 * @param {number} scalar - The scalar to multiply.
1397		 * @return {Vector2} A reference to this vector.
1398		 */ multiplyScalar(scalar) {
1399	        this.x *= scalar;
1400	        this.y *= scalar;
1401	        return this;
1402	    }
1403	    /**
1404		 * Divides this instance by the given vector.
1405		 *
1406		 * @param {Vector2} v - The vector to divide.
1407		 * @return {Vector2} A reference to this vector.
1408		 */ divide(v) {
1409	        this.x /= v.x;
1410	        this.y /= v.y;
1411	        return this;
1412	    }
1413	    /**
1414		 * Divides this vector by the given scalar.
1415		 *
1416		 * @param {number} scalar - The scalar to divide.
1417		 * @return {Vector2} A reference to this vector.
1418		 */ divideScalar(scalar) {
1419	        return this.multiplyScalar(1 / scalar);
1420	    }
1421	    /**
1422		 * Multiplies this vector (with an implicit 1 as the 3rd component) by
1423		 * the given 3x3 matrix.
1424		 *
1425		 * @param {Matrix3} m - The matrix to apply.
1426		 * @return {Vector2} A reference to this vector.
1427		 */ applyMatrix3(m) {
1428	        const x = this.x, y = this.y;
1429	        const e = m.elements;
1430	        this.x = e[0] * x + e[3] * y + e[6];
1431	        this.y = e[1] * x + e[4] * y + e[7];
1432	        return this;
1433	    }
1434	    /**
1435		 * If this vector's x or y value is greater than the given vector's x or y
1436		 * value, replace that value with the corresponding min value.
1437		 *
1438		 * @param {Vector2} v - The vector.
1439		 * @return {Vector2} A reference to this vector.
1440		 */ min(v) {
1441	        this.x = Math.min(this.x, v.x);
1442	        this.y = Math.min(this.y, v.y);
1443	        return this;
1444	    }
1445	    /**
1446		 * If this vector's x or y value is less than the given vector's x or y
1447		 * value, replace that value with the corresponding max value.
1448		 *
1449		 * @param {Vector2} v - The vector.
1450		 * @return {Vector2} A reference to this vector.
1451		 */ max(v) {
1452	        this.x = Math.max(this.x, v.x);
1453	        this.y = Math.max(this.y, v.y);
1454	        return this;
1455	    }
1456	    /**
1457		 * If this vector's x or y value is greater than the max vector's x or y
1458		 * value, it is replaced by the corresponding value.
1459		 * If this vector's x or y value is less than the min vector's x or y value,
1460		 * it is replaced by the corresponding value.
1461		 *
1462		 * @param {Vector2} min - The minimum x and y values.
1463		 * @param {Vector2} max - The maximum x and y values in the desired range.
1464		 * @return {Vector2} A reference to this vector.
1465		 */ clamp(min, max) {
1466	        // assumes min < max, componentwise
1467	        this.x = clamp$1(this.x, min.x, max.x);
1468	        this.y = clamp$1(this.y, min.y, max.y);
1469	        return this;
1470	    }
1471	    /**
1472		 * If this vector's x or y values are greater than the max value, they are
1473		 * replaced by the max value.
1474		 * If this vector's x or y values are less than the min value, they are
1475		 * replaced by the min value.
1476		 *
1477		 * @param {number} minVal - The minimum value the components will be clamped to.
1478		 * @param {number} maxVal - The maximum value the components will be clamped to.
1479		 * @return {Vector2} A reference to this vector.
1480		 */ clampScalar(minVal, maxVal) {
1481	        this.x = clamp$1(this.x, minVal, maxVal);
1482	        this.y = clamp$1(this.y, minVal, maxVal);
1483	        return this;
1484	    }
1485	    /**
1486		 * If this vector's length is greater than the max value, it is replaced by
1487		 * the max value.
1488		 * If this vector's length is less than the min value, it is replaced by the
1489		 * min value.
1490		 *
1491		 * @param {number} min - The minimum value the vector length will be clamped to.
1492		 * @param {number} max - The maximum value the vector length will be clamped to.
1493		 * @return {Vector2} A reference to this vector.
1494		 */ clampLength(min, max) {
1495	        const length = this.length();
1496	        return this.divideScalar(length || 1).multiplyScalar(clamp$1(length, min, max));
1497	    }
1498	    /**
1499		 * The components of this vector are rounded down to the nearest integer value.
1500		 *
1501		 * @return {Vector2} A reference to this vector.
1502		 */ floor() {
1503	        this.x = Math.floor(this.x);
1504	        this.y = Math.floor(this.y);
1505	        return this;
1506	    }
1507	    /**
1508		 * The components of this vector are rounded up to the nearest integer value.
1509		 *
1510		 * @return {Vector2} A reference to this vector.
1511		 */ ceil() {
1512	        this.x = Math.ceil(this.x);
1513	        this.y = Math.ceil(this.y);
1514	        return this;
1515	    }
1516	    /**
1517		 * The components of this vector are rounded to the nearest integer value
1518		 *
1519		 * @return {Vector2} A reference to this vector.
1520		 */ round() {
1521	        this.x = Math.round(this.x);
1522	        this.y = Math.round(this.y);
1523	        return this;
1524	    }
1525	    /**
1526		 * The components of this vector are rounded towards zero (up if negative,
1527		 * down if positive) to an integer value.
1528		 *
1529		 * @return {Vector2} A reference to this vector.
1530		 */ roundToZero() {
1531	        this.x = Math.trunc(this.x);
1532	        this.y = Math.trunc(this.y);
1533	        return this;
1534	    }
1535	    /**
1536		 * Inverts this vector - i.e. sets x = -x and y = -y.
1537		 *
1538		 * @return {Vector2} A reference to this vector.
1539		 */ negate() {
1540	        this.x = -this.x;
1541	        this.y = -this.y;
1542	        return this;
1543	    }
1544	    /**
1545		 * Calculates the dot product of the given vector with this instance.
1546		 *
1547		 * @param {Vector2} v - The vector to compute the dot product with.
1548		 * @return {number} The result of the dot product.
1549		 */ dot(v) {
1550	        return this.x * v.x + this.y * v.y;
1551	    }
1552	    /**
1553		 * Calculates the cross product of the given vector with this instance.
1554		 *
1555		 * @param {Vector2} v - The vector to compute the cross product with.
1556		 * @return {number} The result of the cross product.
1557		 */ cross(v) {
1558	        return this.x * v.y - this.y * v.x;
1559	    }
1560	    /**
1561		 * Computes the square of the Euclidean length (straight-line length) from
1562		 * (0, 0) to (x, y). If you are comparing the lengths of vectors, you should
1563		 * compare the length squared instead as it is slightly more efficient to calculate.
1564		 *
1565		 * @return {number} The square length of this vector.
1566		 */ lengthSq() {
1567	        return this.x * this.x + this.y * this.y;
1568	    }
1569	    /**
1570		 * Computes the  Euclidean length (straight-line length) from (0, 0) to (x, y).
1571		 *
1572		 * @return {number} The length of this vector.
1573		 */ length() {
1574	        return Math.sqrt(this.x * this.x + this.y * this.y);
1575	    }
1576	    /**
1577		 * Computes the Manhattan length of this vector.
1578		 *
1579		 * @return {number} The length of this vector.
1580		 */ manhattanLength() {
1581	        return Math.abs(this.x) + Math.abs(this.y);
1582	    }
1583	    /**
1584		 * Converts this vector to a unit vector - that is, sets it equal to a vector
1585		 * with the same direction as this one, but with a vector length of `1`.
1586		 *
1587		 * @return {Vector2} A reference to this vector.
1588		 */ normalize() {
1589	        return this.divideScalar(this.length() || 1);
1590	    }
1591	    /**
1592		 * Computes the angle in radians of this vector with respect to the positive x-axis.
1593		 *
1594		 * @return {number} The angle in radians.
1595		 */ angle() {
1596	        const angle = Math.atan2(-this.y, -this.x) + Math.PI;
1597	        return angle;
1598	    }
1599	    /**
1600		 * Returns the angle between the given vector and this instance in radians.
1601		 *
1602		 * @param {Vector2} v - The vector to compute the angle with.
1603		 * @return {number} The angle in radians.
1604		 */ angleTo(v) {
1605	        const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
1606	        if (denominator === 0) return Math.PI / 2;
1607	        const theta = this.dot(v) / denominator;
1608	        // clamp, to handle numerical problems
1609	        return Math.acos(clamp$1(theta, -1, 1));
1610	    }
1611	    /**
1612		 * Computes the distance from the given vector to this instance.
1613		 *
1614		 * @param {Vector2} v - The vector to compute the distance to.
1615		 * @return {number} The distance.
1616		 */ distanceTo(v) {
1617	        return Math.sqrt(this.distanceToSquared(v));
1618	    }
1619	    /**
1620		 * Computes the squared distance from the given vector to this instance.
1621		 * If you are just comparing the distance with another distance, you should compare
1622		 * the distance squared instead as it is slightly more efficient to calculate.
1623		 *
1624		 * @param {Vector2} v - The vector to compute the squared distance to.
1625		 * @return {number} The squared distance.
1626		 */ distanceToSquared(v) {
1627	        const dx = this.x - v.x, dy = this.y - v.y;
1628	        return dx * dx + dy * dy;
1629	    }
1630	    /**
1631		 * Computes the Manhattan distance from the given vector to this instance.
1632		 *
1633		 * @param {Vector2} v - The vector to compute the Manhattan distance to.
1634		 * @return {number} The Manhattan distance.
1635		 */ manhattanDistanceTo(v) {
1636	        return Math.abs(this.x - v.x) + Math.abs(this.y - v.y);
1637	    }
1638	    /**
1639		 * Sets this vector to a vector with the same direction as this one, but
1640		 * with the specified length.
1641		 *
1642		 * @param {number} length - The new length of this vector.
1643		 * @return {Vector2} A reference to this vector.
1644		 */ setLength(length) {
1645	        return this.normalize().multiplyScalar(length);
1646	    }
1647	    /**
1648		 * Linearly interpolates between the given vector and this instance, where
1649		 * alpha is the percent distance along the line - alpha = 0 will be this
1650		 * vector, and alpha = 1 will be the given one.
1651		 *
1652		 * @param {Vector2} v - The vector to interpolate towards.
1653		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
1654		 * @return {Vector2} A reference to this vector.
1655		 */ lerp(v, alpha) {
1656	        this.x += (v.x - this.x) * alpha;
1657	        this.y += (v.y - this.y) * alpha;
1658	        return this;
1659	    }
1660	    /**
1661		 * Linearly interpolates between the given vectors, where alpha is the percent
1662		 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
1663		 * be the second one. The result is stored in this instance.
1664		 *
1665		 * @param {Vector2} v1 - The first vector.
1666		 * @param {Vector2} v2 - The second vector.
1667		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
1668		 * @return {Vector2} A reference to this vector.
1669		 */ lerpVectors(v1, v2, alpha) {
1670	        this.x = v1.x + (v2.x - v1.x) * alpha;
1671	        this.y = v1.y + (v2.y - v1.y) * alpha;
1672	        return this;
1673	    }
1674	    /**
1675		 * Returns `true` if this vector is equal with the given one.
1676		 *
1677		 * @param {Vector2} v - The vector to test for equality.
1678		 * @return {boolean} Whether this vector is equal with the given one.
1679		 */ equals(v) {
1680	        return v.x === this.x && v.y === this.y;
1681	    }
1682	    /**
1683		 * Sets this vector's x value to be `array[ offset ]` and y
1684		 * value to be `array[ offset + 1 ]`.
1685		 *
1686		 * @param {Array<number>} array - An array holding the vector component values.
1687		 * @param {number} [offset=0] - The offset into the array.
1688		 * @return {Vector2} A reference to this vector.
1689		 */ fromArray(array, offset = 0) {
1690	        this.x = array[offset];
1691	        this.y = array[offset + 1];
1692	        return this;
1693	    }
1694	    /**
1695		 * Writes the components of this vector to the given array. If no array is provided,
1696		 * the method returns a new instance.
1697		 *
1698		 * @param {Array<number>} [array=[]] - The target array holding the vector components.
1699		 * @param {number} [offset=0] - Index of the first element in the array.
1700		 * @return {Array<number>} The vector components.
1701		 */ toArray(array = [], offset = 0) {
1702	        array[offset] = this.x;
1703	        array[offset + 1] = this.y;
1704	        return array;
1705	    }
1706	    /**
1707		 * Sets the components of this vector from the given buffer attribute.
1708		 *
1709		 * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
1710		 * @param {number} index - The index into the attribute.
1711		 * @return {Vector2} A reference to this vector.
1712		 */ fromBufferAttribute(attribute, index) {
1713	        this.x = attribute.getX(index);
1714	        this.y = attribute.getY(index);
1715	        return this;
1716	    }
1717	    /**
1718		 * Rotates this vector around the given center by the given angle.
1719		 *
1720		 * @param {Vector2} center - The point around which to rotate.
1721		 * @param {number} angle - The angle to rotate, in radians.
1722		 * @return {Vector2} A reference to this vector.
1723		 */ rotateAround(center, angle) {
1724	        const c = Math.cos(angle), s = Math.sin(angle);
1725	        const x = this.x - center.x;
1726	        const y = this.y - center.y;
1727	        this.x = x * c - y * s + center.x;
1728	        this.y = x * s + y * c + center.y;
1729	        return this;
1730	    }
1731	    /**
1732		 * Sets each component of this vector to a pseudo-random value between `0` and
1733		 * `1`, excluding `1`.
1734		 *
1735		 * @return {Vector2} A reference to this vector.
1736		 */ random() {
1737	        this.x = Math.random();
1738	        this.y = Math.random();
1739	        return this;
1740	    }
1741	    *[Symbol.iterator]() {
1742	        yield this.x;
1743	        yield this.y;
1744	    }
1745	    /**
1746		 * Constructs a new 2D vector.
1747		 *
1748		 * @param {number} [x=0] - The x value of this vector.
1749		 * @param {number} [y=0] - The y value of this vector.
1750		 */ constructor(x = 0, y = 0){
1751	        /**
1752			 * This flag can be used for type testing.
1753			 *
1754			 * @type {boolean}
1755			 * @readonly
1756			 * @default true
1757			 */ Vector2.prototype.isVector2 = true;
1758	        /**
1759			 * The x value of this vector.
1760			 *
1761			 * @type {number}
1762			 */ this.x = x;
1763	        /**
1764			 * The y value of this vector.
1765			 *
1766			 * @type {number}
1767			 */ this.y = y;
1768	    }
1769	}
1770	/**
1771	 * Represents a 3x3 matrix.
1772	 *
1773	 * A Note on Row-Major and Column-Major Ordering:
1774	 *
1775	 * The constructor and {@link Matrix3#set} method take arguments in
1776	 * [row-major]{@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order}
1777	 * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order.
1778	 * This means that calling:
1779	 * ```js
1780	 * const m = new THREE.Matrix();
1781	 * m.set( 11, 12, 13,
1782	 *        21, 22, 23,
1783	 *        31, 32, 33 );
1784	 * ```
1785	 * will result in the elements array containing:
1786	 * ```js
1787	 * m.elements = [ 11, 21, 31,
1788	 *                12, 22, 32,
1789	 *                13, 23, 33 ];
1790	 * ```
1791	 * and internally all calculations are performed using column-major ordering.
1792	 * However, as the actual ordering makes no difference mathematically and
1793	 * most people are used to thinking about matrices in row-major order, the
1794	 * three.js documentation shows matrices in row-major order. Just bear in
1795	 * mind that if you are reading the source code, you'll have to take the
1796	 * transpose of any matrices outlined here to make sense of the calculations.
1797	 */ class Matrix3 {
1798	    /**
1799		 * Sets the elements of the matrix.The arguments are supposed to be
1800		 * in row-major order.
1801		 *
1802		 * @param {number} [n11] - 1-1 matrix element.
1803		 * @param {number} [n12] - 1-2 matrix element.
1804		 * @param {number} [n13] - 1-3 matrix element.
1805		 * @param {number} [n21] - 2-1 matrix element.
1806		 * @param {number} [n22] - 2-2 matrix element.
1807		 * @param {number} [n23] - 2-3 matrix element.
1808		 * @param {number} [n31] - 3-1 matrix element.
1809		 * @param {number} [n32] - 3-2 matrix element.
1810		 * @param {number} [n33] - 3-3 matrix element.
1811		 * @return {Matrix3} A reference to this matrix.
1812		 */ set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
1813	        const te = this.elements;
1814	        te[0] = n11;
1815	        te[1] = n21;
1816	        te[2] = n31;
1817	        te[3] = n12;
1818	        te[4] = n22;
1819	        te[5] = n32;
1820	        te[6] = n13;
1821	        te[7] = n23;
1822	        te[8] = n33;
1823	        return this;
1824	    }
1825	    /**
1826		 * Sets this matrix to the 3x3 identity matrix.
1827		 *
1828		 * @return {Matrix3} A reference to this matrix.
1829		 */ identity() {
1830	        this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
1831	        return this;
1832	    }
1833	    /**
1834		 * Copies the values of the given matrix to this instance.
1835		 *
1836		 * @param {Matrix3} m - The matrix to copy.
1837		 * @return {Matrix3} A reference to this matrix.
1838		 */ copy(m) {
1839	        const te = this.elements;
1840	        const me = m.elements;
1841	        te[0] = me[0];
1842	        te[1] = me[1];
1843	        te[2] = me[2];
1844	        te[3] = me[3];
1845	        te[4] = me[4];
1846	        te[5] = me[5];
1847	        te[6] = me[6];
1848	        te[7] = me[7];
1849	        te[8] = me[8];
1850	        return this;
1851	    }
1852	    /**
1853		 * Extracts the basis of this matrix into the three axis vectors provided.
1854		 *
1855		 * @param {Vector3} xAxis - The basis's x axis.
1856		 * @param {Vector3} yAxis - The basis's y axis.
1857		 * @param {Vector3} zAxis - The basis's z axis.
1858		 * @return {Matrix3} A reference to this matrix.
1859		 */ extractBasis(xAxis, yAxis, zAxis) {
1860	        xAxis.setFromMatrix3Column(this, 0);
1861	        yAxis.setFromMatrix3Column(this, 1);
1862	        zAxis.setFromMatrix3Column(this, 2);
1863	        return this;
1864	    }
1865	    /**
1866		 * Set this matrix to the upper 3x3 matrix of the given 4x4 matrix.
1867		 *
1868		 * @param {Matrix4} m - The 4x4 matrix.
1869		 * @return {Matrix3} A reference to this matrix.
1870		 */ setFromMatrix4(m) {
1871	        const me = m.elements;
1872	        this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]);
1873	        return this;
1874	    }
1875	    /**
1876		 * Post-multiplies this matrix by the given 3x3 matrix.
1877		 *
1878		 * @param {Matrix3} m - The matrix to multiply with.
1879		 * @return {Matrix3} A reference to this matrix.
1880		 */ multiply(m) {
1881	        return this.multiplyMatrices(this, m);
1882	    }
1883	    /**
1884		 * Pre-multiplies this matrix by the given 3x3 matrix.
1885		 *
1886		 * @param {Matrix3} m - The matrix to multiply with.
1887		 * @return {Matrix3} A reference to this matrix.
1888		 */ premultiply(m) {
1889	        return this.multiplyMatrices(m, this);
1890	    }
1891	    /**
1892		 * Multiples the given 3x3 matrices and stores the result
1893		 * in this matrix.
1894		 *
1895		 * @param {Matrix3} a - The first matrix.
1896		 * @param {Matrix3} b - The second matrix.
1897		 * @return {Matrix3} A reference to this matrix.
1898		 */ multiplyMatrices(a, b) {
1899	        const ae = a.elements;
1900	        const be = b.elements;
1901	        const te = this.elements;
1902	        const a11 = ae[0], a12 = ae[3], a13 = ae[6];
1903	        const a21 = ae[1], a22 = ae[4], a23 = ae[7];
1904	        const a31 = ae[2], a32 = ae[5], a33 = ae[8];
1905	        const b11 = be[0], b12 = be[3], b13 = be[6];
1906	        const b21 = be[1], b22 = be[4], b23 = be[7];
1907	        const b31 = be[2], b32 = be[5], b33 = be[8];
1908	        te[0] = a11 * b11 + a12 * b21 + a13 * b31;
1909	        te[3] = a11 * b12 + a12 * b22 + a13 * b32;
1910	        te[6] = a11 * b13 + a12 * b23 + a13 * b33;
1911	        te[1] = a21 * b11 + a22 * b21 + a23 * b31;
1912	        te[4] = a21 * b12 + a22 * b22 + a23 * b32;
1913	        te[7] = a21 * b13 + a22 * b23 + a23 * b33;
1914	        te[2] = a31 * b11 + a32 * b21 + a33 * b31;
1915	        te[5] = a31 * b12 + a32 * b22 + a33 * b32;
1916	        te[8] = a31 * b13 + a32 * b23 + a33 * b33;
1917	        return this;
1918	    }
1919	    /**
1920		 * Multiplies every component of the matrix by the given scalar.
1921		 *
1922		 * @param {number} s - The scalar.
1923		 * @return {Matrix3} A reference to this matrix.
1924		 */ multiplyScalar(s) {
1925	        const te = this.elements;
1926	        te[0] *= s;
1927	        te[3] *= s;
1928	        te[6] *= s;
1929	        te[1] *= s;
1930	        te[4] *= s;
1931	        te[7] *= s;
1932	        te[2] *= s;
1933	        te[5] *= s;
1934	        te[8] *= s;
1935	        return this;
1936	    }
1937	    /**
1938		 * Computes and returns the determinant of this matrix.
1939		 *
1940		 * @return {number} The determinant.
1941		 */ determinant() {
1942	        const te = this.elements;
1943	        const a = te[0], b = te[1], c = te[2], d = te[3], e = te[4], f = te[5], g = te[6], h = te[7], i = te[8];
1944	        return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
1945	    }
1946	    /**
1947		 * Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.
1948		 * You can not invert with a determinant of zero. If you attempt this, the method produces
1949		 * a zero matrix instead.
1950		 *
1951		 * @return {Matrix3} A reference to this matrix.
1952		 */ invert() {
1953	        const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n12 = te[3], n22 = te[4], n32 = te[5], n13 = te[6], n23 = te[7], n33 = te[8], t11 = n33 * n22 - n32 * n23, t12 = n32 * n13 - n33 * n12, t13 = n23 * n12 - n22 * n13, det = n11 * t11 + n21 * t12 + n31 * t13;
1954	        if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
1955	        const detInv = 1 / det;
1956	        te[0] = t11 * detInv;
1957	        te[1] = (n31 * n23 - n33 * n21) * detInv;
1958	        te[2] = (n32 * n21 - n31 * n22) * detInv;
1959	        te[3] = t12 * detInv;
1960	        te[4] = (n33 * n11 - n31 * n13) * detInv;
1961	        te[5] = (n31 * n12 - n32 * n11) * detInv;
1962	        te[6] = t13 * detInv;
1963	        te[7] = (n21 * n13 - n23 * n11) * detInv;
1964	        te[8] = (n22 * n11 - n21 * n12) * detInv;
1965	        return this;
1966	    }
1967	    /**
1968		 * Transposes this matrix in place.
1969		 *
1970		 * @return {Matrix3} A reference to this matrix.
1971		 */ transpose() {
1972	        let tmp;
1973	        const m = this.elements;
1974	        tmp = m[1];
1975	        m[1] = m[3];
1976	        m[3] = tmp;
1977	        tmp = m[2];
1978	        m[2] = m[6];
1979	        m[6] = tmp;
1980	        tmp = m[5];
1981	        m[5] = m[7];
1982	        m[7] = tmp;
1983	        return this;
1984	    }
1985	    /**
1986		 * Computes the normal matrix which is the inverse transpose of the upper
1987		 * left 3x3 portion of the given 4x4 matrix.
1988		 *
1989		 * @param {Matrix4} matrix4 - The 4x4 matrix.
1990		 * @return {Matrix3} A reference to this matrix.
1991		 */ getNormalMatrix(matrix4) {
1992	        return this.setFromMatrix4(matrix4).invert().transpose();
1993	    }
1994	    /**
1995		 * Transposes this matrix into the supplied array, and returns itself unchanged.
1996		 *
1997		 * @param {Array<number>} r - An array to store the transposed matrix elements.
1998		 * @return {Matrix3} A reference to this matrix.
1999		 */ transposeIntoArray(r) {
2000	        const m = this.elements;
2001	        r[0] = m[0];
2002	        r[1] = m[3];
2003	        r[2] = m[6];
2004	        r[3] = m[1];
2005	        r[4] = m[4];
2006	        r[5] = m[7];
2007	        r[6] = m[2];
2008	        r[7] = m[5];
2009	        r[8] = m[8];
2010	        return this;
2011	    }
2012	    /**
2013		 * Sets the UV transform matrix from offset, repeat, rotation, and center.
2014		 *
2015		 * @param {number} tx - Offset x.
2016		 * @param {number} ty - Offset y.
2017		 * @param {number} sx - Repeat x.
2018		 * @param {number} sy - Repeat y.
2019		 * @param {number} rotation - Rotation, in radians. Positive values rotate counterclockwise.
2020		 * @param {number} cx - Center x of rotation.
2021		 * @param {number} cy - Center y of rotation
2022		 * @return {Matrix3} A reference to this matrix.
2023		 */ setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {
2024	        const c = Math.cos(rotation);
2025	        const s = Math.sin(rotation);
2026	        this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1);
2027	        return this;
2028	    }
2029	    /**
2030		 * Scales this matrix with the given scalar values.
2031		 *
2032		 * @param {number} sx - The amount to scale in the X axis.
2033		 * @param {number} sy - The amount to scale in the Y axis.
2034		 * @return {Matrix3} A reference to this matrix.
2035		 */ scale(sx, sy) {
2036	        this.premultiply(_m3.makeScale(sx, sy));
2037	        return this;
2038	    }
2039	    /**
2040		 * Rotates this matrix by the given angle.
2041		 *
2042		 * @param {number} theta - The rotation in radians.
2043		 * @return {Matrix3} A reference to this matrix.
2044		 */ rotate(theta) {
2045	        this.premultiply(_m3.makeRotation(-theta));
2046	        return this;
2047	    }
2048	    /**
2049		 * Translates this matrix by the given scalar values.
2050		 *
2051		 * @param {number} tx - The amount to translate in the X axis.
2052		 * @param {number} ty - The amount to translate in the Y axis.
2053		 * @return {Matrix3} A reference to this matrix.
2054		 */ translate(tx, ty) {
2055	        this.premultiply(_m3.makeTranslation(tx, ty));
2056	        return this;
2057	    }
2058	    // for 2D Transforms
2059	    /**
2060		 * Sets this matrix as a 2D translation transform.
2061		 *
2062		 * @param {number|Vector2} x - The amount to translate in the X axis or alternatively a translation vector.
2063		 * @param {number} y - The amount to translate in the Y axis.
2064		 * @return {Matrix3} A reference to this matrix.
2065		 */ makeTranslation(x, y) {
2066	        if (x.isVector2) {
2067	            this.set(1, 0, x.x, 0, 1, x.y, 0, 0, 1);
2068	        } else {
2069	            this.set(1, 0, x, 0, 1, y, 0, 0, 1);
2070	        }
2071	        return this;
2072	    }
2073	    /**
2074		 * Sets this matrix as a 2D rotational transformation.
2075		 *
2076		 * @param {number} theta - The rotation in radians.
2077		 * @return {Matrix3} A reference to this matrix.
2078		 */ makeRotation(theta) {
2079	        // counterclockwise
2080	        const c = Math.cos(theta);
2081	        const s = Math.sin(theta);
2082	        this.set(c, -s, 0, s, c, 0, 0, 0, 1);
2083	        return this;
2084	    }
2085	    /**
2086		 * Sets this matrix as a 2D scale transform.
2087		 *
2088		 * @param {number} x - The amount to scale in the X axis.
2089		 * @param {number} y - The amount to scale in the Y axis.
2090		 * @return {Matrix3} A reference to this matrix.
2091		 */ makeScale(x, y) {
2092	        this.set(x, 0, 0, 0, y, 0, 0, 0, 1);
2093	        return this;
2094	    }
2095	    /**
2096		 * Returns `true` if this matrix is equal with the given one.
2097		 *
2098		 * @param {Matrix3} matrix - The matrix to test for equality.
2099		 * @return {boolean} Whether this matrix is equal with the given one.
2100		 */ equals(matrix) {
2101	        const te = this.elements;
2102	        const me = matrix.elements;
2103	        for(let i = 0; i < 9; i++){
2104	            if (te[i] !== me[i]) return false;
2105	        }
2106	        return true;
2107	    }
2108	    /**
2109		 * Sets the elements of the matrix from the given array.
2110		 *
2111		 * @param {Array<number>} array - The matrix elements in column-major order.
2112		 * @param {number} [offset=0] - Index of the first element in the array.
2113		 * @return {Matrix3} A reference to this matrix.
2114		 */ fromArray(array, offset = 0) {
2115	        for(let i = 0; i < 9; i++){
2116	            this.elements[i] = array[i + offset];
2117	        }
2118	        return this;
2119	    }
2120	    /**
2121		 * Writes the elements of this matrix to the given array. If no array is provided,
2122		 * the method returns a new instance.
2123		 *
2124		 * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.
2125		 * @param {number} [offset=0] - Index of the first element in the array.
2126		 * @return {Array<number>} The matrix elements in column-major order.
2127		 */ toArray(array = [], offset = 0) {
2128	        const te = this.elements;
2129	        array[offset] = te[0];
2130	        array[offset + 1] = te[1];
2131	        array[offset + 2] = te[2];
2132	        array[offset + 3] = te[3];
2133	        array[offset + 4] = te[4];
2134	        array[offset + 5] = te[5];
2135	        array[offset + 6] = te[6];
2136	        array[offset + 7] = te[7];
2137	        array[offset + 8] = te[8];
2138	        return array;
2139	    }
2140	    /**
2141		 * Returns a matrix with copied values from this instance.
2142		 *
2143		 * @return {Matrix3} A clone of this instance.
2144		 */ clone() {
2145	        return new this.constructor().fromArray(this.elements);
2146	    }
2147	    /**
2148		 * Constructs a new 3x3 matrix. The arguments are supposed to be
2149		 * in row-major order. If no arguments are provided, the constructor
2150		 * initializes the matrix as an identity matrix.
2151		 *
2152		 * @param {number} [n11] - 1-1 matrix element.
2153		 * @param {number} [n12] - 1-2 matrix element.
2154		 * @param {number} [n13] - 1-3 matrix element.
2155		 * @param {number} [n21] - 2-1 matrix element.
2156		 * @param {number} [n22] - 2-2 matrix element.
2157		 * @param {number} [n23] - 2-3 matrix element.
2158		 * @param {number} [n31] - 3-1 matrix element.
2159		 * @param {number} [n32] - 3-2 matrix element.
2160		 * @param {number} [n33] - 3-3 matrix element.
2161		 */ constructor(n11, n12, n13, n21, n22, n23, n31, n32, n33){
2162	        /**
2163			 * This flag can be used for type testing.
2164			 *
2165			 * @type {boolean}
2166			 * @readonly
2167			 * @default true
2168			 */ Matrix3.prototype.isMatrix3 = true;
2169	        /**
2170			 * A column-major list of matrix values.
2171			 *
2172			 * @type {Array<number>}
2173			 */ this.elements = [
2174	            1,
2175	            0,
2176	            0,
2177	            0,
2178	            1,
2179	            0,
2180	            0,
2181	            0,
2182	            1
2183	        ];
2184	        if (n11 !== undefined) {
2185	            this.set(n11, n12, n13, n21, n22, n23, n31, n32, n33);
2186	        }
2187	    }
2188	}
2189	const _m3 = /*@__PURE__*/ new Matrix3();
2190	function arrayNeedsUint32(array) {
2191	    // assumes larger values usually on last
2192	    for(let i = array.length - 1; i >= 0; --i){
2193	        if (array[i] >= 65535) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565
2194	    }
2195	    return false;
2196	}
2197	function createElementNS(name) {
2198	    return document.createElementNS('http://www.w3.org/1999/xhtml', name);
2199	}
2200	function createCanvasElement() {
2201	    const canvas = createElementNS('canvas');
2202	    canvas.style.display = 'block';
2203	    return canvas;
2204	}
2205	const _cache = {};
2206	function warnOnce(message) {
2207	    if (message in _cache) return;
2208	    _cache[message] = true;
2209	    console.warn(message);
2210	}
2211	function probeAsync(gl, sync, interval) {
2212	    return new Promise(function(resolve, reject) {
2213	        function probe() {
2214	            switch(gl.clientWaitSync(sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0)){
2215	                case gl.WAIT_FAILED:
2216	                    reject();
2217	                    break;
2218	                case gl.TIMEOUT_EXPIRED:
2219	                    setTimeout(probe, interval);
2220	                    break;
2221	                default:
2222	                    resolve();
2223	            }
2224	        }
2225	        setTimeout(probe, interval);
2226	    });
2227	}
2228	function toNormalizedProjectionMatrix(projectionMatrix) {
2229	    const m = projectionMatrix.elements;
2230	    // Convert [-1, 1] to [0, 1] projection matrix
2231	    m[2] = 0.5 * m[2] + 0.5 * m[3];
2232	    m[6] = 0.5 * m[6] + 0.5 * m[7];
2233	    m[10] = 0.5 * m[10] + 0.5 * m[11];
2234	    m[14] = 0.5 * m[14] + 0.5 * m[15];
2235	}
2236	function toReversedProjectionMatrix(projectionMatrix) {
2237	    const m = projectionMatrix.elements;
2238	    const isPerspectiveMatrix = m[11] === -1;
2239	    // Reverse [0, 1] projection matrix
2240	    if (isPerspectiveMatrix) {
2241	        m[10] = -m[10] - 1;
2242	        m[14] = -m[14];
2243	    } else {
2244	        m[10] = -m[10];
2245	        m[14] = -m[14] + 1;
2246	    }
2247	}
2248	const LINEAR_REC709_TO_XYZ = /*@__PURE__*/ new Matrix3().set(0.4123908, 0.3575843, 0.1804808, 0.2126390, 0.7151687, 0.0721923, 0.0193308, 0.1191948, 0.9505322);
2249	const XYZ_TO_LINEAR_REC709 = /*@__PURE__*/ new Matrix3().set(3.2409699, -1.5373832, -0.4986108, -0.9692436, 1.8759675, 0.0415551, 0.0556301, -0.203977, 1.0569715);
2250	function createColorManagement() {
2251	    const ColorManagement = {
2252	        enabled: true,
2253	        workingColorSpace: LinearSRGBColorSpace,
2254	        /**
2255			 * Implementations of supported color spaces.
2256			 *
2257			 * Required:
2258			 *	- primaries: chromaticity coordinates [ rx ry gx gy bx by ]
2259			 *	- whitePoint: reference white [ x y ]
2260			 *	- transfer: transfer function (pre-defined)
2261			 *	- toXYZ: Matrix3 RGB to XYZ transform
2262			 *	- fromXYZ: Matrix3 XYZ to RGB transform
2263			 *	- luminanceCoefficients: RGB luminance coefficients
2264			 *
2265			 * Optional:
2266			 *  - outputColorSpaceConfig: { drawingBufferColorSpace: ColorSpace }
2267			 *  - workingColorSpaceConfig: { unpackColorSpace: ColorSpace }
2268			 *
2269			 * Reference:
2270			 * - https://www.russellcottrell.com/photo/matrixCalculator.htm
2271			 */ spaces: {},
2272	        convert: function(color, sourceColorSpace, targetColorSpace) {
2273	            if (this.enabled === false || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) {
2274	                return color;
2275	            }
2276	            if (this.spaces[sourceColorSpace].transfer === SRGBTransfer) {
2277	                color.r = SRGBToLinear(color.r);
2278	                color.g = SRGBToLinear(color.g);
2279	                color.b = SRGBToLinear(color.b);
2280	            }
2281	            if (this.spaces[sourceColorSpace].primaries !== this.spaces[targetColorSpace].primaries) {
2282	                color.applyMatrix3(this.spaces[sourceColorSpace].toXYZ);
2283	                color.applyMatrix3(this.spaces[targetColorSpace].fromXYZ);
2284	            }
2285	            if (this.spaces[targetColorSpace].transfer === SRGBTransfer) {
2286	                color.r = LinearToSRGB(color.r);
2287	                color.g = LinearToSRGB(color.g);
2288	                color.b = LinearToSRGB(color.b);
2289	            }
2290	            return color;
2291	        },
2292	        fromWorkingColorSpace: function(color, targetColorSpace) {
2293	            return this.convert(color, this.workingColorSpace, targetColorSpace);
2294	        },
2295	        toWorkingColorSpace: function(color, sourceColorSpace) {
2296	            return this.convert(color, sourceColorSpace, this.workingColorSpace);
2297	        },
2298	        getPrimaries: function(colorSpace) {
2299	            return this.spaces[colorSpace].primaries;
2300	        },
2301	        getTransfer: function(colorSpace) {
2302	            if (colorSpace === NoColorSpace) return LinearTransfer;
2303	            return this.spaces[colorSpace].transfer;
2304	        },
2305	        getLuminanceCoefficients: function(target, colorSpace = this.workingColorSpace) {
2306	            return target.fromArray(this.spaces[colorSpace].luminanceCoefficients);
2307	        },
2308	        define: function(colorSpaces) {
2309	            Object.assign(this.spaces, colorSpaces);
2310	        },
2311	        // Internal APIs
2312	        _getMatrix: function(targetMatrix, sourceColorSpace, targetColorSpace) {
2313	            return targetMatrix.copy(this.spaces[sourceColorSpace].toXYZ).multiply(this.spaces[targetColorSpace].fromXYZ);
2314	        },
2315	        _getDrawingBufferColorSpace: function(colorSpace) {
2316	            return this.spaces[colorSpace].outputColorSpaceConfig.drawingBufferColorSpace;
2317	        },
2318	        _getUnpackColorSpace: function(colorSpace = this.workingColorSpace) {
2319	            return this.spaces[colorSpace].workingColorSpaceConfig.unpackColorSpace;
2320	        }
2321	    };
2322	    /******************************************************************************
2323		 * sRGB definitions
2324		 */ const REC709_PRIMARIES = [
2325	        0.640,
2326	        0.330,
2327	        0.300,
2328	        0.600,
2329	        0.150,
2330	        0.060
2331	    ];
2332	    const REC709_LUMINANCE_COEFFICIENTS = [
2333	        0.2126,
2334	        0.7152,
2335	        0.0722
2336	    ];
2337	    const D65 = [
2338	        0.3127,
2339	        0.3290
2340	    ];
2341	    ColorManagement.define({
2342	        [LinearSRGBColorSpace]: {
2343	            primaries: REC709_PRIMARIES,
vendor: 16,707 bytes, lines 2344-2802
2344	            whitePoint: D65,
2345	            transfer: LinearTransfer,
2346	            toXYZ: LINEAR_REC709_TO_XYZ,
2347	            fromXYZ: XYZ_TO_LINEAR_REC709,
2348	            luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
2349	            workingColorSpaceConfig: {
2350	                unpackColorSpace: SRGBColorSpace
2351	            },
2352	            outputColorSpaceConfig: {
2353	                drawingBufferColorSpace: SRGBColorSpace
2354	            }
2355	        },
2356	        [SRGBColorSpace]: {
2357	            primaries: REC709_PRIMARIES,
2358	            whitePoint: D65,
2359	            transfer: SRGBTransfer,
2360	            toXYZ: LINEAR_REC709_TO_XYZ,
2361	            fromXYZ: XYZ_TO_LINEAR_REC709,
2362	            luminanceCoefficients: REC709_LUMINANCE_COEFFICIENTS,
2363	            outputColorSpaceConfig: {
2364	                drawingBufferColorSpace: SRGBColorSpace
2365	            }
2366	        }
2367	    });
2368	    return ColorManagement;
2369	}
2370	const ColorManagement = /*@__PURE__*/ createColorManagement();
2371	function SRGBToLinear(c) {
2372	    return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
2373	}
2374	function LinearToSRGB(c) {
2375	    return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;
2376	}
2377	let _canvas;
2378	/**
2379	 * A class containing utility functions for images.
2380	 *
2381	 * @hideconstructor
2382	 */ class ImageUtils {
2383	    /**
2384		 * Returns a data URI containing a representation of the given image.
2385		 *
2386		 * @param {(HTMLImageElement|HTMLCanvasElement)} image - The image object.
2387		 * @return {string} The data URI.
2388		 */ static getDataURL(image) {
2389	        if (/^data:/i.test(image.src)) {
2390	            return image.src;
2391	        }
2392	        if (typeof HTMLCanvasElement === 'undefined') {
2393	            return image.src;
2394	        }
2395	        let canvas;
2396	        if (image instanceof HTMLCanvasElement) {
2397	            canvas = image;
2398	        } else {
2399	            if (_canvas === undefined) _canvas = createElementNS('canvas');
2400	            _canvas.width = image.width;
2401	            _canvas.height = image.height;
2402	            const context = _canvas.getContext('2d');
2403	            if (image instanceof ImageData) {
2404	                context.putImageData(image, 0, 0);
2405	            } else {
2406	                context.drawImage(image, 0, 0, image.width, image.height);
2407	            }
2408	            canvas = _canvas;
2409	        }
2410	        return canvas.toDataURL('image/png');
2411	    }
2412	    /**
2413		 * Converts the given sRGB image data to linear color space.
2414		 *
2415		 * @param {(HTMLImageElement|HTMLCanvasElement|ImageBitmap|Object)} image - The image object.
2416		 * @return {HTMLCanvasElement|Object} The converted image.
2417		 */ static sRGBToLinear(image) {
2418	        if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
2419	            const canvas = createElementNS('canvas');
2420	            canvas.width = image.width;
2421	            canvas.height = image.height;
2422	            const context = canvas.getContext('2d');
2423	            context.drawImage(image, 0, 0, image.width, image.height);
2424	            const imageData = context.getImageData(0, 0, image.width, image.height);
2425	            const data = imageData.data;
2426	            for(let i = 0; i < data.length; i++){
2427	                data[i] = SRGBToLinear(data[i] / 255) * 255;
2428	            }
2429	            context.putImageData(imageData, 0, 0);
2430	            return canvas;
2431	        } else if (image.data) {
2432	            const data = image.data.slice(0);
2433	            for(let i = 0; i < data.length; i++){
2434	                if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
2435	                    data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255);
2436	                } else {
2437	                    // assuming float
2438	                    data[i] = SRGBToLinear(data[i]);
2439	                }
2440	            }
2441	            return {
2442	                data: data,
2443	                width: image.width,
2444	                height: image.height
2445	            };
2446	        } else {
2447	            console.warn('THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.');
2448	            return image;
2449	        }
2450	    }
2451	}
2452	let _sourceId = 0;
2453	class Source {
2454	    set needsUpdate(value) {
2455	        if (value === true) this.version++;
2456	    }
2457	    toJSON(meta) {
2458	        const isRootObject = meta === undefined || typeof meta === 'string';
2459	        if (!isRootObject && meta.images[this.uuid] !== undefined) {
2460	            return meta.images[this.uuid];
2461	        }
2462	        const output = {
2463	            uuid: this.uuid,
2464	            url: ''
2465	        };
2466	        const data = this.data;
2467	        if (data !== null) {
2468	            let url;
2469	            if (Array.isArray(data)) {
2470	                // cube texture
2471	                url = [];
2472	                for(let i = 0, l = data.length; i < l; i++){
2473	                    if (data[i].isDataTexture) {
2474	                        url.push(serializeImage(data[i].image));
2475	                    } else {
2476	                        url.push(serializeImage(data[i]));
2477	                    }
2478	                }
2479	            } else {
2480	                // texture
2481	                url = serializeImage(data);
2482	            }
2483	            output.url = url;
2484	        }
2485	        if (!isRootObject) {
2486	            meta.images[this.uuid] = output;
2487	        }
2488	        return output;
2489	    }
2490	    constructor(data = null){
2491	        this.isSource = true;
2492	        Object.defineProperty(this, 'id', {
2493	            value: _sourceId++
2494	        });
2495	        this.uuid = generateUUID();
2496	        this.data = data;
2497	        this.dataReady = true;
2498	        this.version = 0;
2499	    }
2500	}
2501	function serializeImage(image) {
2502	    if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
2503	        // default images
2504	        return ImageUtils.getDataURL(image);
2505	    } else {
2506	        if (image.data) {
2507	            // images of DataTexture
2508	            return {
2509	                data: Array.from(image.data),
2510	                width: image.width,
2511	                height: image.height,
2512	                type: image.data.constructor.name
2513	            };
2514	        } else {
2515	            console.warn('THREE.Texture: Unable to serialize Texture.');
2516	            return {};
2517	        }
2518	    }
2519	}
2520	let _textureId = 0;
2521	/**
2522	 * Base class for all textures.
2523	 *
2524	 * Note: After the initial use of a texture, its dimensions, format, and type
2525	 * cannot be changed. Instead, call {@link Texture#dispose} on the texture and instantiate a new one.
2526	 *
2527	 * @augments EventDispatcher
2528	 */ let Texture$1 = class Texture extends EventDispatcher {
2529	    /**
2530		 * The image object holding the texture data.
2531		 *
2532		 * @type {?Object}
2533		 */ get image() {
2534	        return this.source.data;
2535	    }
2536	    set image(value = null) {
2537	        this.source.data = value;
2538	    }
2539	    /**
2540		 * Updates the texture transformation matrix from the from the properties {@link Texture#offset},
2541		 * {@link Texture#repeat}, {@link Texture#rotation}, and {@link Texture#center}.
2542		 */ updateMatrix() {
2543	        this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
2544	    }
2545	    /**
2546		 * Returns a new texture with copied values from this instance.
2547		 *
2548		 * @return {Texture} A clone of this instance.
2549		 */ clone() {
2550	        return new this.constructor().copy(this);
2551	    }
2552	    /**
2553		 * Copies the values of the given texture to this instance.
2554		 *
2555		 * @param {Texture} source - The texture to copy.
2556		 * @return {Texture} A reference to this instance.
2557		 */ copy(source) {
2558	        this.name = source.name;
2559	        this.source = source.source;
2560	        this.mipmaps = source.mipmaps.slice(0);
2561	        this.mapping = source.mapping;
2562	        this.channel = source.channel;
2563	        this.wrapS = source.wrapS;
2564	        this.wrapT = source.wrapT;
2565	        this.magFilter = source.magFilter;
2566	        this.minFilter = source.minFilter;
2567	        this.anisotropy = source.anisotropy;
2568	        this.format = source.format;
2569	        this.internalFormat = source.internalFormat;
2570	        this.type = source.type;
2571	        this.offset.copy(source.offset);
2572	        this.repeat.copy(source.repeat);
2573	        this.center.copy(source.center);
2574	        this.rotation = source.rotation;
2575	        this.matrixAutoUpdate = source.matrixAutoUpdate;
2576	        this.matrix.copy(source.matrix);
2577	        this.generateMipmaps = source.generateMipmaps;
2578	        this.premultiplyAlpha = source.premultiplyAlpha;
2579	        this.flipY = source.flipY;
2580	        this.unpackAlignment = source.unpackAlignment;
2581	        this.colorSpace = source.colorSpace;
2582	        this.renderTarget = source.renderTarget;
2583	        this.isRenderTargetTexture = source.isRenderTargetTexture;
2584	        this.userData = JSON.parse(JSON.stringify(source.userData));
2585	        this.needsUpdate = true;
2586	        return this;
2587	    }
2588	    /**
2589		 * Serializes the texture into JSON.
2590		 *
2591		 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
2592		 * @return {Object} A JSON object representing the serialized texture.
2593		 * @see {@link ObjectLoader#parse}
2594		 */ toJSON(meta) {
2595	        const isRootObject = meta === undefined || typeof meta === 'string';
2596	        if (!isRootObject && meta.textures[this.uuid] !== undefined) {
2597	            return meta.textures[this.uuid];
2598	        }
2599	        const output = {
2600	            metadata: {
2601	                version: 4.6,
2602	                type: 'Texture',
2603	                generator: 'Texture.toJSON'
2604	            },
2605	            uuid: this.uuid,
2606	            name: this.name,
2607	            image: this.source.toJSON(meta).uuid,
2608	            mapping: this.mapping,
2609	            channel: this.channel,
2610	            repeat: [
2611	                this.repeat.x,
2612	                this.repeat.y
2613	            ],
2614	            offset: [
2615	                this.offset.x,
2616	                this.offset.y
2617	            ],
2618	            center: [
2619	                this.center.x,
2620	                this.center.y
2621	            ],
2622	            rotation: this.rotation,
2623	            wrap: [
2624	                this.wrapS,
2625	                this.wrapT
2626	            ],
2627	            format: this.format,
2628	            internalFormat: this.internalFormat,
2629	            type: this.type,
2630	            colorSpace: this.colorSpace,
2631	            minFilter: this.minFilter,
2632	            magFilter: this.magFilter,
2633	            anisotropy: this.anisotropy,
2634	            flipY: this.flipY,
2635	            generateMipmaps: this.generateMipmaps,
2636	            premultiplyAlpha: this.premultiplyAlpha,
2637	            unpackAlignment: this.unpackAlignment
2638	        };
2639	        if (Object.keys(this.userData).length > 0) output.userData = this.userData;
2640	        if (!isRootObject) {
2641	            meta.textures[this.uuid] = output;
2642	        }
2643	        return output;
2644	    }
2645	    /**
2646		 * Frees the GPU-related resources allocated by this instance. Call this
2647		 * method whenever this instance is no longer used in your app.
2648		 *
2649		 * @fires Texture#dispose
2650		 */ dispose() {
2651	        /**
2652			 * Fires when the texture has been disposed of.
2653			 *
2654			 * @event Texture#dispose
2655			 * @type {Object}
2656			 */ this.dispatchEvent({
2657	            type: 'dispose'
2658	        });
2659	    }
2660	    /**
2661		 * Transforms the given uv vector with the textures uv transformation matrix.
2662		 *
2663		 * @param {Vector2} uv - The uv vector.
2664		 * @return {Vector2} The transformed uv vector.
2665		 */ transformUv(uv) {
2666	        if (this.mapping !== UVMapping) return uv;
2667	        uv.applyMatrix3(this.matrix);
2668	        if (uv.x < 0 || uv.x > 1) {
2669	            switch(this.wrapS){
2670	                case RepeatWrapping:
2671	                    uv.x = uv.x - Math.floor(uv.x);
2672	                    break;
2673	                case ClampToEdgeWrapping:
2674	                    uv.x = uv.x < 0 ? 0 : 1;
2675	                    break;
2676	                case MirroredRepeatWrapping:
2677	                    if (Math.abs(Math.floor(uv.x) % 2) === 1) {
2678	                        uv.x = Math.ceil(uv.x) - uv.x;
2679	                    } else {
2680	                        uv.x = uv.x - Math.floor(uv.x);
2681	                    }
2682	                    break;
2683	            }
2684	        }
2685	        if (uv.y < 0 || uv.y > 1) {
2686	            switch(this.wrapT){
2687	                case RepeatWrapping:
2688	                    uv.y = uv.y - Math.floor(uv.y);
2689	                    break;
2690	                case ClampToEdgeWrapping:
2691	                    uv.y = uv.y < 0 ? 0 : 1;
2692	                    break;
2693	                case MirroredRepeatWrapping:
2694	                    if (Math.abs(Math.floor(uv.y) % 2) === 1) {
2695	                        uv.y = Math.ceil(uv.y) - uv.y;
2696	                    } else {
2697	                        uv.y = uv.y - Math.floor(uv.y);
2698	                    }
2699	                    break;
2700	            }
2701	        }
2702	        if (this.flipY) {
2703	            uv.y = 1 - uv.y;
2704	        }
2705	        return uv;
2706	    }
2707	    /**
2708		 * Setting this property to `true` indicates the engine the texture
2709		 * must be updated in the next render. This triggers a texture upload
2710		 * to the GPU and ensures correct texture parameter configuration.
2711		 *
2712		 * @type {boolean}
2713		 * @default false
2714		 * @param {boolean} value
2715		 */ set needsUpdate(value) {
2716	        if (value === true) {
2717	            this.version++;
2718	            this.source.needsUpdate = true;
2719	        }
2720	    }
2721	    /**
2722		 * Setting this property to `true` indicates the engine the PMREM
2723		 * must be regenerated.
2724		 *
2725		 * @type {boolean}
2726		 * @default false
2727		 * @param {boolean} value
2728		 */ set needsPMREMUpdate(value) {
2729	        if (value === true) {
2730	            this.pmremVersion++;
2731	        }
2732	    }
2733	    /**
2734		 * Constructs a new texture.
2735		 *
2736		 * @param {?Object} [image=Texture.DEFAULT_IMAGE] - The image holding the texture data.
2737		 * @param {number} [mapping=Texture.DEFAULT_MAPPING] - The texture mapping.
2738		 * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value.
2739		 * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value.
2740		 * @param {number} [magFilter=LinearFilter] - The mag filter value.
2741		 * @param {number} [minFilter=LinearFilter] - The min filter value.
2742		 * @param {number} [format=RGBAFormat] - The min filter value.
2743		 * @param {number} [type=UnsignedByteType] - The min filter value.
2744		 * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The min filter value.
2745		 * @param {string} [colorSpace=NoColorSpace] - The min filter value.
2746		 */ constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = Texture.DEFAULT_ANISOTROPY, colorSpace = NoColorSpace){
2747	        super();
2748	        /**
2749			 * This flag can be used for type testing.
2750			 *
2751			 * @type {boolean}
2752			 * @readonly
2753			 * @default true
2754			 */ this.isTexture = true;
2755	        /**
2756			 * The ID of the texture.
2757			 *
2758			 * @name Texture#id
2759			 * @type {number}
2760			 * @readonly
2761			 */ Object.defineProperty(this, 'id', {
2762	            value: _textureId++
2763	        });
2764	        /**
2765			 * The UUID of the material.
2766			 *
2767			 * @type {string}
2768			 * @readonly
2769			 */ this.uuid = generateUUID();
2770	        /**
2771			 * The name of the material.
2772			 *
2773			 * @type {string}
2774			 */ this.name = '';
2775	        /**
2776			 * The data definition of a texture. A reference to the data source can be
2777			 * shared across textures. This is often useful in context of spritesheets
2778			 * where multiple textures render the same data but with different texture
2779			 * transformations.
2780			 *
2781			 * @type {Source}
2782			 */ this.source = new Source(image);
2783	        /**
2784			 * An array holding user-defined mipmaps.
2785			 *
2786			 * @type {Array<Object>}
2787			 */ this.mipmaps = [];
2788	        /**
2789			 * How the texture is applied to the object. The value `UVMapping`
2790			 * is the default, where texture or uv coordinates are used to apply the map.
2791			 *
2792			 * @type {(UVMapping|CubeReflectionMapping|CubeRefractionMapping|EquirectangularReflectionMapping|EquirectangularRefractionMapping|CubeUVReflectionMapping)}
2793			 * @default UVMapping
2794			*/ this.mapping = mapping;
2795	        /**
2796			 * Lets you select the uv attribute to map the texture to. `0` for `uv`,
2797			 * `1` for `uv1`, `2` for `uv2` and `3` for `uv3`.
2798			 *
2799			 * @type {number}
2800			 * @default 0
2801			 */ this.channel = 0;
2802	        /**
2803			 * This defines how the texture is wrapped horizontally and corresponds to
2804			 * *U* in UV mapping.
2805			 *
2806			 * @type {(RepeatWrapping|ClampToEdgeWrapping|MirroredRepeatWrapping)}
2807			 * @default ClampToEdgeWrapping
2808			 */ this.wrapS = wrapS;
2809	        /**
2810			 * This defines how the texture is wrapped horizontally and corresponds to
2811			 * *V* in UV mapping.
2812			 *
2813			 * @type {(RepeatWrapping|ClampToEdgeWrapping|MirroredRepeatWrapping)}
2814			 * @default ClampToEdgeWrapping
2815			 */ this.wrapT = wrapT;
2816	        /**
2817			 * How the texture is sampled when a texel covers more than one pixel.
2818			 *
2819			 * @type {(NearestFilter|NearestMipmapNearestFilter|NearestMipmapLinearFilter|LinearFilter|LinearMipmapNearestFilter|LinearMipmapLinearFilter)}
2820			 * @default LinearFilter
2821			 */ this.magFilter = magFilter;
2822	        /**
2823			 * How the texture is sampled when a texel covers less than one pixel.
2824			 *
2825			 * @type {(NearestFilter|NearestMipmapNearestFilter|NearestMipmapLinearFilter|LinearFilter|LinearMipmapNearestFilter|LinearMipmapLinearFilter)}
2826			 * @default LinearMipmapLinearFilter
2827			 */ this.minFilter = minFilter;
2828	        /**
2829			 * The number of samples taken along the axis through the pixel that has the
2830			 * highest density of texels. By default, this value is `1`. A higher value
2831			 * gives a less blurry result than a basic mipmap, at the cost of more
2832			 * texture samples being used.
2833			 *
2834			 * @type {number}
2835			 * @default 0
2836			 */ this.anisotropy = anisotropy;
2837	        /**
2838			 * The format of the texture.
2839			 *
2840			 * @type {number}
2841			 * @default RGBAFormat
2842			 */ this.format = format;
2843	        /**
2844			 * The default internal format is derived from {@link Texture#format} and {@link Texture#type} and
2845			 * defines how the texture data is going to be stored on the GPU.
2846			 *
2847			 * This property allows to overwrite the default format.
2848			 *
2849			 * @type {?string}
2850			 * @default null
2851			 */ this.internalFormat = null;
2852	        /**
2853			 * The data type of the texture.
2854			 *
2855			 * @type {number}
2856			 * @default UnsignedByteType
2857			 */ this.type = type;
2858	        /**
2859			 * How much a single repetition of the texture is offset from the beginning,
2860			 * in each direction U and V. Typical range is `0.0` to `1.0`.
2861			 *
2862			 * @type {Vector2}
2863			 * @default (0,0)
2864			 */ this.offset = new Vector2(0, 0);
2865	        /**
2866			 * How many times the texture is repeated across the surface, in each
2867			 * direction U and V. If repeat is set greater than `1` in either direction,
2868			 * the corresponding wrap parameter should also be set to `RepeatWrapping`
2869			 * or `MirroredRepeatWrapping` to achieve the desired tiling effect.
2870			 *
2871			 * @type {Vector2}
2872			 * @default (1,1)
2873			 */ this.repeat = new Vector2(1, 1);
2874	        /**
2875			 * The point around which rotation occurs. A value of `(0.5, 0.5)` corresponds
2876			 * to the center of the texture. Default is `(0, 0)`, the lower left.
2877			 *
2878			 * @type {Vector2}
2879			 * @default (0,0)
2880			 */ this.center = new Vector2(0, 0);
2881	        /**
2882			 * How much the texture is rotated around the center point, in radians.
2883			 * Positive values are counter-clockwise.
2884			 *
2885			 * @type {number}
2886			 * @default 0
2887			 */ this.rotation = 0;
2888	        /**
2889			 * Whether to update the texture's uv-transformation {@link Texture#matrix}
2890			 * from the properties {@link Texture#offset}, {@link Texture#repeat},
2891			 * {@link Texture#rotation}, and {@link Texture#center}.
2892			 *
2893			 * Set this to `false` if you are specifying the uv-transform matrix directly.
2894			 *
2895			 * @type {boolean}
2896			 * @default true
2897			 */ this.matrixAutoUpdate = true;
2898	        /**
2899			 * The uv-transformation matrix of the texture.
2900			 *
2901			 * @type {Matrix3}
2902			 */ this.matrix = new Matrix3();
2903	        /**
2904			 * Whether to generate mipmaps (if possible) for a texture.
2905			 *
2906			 * Set this to `false` if you are creating mipmaps manually.
2907			 *
2908			 * @type {boolean}
2909			 * @default true
2910			 */ this.generateMipmaps = true;
2911	        /**
2912			 * If set to `true`, the alpha channel, if present, is multiplied into the
2913			 * color channels when the texture is uploaded to the GPU.
2914			 *
2915			 * Note that this property has no effect when using `ImageBitmap`. You need to
2916			 * configure premultiply alpha on bitmap creation instead.
2917			 *
2918			 * @type {boolean}
2919			 * @default false
2920			 */ this.premultiplyAlpha = false;
vendor: 32,593 bytes, lines 2921-3863
2921	        /**
2922			 * If set to `true`, the texture is flipped along the vertical axis when
2923			 * uploaded to the GPU.
2924			 *
2925			 * Note that this property has no effect when using `ImageBitmap`. You need to
2926			 * configure the flip on bitmap creation instead.
2927			 *
2928			 * @type {boolean}
2929			 * @default true
2930			 */ this.flipY = true;
2931	        /**
2932			 * Specifies the alignment requirements for the start of each pixel row in memory.
2933			 * The allowable values are `1` (byte-alignment), `2` (rows aligned to even-numbered bytes),
2934			 * `4` (word-alignment), and `8` (rows start on double-word boundaries).
2935			 *
2936			 * @type {number}
2937			 * @default 4
2938			 */ this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
2939	        /**
2940			 * Textures containing color data should be annotated with `SRGBColorSpace` or `LinearSRGBColorSpace`.
2941			 *
2942			 * @type {string}
2943			 * @default NoColorSpace
2944			 */ this.colorSpace = colorSpace;
2945	        /**
2946			 * An object that can be used to store custom data about the texture. It
2947			 * should not hold references to functions as these will not be cloned.
2948			 *
2949			 * @type {Object}
2950			 */ this.userData = {};
2951	        /**
2952			 * This starts at `0` and counts how many times {@link Texture#needsUpdate} is set to `true`.
2953			 *
2954			 * @type {number}
2955			 * @readonly
2956			 * @default 0
2957			 */ this.version = 0;
2958	        /**
2959			 * A callback function, called when the texture is updated (e.g., when
2960			 * {@link Texture#needsUpdate} has been set to true and then the texture is used).
2961			 *
2962			 * @type {?Function}
2963			 * @default null
2964			 */ this.onUpdate = null;
2965	        /**
2966			 * An optional back reference to the textures render target.
2967			 *
2968			 * @type {?(RenderTarget|WebGLRenderTarget)}
2969			 * @default null
2970			 */ this.renderTarget = null;
2971	        /**
2972			 * Indicates whether a texture belongs to a render target or not.
2973			 *
2974			 * @type {boolean}
2975			 * @readonly
2976			 * @default false
2977			 */ this.isRenderTargetTexture = false;
2978	        /**
2979			 * Indicates whether this texture should be processed by `PMREMGenerator` or not
2980			 * (only relevant for render target textures).
2981			 *
2982			 * @type {number}
2983			 * @readonly
2984			 * @default 0
2985			 */ this.pmremVersion = 0;
2986	    }
2987	};
2988	/**
2989	 * The default image for all textures.
2990	 *
2991	 * @static
2992	 * @type {?Image}
2993	 * @default null
2994	 */ Texture$1.DEFAULT_IMAGE = null;
2995	/**
2996	 * The default mapping for all textures.
2997	 *
2998	 * @static
2999	 * @type {number}
3000	 * @default UVMapping
3001	 */ Texture$1.DEFAULT_MAPPING = UVMapping;
3002	/**
3003	 * The default anisotropy value for all textures.
3004	 *
3005	 * @static
3006	 * @type {number}
3007	 * @default 1
3008	 */ Texture$1.DEFAULT_ANISOTROPY = 1;
3009	/**
3010	 * Class representing a 4D vector. A 4D vector is an ordered quadruplet of numbers
3011	 * (labeled x, y, z and w), which can be used to represent a number of things, such as:
3012	 *
3013	 * - A point in 4D space.
3014	 * - A direction and length in 4D space. In three.js the length will
3015	 * always be the Euclidean distance(straight-line distance) from `(0, 0, 0, 0)` to `(x, y, z, w)`
3016	 * and the direction is also measured from `(0, 0, 0, 0)` towards `(x, y, z, w)`.
3017	 * - Any arbitrary ordered quadruplet of numbers.
3018	 *
3019	 * There are other things a 4D vector can be used to represent, however these
3020	 * are the most common uses in *three.js*.
3021	 *
3022	 * Iterating through a vector instance will yield its components `(x, y, z, w)` in
3023	 * the corresponding order.
3024	 * ```js
3025	 * const a = new THREE.Vector4( 0, 1, 0, 0 );
3026	 *
3027	 * //no arguments; will be initialised to (0, 0, 0, 1)
3028	 * const b = new THREE.Vector4( );
3029	 *
3030	 * const d = a.dot( b );
3031	 * ```
3032	 */ class Vector4 {
3033	    /**
3034		 * Alias for {@link Vector4#z}.
3035		 *
3036		 * @type {number}
3037		 */ get width() {
3038	        return this.z;
3039	    }
3040	    set width(value) {
3041	        this.z = value;
3042	    }
3043	    /**
3044		 * Alias for {@link Vector4#w}.
3045		 *
3046		 * @type {number}
3047		 */ get height() {
3048	        return this.w;
3049	    }
3050	    set height(value) {
3051	        this.w = value;
3052	    }
3053	    /**
3054		 * Sets the vector components.
3055		 *
3056		 * @param {number} x - The value of the x component.
3057		 * @param {number} y - The value of the y component.
3058		 * @param {number} z - The value of the z component.
3059		 * @param {number} w - The value of the w component.
3060		 * @return {Vector4} A reference to this vector.
3061		 */ set(x, y, z, w) {
3062	        this.x = x;
3063	        this.y = y;
3064	        this.z = z;
3065	        this.w = w;
3066	        return this;
3067	    }
3068	    /**
3069		 * Sets the vector components to the same value.
3070		 *
3071		 * @param {number} scalar - The value to set for all vector components.
3072		 * @return {Vector4} A reference to this vector.
3073		 */ setScalar(scalar) {
3074	        this.x = scalar;
3075	        this.y = scalar;
3076	        this.z = scalar;
3077	        this.w = scalar;
3078	        return this;
3079	    }
3080	    /**
3081		 * Sets the vector's x component to the given value
3082		 *
3083		 * @param {number} x - The value to set.
3084		 * @return {Vector4} A reference to this vector.
3085		 */ setX(x) {
3086	        this.x = x;
3087	        return this;
3088	    }
3089	    /**
3090		 * Sets the vector's y component to the given value
3091		 *
3092		 * @param {number} y - The value to set.
3093		 * @return {Vector4} A reference to this vector.
3094		 */ setY(y) {
3095	        this.y = y;
3096	        return this;
3097	    }
3098	    /**
3099		 * Sets the vector's z component to the given value
3100		 *
3101		 * @param {number} z - The value to set.
3102		 * @return {Vector4} A reference to this vector.
3103		 */ setZ(z) {
3104	        this.z = z;
3105	        return this;
3106	    }
3107	    /**
3108		 * Sets the vector's w component to the given value
3109		 *
3110		 * @param {number} w - The value to set.
3111		 * @return {Vector4} A reference to this vector.
3112		 */ setW(w) {
3113	        this.w = w;
3114	        return this;
3115	    }
3116	    /**
3117		 * Allows to set a vector component with an index.
3118		 *
3119		 * @param {number} index - The component index. `0` equals to x, `1` equals to y,
3120		 * `2` equals to z, `3` equals to w.
3121		 * @param {number} value - The value to set.
3122		 * @return {Vector4} A reference to this vector.
3123		 */ setComponent(index, value) {
3124	        switch(index){
3125	            case 0:
3126	                this.x = value;
3127	                break;
3128	            case 1:
3129	                this.y = value;
3130	                break;
3131	            case 2:
3132	                this.z = value;
3133	                break;
3134	            case 3:
3135	                this.w = value;
3136	                break;
3137	            default:
3138	                throw new Error('index is out of range: ' + index);
3139	        }
3140	        return this;
3141	    }
3142	    /**
3143		 * Returns the value of the vector component which matches the given index.
3144		 *
3145		 * @param {number} index - The component index. `0` equals to x, `1` equals to y,
3146		 * `2` equals to z, `3` equals to w.
3147		 * @return {number} A vector component value.
3148		 */ getComponent(index) {
3149	        switch(index){
3150	            case 0:
3151	                return this.x;
3152	            case 1:
3153	                return this.y;
3154	            case 2:
3155	                return this.z;
3156	            case 3:
3157	                return this.w;
3158	            default:
3159	                throw new Error('index is out of range: ' + index);
3160	        }
3161	    }
3162	    /**
3163		 * Returns a new vector with copied values from this instance.
3164		 *
3165		 * @return {Vector4} A clone of this instance.
3166		 */ clone() {
3167	        return new this.constructor(this.x, this.y, this.z, this.w);
3168	    }
3169	    /**
3170		 * Copies the values of the given vector to this instance.
3171		 *
3172		 * @param {Vector3|Vector4} v - The vector to copy.
3173		 * @return {Vector4} A reference to this vector.
3174		 */ copy(v) {
3175	        this.x = v.x;
3176	        this.y = v.y;
3177	        this.z = v.z;
3178	        this.w = v.w !== undefined ? v.w : 1;
3179	        return this;
3180	    }
3181	    /**
3182		 * Adds the given vector to this instance.
3183		 *
3184		 * @param {Vector4} v - The vector to add.
3185		 * @return {Vector4} A reference to this vector.
3186		 */ add(v) {
3187	        this.x += v.x;
3188	        this.y += v.y;
3189	        this.z += v.z;
3190	        this.w += v.w;
3191	        return this;
3192	    }
3193	    /**
3194		 * Adds the given scalar value to all components of this instance.
3195		 *
3196		 * @param {number} s - The scalar to add.
3197		 * @return {Vector4} A reference to this vector.
3198		 */ addScalar(s) {
3199	        this.x += s;
3200	        this.y += s;
3201	        this.z += s;
3202	        this.w += s;
3203	        return this;
3204	    }
3205	    /**
3206		 * Adds the given vectors and stores the result in this instance.
3207		 *
3208		 * @param {Vector4} a - The first vector.
3209		 * @param {Vector4} b - The second vector.
3210		 * @return {Vector4} A reference to this vector.
3211		 */ addVectors(a, b) {
3212	        this.x = a.x + b.x;
3213	        this.y = a.y + b.y;
3214	        this.z = a.z + b.z;
3215	        this.w = a.w + b.w;
3216	        return this;
3217	    }
3218	    /**
3219		 * Adds the given vector scaled by the given factor to this instance.
3220		 *
3221		 * @param {Vector4} v - The vector.
3222		 * @param {number} s - The factor that scales `v`.
3223		 * @return {Vector4} A reference to this vector.
3224		 */ addScaledVector(v, s) {
3225	        this.x += v.x * s;
3226	        this.y += v.y * s;
3227	        this.z += v.z * s;
3228	        this.w += v.w * s;
3229	        return this;
3230	    }
3231	    /**
3232		 * Subtracts the given vector from this instance.
3233		 *
3234		 * @param {Vector4} v - The vector to subtract.
3235		 * @return {Vector4} A reference to this vector.
3236		 */ sub(v) {
3237	        this.x -= v.x;
3238	        this.y -= v.y;
3239	        this.z -= v.z;
3240	        this.w -= v.w;
3241	        return this;
3242	    }
3243	    /**
3244		 * Subtracts the given scalar value from all components of this instance.
3245		 *
3246		 * @param {number} s - The scalar to subtract.
3247		 * @return {Vector4} A reference to this vector.
3248		 */ subScalar(s) {
3249	        this.x -= s;
3250	        this.y -= s;
3251	        this.z -= s;
3252	        this.w -= s;
3253	        return this;
3254	    }
3255	    /**
3256		 * Subtracts the given vectors and stores the result in this instance.
3257		 *
3258		 * @param {Vector4} a - The first vector.
3259		 * @param {Vector4} b - The second vector.
3260		 * @return {Vector4} A reference to this vector.
3261		 */ subVectors(a, b) {
3262	        this.x = a.x - b.x;
3263	        this.y = a.y - b.y;
3264	        this.z = a.z - b.z;
3265	        this.w = a.w - b.w;
3266	        return this;
3267	    }
3268	    /**
3269		 * Multiplies the given vector with this instance.
3270		 *
3271		 * @param {Vector4} v - The vector to multiply.
3272		 * @return {Vector4} A reference to this vector.
3273		 */ multiply(v) {
3274	        this.x *= v.x;
3275	        this.y *= v.y;
3276	        this.z *= v.z;
3277	        this.w *= v.w;
3278	        return this;
3279	    }
3280	    /**
3281		 * Multiplies the given scalar value with all components of this instance.
3282		 *
3283		 * @param {number} scalar - The scalar to multiply.
3284		 * @return {Vector4} A reference to this vector.
3285		 */ multiplyScalar(scalar) {
3286	        this.x *= scalar;
3287	        this.y *= scalar;
3288	        this.z *= scalar;
3289	        this.w *= scalar;
3290	        return this;
3291	    }
3292	    /**
3293		 * Multiplies this vector with the given 4x4 matrix.
3294		 *
3295		 * @param {Matrix4} m - The 4x4 matrix.
3296		 * @return {Vector4} A reference to this vector.
3297		 */ applyMatrix4(m) {
3298	        const x = this.x, y = this.y, z = this.z, w = this.w;
3299	        const e = m.elements;
3300	        this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
3301	        this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
3302	        this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
3303	        this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
3304	        return this;
3305	    }
3306	    /**
3307		 * Divides this instance by the given vector.
3308		 *
3309		 * @param {Vector4} v - The vector to divide.
3310		 * @return {Vector4} A reference to this vector.
3311		 */ divide(v) {
3312	        this.x /= v.x;
3313	        this.y /= v.y;
3314	        this.z /= v.z;
3315	        this.w /= v.w;
3316	        return this;
3317	    }
3318	    /**
3319		 * Divides this vector by the given scalar.
3320		 *
3321		 * @param {number} scalar - The scalar to divide.
3322		 * @return {Vector4} A reference to this vector.
3323		 */ divideScalar(scalar) {
3324	        return this.multiplyScalar(1 / scalar);
3325	    }
3326	    /**
3327		 * Sets the x, y and z components of this
3328		 * vector to the quaternion's axis and w to the angle.
3329		 *
3330		 * @param {Quaternion} q - The Quaternion to set.
3331		 * @return {Vector4} A reference to this vector.
3332		 */ setAxisAngleFromQuaternion(q) {
3333	        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
3334	        // q is assumed to be normalized
3335	        this.w = 2 * Math.acos(q.w);
3336	        const s = Math.sqrt(1 - q.w * q.w);
3337	        if (s < 0.0001) {
3338	            this.x = 1;
3339	            this.y = 0;
3340	            this.z = 0;
3341	        } else {
3342	            this.x = q.x / s;
3343	            this.y = q.y / s;
3344	            this.z = q.z / s;
3345	        }
3346	        return this;
3347	    }
3348	    /**
3349		 * Sets the x, y and z components of this
3350		 * vector to the axis of rotation and w to the angle.
3351		 *
3352		 * @param {Matrix4} m - A 4x4 matrix of which the upper left 3x3 matrix is a pure rotation matrix.
3353		 * @return {Vector4} A reference to this vector.
3354		 */ setAxisAngleFromRotationMatrix(m) {
3355	        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
3356	        // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
3357	        let angle, x, y, z; // variables for result
3358	        const epsilon = 0.01, epsilon2 = 0.1, te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10];
3359	        if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
3360	            // singularity found
3361	            // first check for identity matrix which must have +1 for all terms
3362	            // in leading diagonal and zero in other terms
3363	            if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
3364	                // this singularity is identity matrix so angle = 0
3365	                this.set(1, 0, 0, 0);
3366	                return this; // zero angle, arbitrary axis
3367	            }
3368	            // otherwise this singularity is angle = 180
3369	            angle = Math.PI;
3370	            const xx = (m11 + 1) / 2;
3371	            const yy = (m22 + 1) / 2;
3372	            const zz = (m33 + 1) / 2;
3373	            const xy = (m12 + m21) / 4;
3374	            const xz = (m13 + m31) / 4;
3375	            const yz = (m23 + m32) / 4;
3376	            if (xx > yy && xx > zz) {
3377	                // m11 is the largest diagonal term
3378	                if (xx < epsilon) {
3379	                    x = 0;
3380	                    y = 0.707106781;
3381	                    z = 0.707106781;
3382	                } else {
3383	                    x = Math.sqrt(xx);
3384	                    y = xy / x;
3385	                    z = xz / x;
3386	                }
3387	            } else if (yy > zz) {
3388	                // m22 is the largest diagonal term
3389	                if (yy < epsilon) {
3390	                    x = 0.707106781;
3391	                    y = 0;
3392	                    z = 0.707106781;
3393	                } else {
3394	                    y = Math.sqrt(yy);
3395	                    x = xy / y;
3396	                    z = yz / y;
3397	                }
3398	            } else {
3399	                // m33 is the largest diagonal term so base result on this
3400	                if (zz < epsilon) {
3401	                    x = 0.707106781;
3402	                    y = 0.707106781;
3403	                    z = 0;
3404	                } else {
3405	                    z = Math.sqrt(zz);
3406	                    x = xz / z;
3407	                    y = yz / z;
3408	                }
3409	            }
3410	            this.set(x, y, z, angle);
3411	            return this; // return 180 deg rotation
3412	        }
3413	        // as we have reached here there are no singularities so we can handle normally
3414	        let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize
3415	        if (Math.abs(s) < 0.001) s = 1;
3416	        // prevent divide by zero, should not happen if matrix is orthogonal and should be
3417	        // caught by singularity test above, but I've left it in just in case
3418	        this.x = (m32 - m23) / s;
3419	        this.y = (m13 - m31) / s;
3420	        this.z = (m21 - m12) / s;
3421	        this.w = Math.acos((m11 + m22 + m33 - 1) / 2);
3422	        return this;
3423	    }
3424	    /**
3425		 * Sets the vector components to the position elements of the
3426		 * given transformation matrix.
3427		 *
3428		 * @param {Matrix4} m - The 4x4 matrix.
3429		 * @return {Vector4} A reference to this vector.
3430		 */ setFromMatrixPosition(m) {
3431	        const e = m.elements;
3432	        this.x = e[12];
3433	        this.y = e[13];
3434	        this.z = e[14];
3435	        this.w = e[15];
3436	        return this;
3437	    }
3438	    /**
3439		 * If this vector's x, y, z or w value is greater than the given vector's x, y, z or w
3440		 * value, replace that value with the corresponding min value.
3441		 *
3442		 * @param {Vector4} v - The vector.
3443		 * @return {Vector4} A reference to this vector.
3444		 */ min(v) {
3445	        this.x = Math.min(this.x, v.x);
3446	        this.y = Math.min(this.y, v.y);
3447	        this.z = Math.min(this.z, v.z);
3448	        this.w = Math.min(this.w, v.w);
3449	        return this;
3450	    }
3451	    /**
3452		 * If this vector's x, y, z or w value is less than the given vector's x, y, z or w
3453		 * value, replace that value with the corresponding max value.
3454		 *
3455		 * @param {Vector4} v - The vector.
3456		 * @return {Vector4} A reference to this vector.
3457		 */ max(v) {
3458	        this.x = Math.max(this.x, v.x);
3459	        this.y = Math.max(this.y, v.y);
3460	        this.z = Math.max(this.z, v.z);
3461	        this.w = Math.max(this.w, v.w);
3462	        return this;
3463	    }
3464	    /**
3465		 * If this vector's x, y, z or w value is greater than the max vector's x, y, z or w
3466		 * value, it is replaced by the corresponding value.
3467		 * If this vector's x, y, z or w value is less than the min vector's x, y, z or w value,
3468		 * it is replaced by the corresponding value.
3469		 *
3470		 * @param {Vector4} min - The minimum x, y and z values.
3471		 * @param {Vector4} max - The maximum x, y and z values in the desired range.
3472		 * @return {Vector4} A reference to this vector.
3473		 */ clamp(min, max) {
3474	        // assumes min < max, componentwise
3475	        this.x = clamp$1(this.x, min.x, max.x);
3476	        this.y = clamp$1(this.y, min.y, max.y);
3477	        this.z = clamp$1(this.z, min.z, max.z);
3478	        this.w = clamp$1(this.w, min.w, max.w);
3479	        return this;
3480	    }
3481	    /**
3482		 * If this vector's x, y, z or w values are greater than the max value, they are
3483		 * replaced by the max value.
3484		 * If this vector's x, y, z or w values are less than the min value, they are
3485		 * replaced by the min value.
3486		 *
3487		 * @param {number} minVal - The minimum value the components will be clamped to.
3488		 * @param {number} maxVal - The maximum value the components will be clamped to.
3489		 * @return {Vector4} A reference to this vector.
3490		 */ clampScalar(minVal, maxVal) {
3491	        this.x = clamp$1(this.x, minVal, maxVal);
3492	        this.y = clamp$1(this.y, minVal, maxVal);
3493	        this.z = clamp$1(this.z, minVal, maxVal);
3494	        this.w = clamp$1(this.w, minVal, maxVal);
3495	        return this;
3496	    }
3497	    /**
3498		 * If this vector's length is greater than the max value, it is replaced by
3499		 * the max value.
3500		 * If this vector's length is less than the min value, it is replaced by the
3501		 * min value.
3502		 *
3503		 * @param {number} min - The minimum value the vector length will be clamped to.
3504		 * @param {number} max - The maximum value the vector length will be clamped to.
3505		 * @return {Vector4} A reference to this vector.
3506		 */ clampLength(min, max) {
3507	        const length = this.length();
3508	        return this.divideScalar(length || 1).multiplyScalar(clamp$1(length, min, max));
3509	    }
3510	    /**
3511		 * The components of this vector are rounded down to the nearest integer value.
3512		 *
3513		 * @return {Vector4} A reference to this vector.
3514		 */ floor() {
3515	        this.x = Math.floor(this.x);
3516	        this.y = Math.floor(this.y);
3517	        this.z = Math.floor(this.z);
3518	        this.w = Math.floor(this.w);
3519	        return this;
3520	    }
3521	    /**
3522		 * The components of this vector are rounded up to the nearest integer value.
3523		 *
3524		 * @return {Vector4} A reference to this vector.
3525		 */ ceil() {
3526	        this.x = Math.ceil(this.x);
3527	        this.y = Math.ceil(this.y);
3528	        this.z = Math.ceil(this.z);
3529	        this.w = Math.ceil(this.w);
3530	        return this;
3531	    }
3532	    /**
3533		 * The components of this vector are rounded to the nearest integer value
3534		 *
3535		 * @return {Vector4} A reference to this vector.
3536		 */ round() {
3537	        this.x = Math.round(this.x);
3538	        this.y = Math.round(this.y);
3539	        this.z = Math.round(this.z);
3540	        this.w = Math.round(this.w);
3541	        return this;
3542	    }
3543	    /**
3544		 * The components of this vector are rounded towards zero (up if negative,
3545		 * down if positive) to an integer value.
3546		 *
3547		 * @return {Vector4} A reference to this vector.
3548		 */ roundToZero() {
3549	        this.x = Math.trunc(this.x);
3550	        this.y = Math.trunc(this.y);
3551	        this.z = Math.trunc(this.z);
3552	        this.w = Math.trunc(this.w);
3553	        return this;
3554	    }
3555	    /**
3556		 * Inverts this vector - i.e. sets x = -x, y = -y, z = -z, w = -w.
3557		 *
3558		 * @return {Vector4} A reference to this vector.
3559		 */ negate() {
3560	        this.x = -this.x;
3561	        this.y = -this.y;
3562	        this.z = -this.z;
3563	        this.w = -this.w;
3564	        return this;
3565	    }
3566	    /**
3567		 * Calculates the dot product of the given vector with this instance.
3568		 *
3569		 * @param {Vector4} v - The vector to compute the dot product with.
3570		 * @return {number} The result of the dot product.
3571		 */ dot(v) {
3572	        return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
3573	    }
3574	    /**
3575		 * Computes the square of the Euclidean length (straight-line length) from
3576		 * (0, 0, 0, 0) to (x, y, z, w). If you are comparing the lengths of vectors, you should
3577		 * compare the length squared instead as it is slightly more efficient to calculate.
3578		 *
3579		 * @return {number} The square length of this vector.
3580		 */ lengthSq() {
3581	        return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
3582	    }
3583	    /**
3584		 * Computes the  Euclidean length (straight-line length) from (0, 0, 0, 0) to (x, y, z, w).
3585		 *
3586		 * @return {number} The length of this vector.
3587		 */ length() {
3588	        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
3589	    }
3590	    /**
3591		 * Computes the Manhattan length of this vector.
3592		 *
3593		 * @return {number} The length of this vector.
3594		 */ manhattanLength() {
3595	        return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
3596	    }
3597	    /**
3598		 * Converts this vector to a unit vector - that is, sets it equal to a vector
3599		 * with the same direction as this one, but with a vector length of `1`.
3600		 *
3601		 * @return {Vector4} A reference to this vector.
3602		 */ normalize() {
3603	        return this.divideScalar(this.length() || 1);
3604	    }
3605	    /**
3606		 * Sets this vector to a vector with the same direction as this one, but
3607		 * with the specified length.
3608		 *
3609		 * @param {number} length - The new length of this vector.
3610		 * @return {Vector4} A reference to this vector.
3611		 */ setLength(length) {
3612	        return this.normalize().multiplyScalar(length);
3613	    }
3614	    /**
3615		 * Linearly interpolates between the given vector and this instance, where
3616		 * alpha is the percent distance along the line - alpha = 0 will be this
3617		 * vector, and alpha = 1 will be the given one.
3618		 *
3619		 * @param {Vector4} v - The vector to interpolate towards.
3620		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
3621		 * @return {Vector4} A reference to this vector.
3622		 */ lerp(v, alpha) {
3623	        this.x += (v.x - this.x) * alpha;
3624	        this.y += (v.y - this.y) * alpha;
3625	        this.z += (v.z - this.z) * alpha;
3626	        this.w += (v.w - this.w) * alpha;
3627	        return this;
3628	    }
3629	    /**
3630		 * Linearly interpolates between the given vectors, where alpha is the percent
3631		 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
3632		 * be the second one. The result is stored in this instance.
3633		 *
3634		 * @param {Vector4} v1 - The first vector.
3635		 * @param {Vector4} v2 - The second vector.
3636		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
3637		 * @return {Vector4} A reference to this vector.
3638		 */ lerpVectors(v1, v2, alpha) {
3639	        this.x = v1.x + (v2.x - v1.x) * alpha;
3640	        this.y = v1.y + (v2.y - v1.y) * alpha;
3641	        this.z = v1.z + (v2.z - v1.z) * alpha;
3642	        this.w = v1.w + (v2.w - v1.w) * alpha;
3643	        return this;
3644	    }
3645	    /**
3646		 * Returns `true` if this vector is equal with the given one.
3647		 *
3648		 * @param {Vector4} v - The vector to test for equality.
3649		 * @return {boolean} Whether this vector is equal with the given one.
3650		 */ equals(v) {
3651	        return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w;
3652	    }
3653	    /**
3654		 * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`,
3655		 * z value to be `array[ offset + 2 ]`, w value to be `array[ offset + 3 ]`.
3656		 *
3657		 * @param {Array<number>} array - An array holding the vector component values.
3658		 * @param {number} [offset=0] - The offset into the array.
3659		 * @return {Vector4} A reference to this vector.
3660		 */ fromArray(array, offset = 0) {
3661	        this.x = array[offset];
3662	        this.y = array[offset + 1];
3663	        this.z = array[offset + 2];
3664	        this.w = array[offset + 3];
3665	        return this;
3666	    }
3667	    /**
3668		 * Writes the components of this vector to the given array. If no array is provided,
3669		 * the method returns a new instance.
3670		 *
3671		 * @param {Array<number>} [array=[]] - The target array holding the vector components.
3672		 * @param {number} [offset=0] - Index of the first element in the array.
3673		 * @return {Array<number>} The vector components.
3674		 */ toArray(array = [], offset = 0) {
3675	        array[offset] = this.x;
3676	        array[offset + 1] = this.y;
3677	        array[offset + 2] = this.z;
3678	        array[offset + 3] = this.w;
3679	        return array;
3680	    }
3681	    /**
3682		 * Sets the components of this vector from the given buffer attribute.
3683		 *
3684		 * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
3685		 * @param {number} index - The index into the attribute.
3686		 * @return {Vector4} A reference to this vector.
3687		 */ fromBufferAttribute(attribute, index) {
3688	        this.x = attribute.getX(index);
3689	        this.y = attribute.getY(index);
3690	        this.z = attribute.getZ(index);
3691	        this.w = attribute.getW(index);
3692	        return this;
3693	    }
3694	    /**
3695		 * Sets each component of this vector to a pseudo-random value between `0` and
3696		 * `1`, excluding `1`.
3697		 *
3698		 * @return {Vector4} A reference to this vector.
3699		 */ random() {
3700	        this.x = Math.random();
3701	        this.y = Math.random();
3702	        this.z = Math.random();
3703	        this.w = Math.random();
3704	        return this;
3705	    }
3706	    *[Symbol.iterator]() {
3707	        yield this.x;
3708	        yield this.y;
3709	        yield this.z;
3710	        yield this.w;
3711	    }
3712	    /**
3713		 * Constructs a new 4D vector.
3714		 *
3715		 * @param {number} [x=0] - The x value of this vector.
3716		 * @param {number} [y=0] - The y value of this vector.
3717		 * @param {number} [z=0] - The z value of this vector.
3718		 * @param {number} [w=1] - The w value of this vector.
3719		 */ constructor(x = 0, y = 0, z = 0, w = 1){
3720	        /**
3721			 * This flag can be used for type testing.
3722			 *
3723			 * @type {boolean}
3724			 * @readonly
3725			 * @default true
3726			 */ Vector4.prototype.isVector4 = true;
3727	        /**
3728			 * The x value of this vector.
3729			 *
3730			 * @type {number}
3731			 */ this.x = x;
3732	        /**
3733			 * The y value of this vector.
3734			 *
3735			 * @type {number}
3736			 */ this.y = y;
3737	        /**
3738			 * The z value of this vector.
3739			 *
3740			 * @type {number}
3741			 */ this.z = z;
3742	        /**
3743			 * The w value of this vector.
3744			 *
3745			 * @type {number}
3746			 */ this.w = w;
3747	    }
3748	}
3749	/*
3750	 In options, we can specify:
3751	 * Texture parameters for an auto-generated target texture
3752	 * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
3753	*/ class RenderTarget extends EventDispatcher {
3754	    get texture() {
3755	        return this.textures[0];
3756	    }
3757	    set texture(value) {
3758	        this.textures[0] = value;
3759	    }
3760	    set depthTexture(current) {
3761	        if (this._depthTexture !== null) this._depthTexture.renderTarget = null;
3762	        if (current !== null) current.renderTarget = this;
3763	        this._depthTexture = current;
3764	    }
3765	    get depthTexture() {
3766	        return this._depthTexture;
3767	    }
3768	    setSize(width, height, depth = 1) {
3769	        if (this.width !== width || this.height !== height || this.depth !== depth) {
3770	            this.width = width;
3771	            this.height = height;
3772	            this.depth = depth;
3773	            for(let i = 0, il = this.textures.length; i < il; i++){
3774	                this.textures[i].image.width = width;
3775	                this.textures[i].image.height = height;
3776	                this.textures[i].image.depth = depth;
3777	            }
3778	            this.dispose();
3779	        }
3780	        this.viewport.set(0, 0, width, height);
3781	        this.scissor.set(0, 0, width, height);
3782	    }
3783	    clone() {
3784	        return new this.constructor().copy(this);
3785	    }
3786	    copy(source) {
3787	        this.width = source.width;
3788	        this.height = source.height;
3789	        this.depth = source.depth;
3790	        this.scissor.copy(source.scissor);
3791	        this.scissorTest = source.scissorTest;
3792	        this.viewport.copy(source.viewport);
3793	        this.textures.length = 0;
3794	        for(let i = 0, il = source.textures.length; i < il; i++){
3795	            this.textures[i] = source.textures[i].clone();
3796	            this.textures[i].isRenderTargetTexture = true;
3797	            this.textures[i].renderTarget = this;
3798	            // ensure image object is not shared, see #20328
3799	            const image = Object.assign({}, source.textures[i].image);
3800	            this.textures[i].source = new Source(image);
3801	        }
3802	        this.depthBuffer = source.depthBuffer;
3803	        this.stencilBuffer = source.stencilBuffer;
3804	        this.resolveDepthBuffer = source.resolveDepthBuffer;
3805	        this.resolveStencilBuffer = source.resolveStencilBuffer;
3806	        if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
3807	        this.samples = source.samples;
3808	        return this;
3809	    }
3810	    dispose() {
3811	        this.dispatchEvent({
3812	            type: 'dispose'
3813	        });
3814	    }
3815	    constructor(width = 1, height = 1, options = {}){
3816	        super();
3817	        this.isRenderTarget = true;
3818	        this.width = width;
3819	        this.height = height;
3820	        this.depth = 1;
3821	        this.scissor = new Vector4(0, 0, width, height);
3822	        this.scissorTest = false;
3823	        this.viewport = new Vector4(0, 0, width, height);
3824	        const image = {
3825	            width: width,
3826	            height: height,
3827	            depth: 1
3828	        };
3829	        options = Object.assign({
3830	            generateMipmaps: false,
3831	            internalFormat: null,
3832	            minFilter: LinearFilter,
3833	            depthBuffer: true,
3834	            stencilBuffer: false,
3835	            resolveDepthBuffer: true,
3836	            resolveStencilBuffer: true,
3837	            depthTexture: null,
3838	            samples: 0,
3839	            count: 1
3840	        }, options);
3841	        const texture = new Texture$1(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace);
3842	        texture.flipY = false;
3843	        texture.generateMipmaps = options.generateMipmaps;
3844	        texture.internalFormat = options.internalFormat;
3845	        this.textures = [];
3846	        const count = options.count;
3847	        for(let i = 0; i < count; i++){
3848	            this.textures[i] = texture.clone();
3849	            this.textures[i].isRenderTargetTexture = true;
3850	            this.textures[i].renderTarget = this;
3851	        }
3852	        this.depthBuffer = options.depthBuffer;
3853	        this.stencilBuffer = options.stencilBuffer;
3854	        this.resolveDepthBuffer = options.resolveDepthBuffer;
3855	        this.resolveStencilBuffer = options.resolveStencilBuffer;
3856	        this._depthTexture = null;
3857	        this.depthTexture = options.depthTexture;
3858	        this.samples = options.samples;
3859	    }
3860	}
3861	class WebGLRenderTarget extends RenderTarget {
3862	    constructor(width = 1, height = 1, options = {}){
3863	        super(width, height, options);
vendor: 20,961 bytes, lines 3864-4419
3864	        this.isWebGLRenderTarget = true;
3865	    }
3866	}
3867	class DataArrayTexture extends Texture$1 {
3868	    addLayerUpdate(layerIndex) {
3869	        this.layerUpdates.add(layerIndex);
3870	    }
3871	    clearLayerUpdates() {
3872	        this.layerUpdates.clear();
3873	    }
3874	    constructor(data = null, width = 1, height = 1, depth = 1){
3875	        super(null);
3876	        this.isDataArrayTexture = true;
3877	        this.image = {
3878	            data,
3879	            width,
3880	            height,
3881	            depth
3882	        };
3883	        this.magFilter = NearestFilter;
3884	        this.minFilter = NearestFilter;
3885	        this.wrapR = ClampToEdgeWrapping;
3886	        this.generateMipmaps = false;
3887	        this.flipY = false;
3888	        this.unpackAlignment = 1;
3889	        this.layerUpdates = new Set();
3890	    }
3891	}
3892	class Data3DTexture extends Texture$1 {
3893	    constructor(data = null, width = 1, height = 1, depth = 1){
3894	        // We're going to add .setXXX() methods for setting properties later.
3895	        // Users can still set in Data3DTexture directly.
3896	        //
3897	        //	const texture = new THREE.Data3DTexture( data, width, height, depth );
3898	        // 	texture.anisotropy = 16;
3899	        //
3900	        // See #14839
3901	        super(null);
3902	        this.isData3DTexture = true;
3903	        this.image = {
3904	            data,
3905	            width,
3906	            height,
3907	            depth
3908	        };
3909	        this.magFilter = NearestFilter;
3910	        this.minFilter = NearestFilter;
3911	        this.wrapR = ClampToEdgeWrapping;
3912	        this.generateMipmaps = false;
3913	        this.flipY = false;
3914	        this.unpackAlignment = 1;
3915	    }
3916	}
3917	/**
3918	 * Class for representing a Quaternion. Quaternions are used in three.js to represent rotations.
3919	 *
3920	 * Iterating through a vector instance will yield its components `(x, y, z, w)` in
3921	 * the corresponding order.
3922	 *
3923	 * Note that three.js expects Quaternions to be normalized.
3924	 * ```js
3925	 * const quaternion = new THREE.Quaternion();
3926	 * quaternion.setFromAxisAngle( new THREE.Vector3( 0, 1, 0 ), Math.PI / 2 );
3927	 *
3928	 * const vector = new THREE.Vector3( 1, 0, 0 );
3929	 * vector.applyQuaternion( quaternion );
3930	 * ```
3931	 */ class Quaternion {
3932	    /**
3933		 * Interpolates between two quaternions via SLERP. This implementation assumes the
3934		 * quaternion data are managed  in flat arrays.
3935		 *
3936		 * @param {Array<number>} dst - The destination array.
3937		 * @param {number} dstOffset - An offset into the destination array.
3938		 * @param {Array<number>} src0 - The source array of the first quaternion.
3939		 * @param {number} srcOffset0 - An offset into the first source array.
3940		 * @param {Array<number>} src1 -  The source array of the second quaternion.
3941		 * @param {number} srcOffset1 - An offset into the second source array.
3942		 * @param {number} t - The interpolation factor in the range `[0,1]`.
3943		 * @see {@link Quaternion#slerp}
3944		 */ static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
3945	        // fuzz-free, array-based Quaternion SLERP operation
3946	        let x0 = src0[srcOffset0 + 0], y0 = src0[srcOffset0 + 1], z0 = src0[srcOffset0 + 2], w0 = src0[srcOffset0 + 3];
3947	        const x1 = src1[srcOffset1 + 0], y1 = src1[srcOffset1 + 1], z1 = src1[srcOffset1 + 2], w1 = src1[srcOffset1 + 3];
3948	        if (t === 0) {
3949	            dst[dstOffset + 0] = x0;
3950	            dst[dstOffset + 1] = y0;
3951	            dst[dstOffset + 2] = z0;
3952	            dst[dstOffset + 3] = w0;
3953	            return;
3954	        }
3955	        if (t === 1) {
3956	            dst[dstOffset + 0] = x1;
3957	            dst[dstOffset + 1] = y1;
3958	            dst[dstOffset + 2] = z1;
3959	            dst[dstOffset + 3] = w1;
3960	            return;
3961	        }
3962	        if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
3963	            let s = 1 - t;
3964	            const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1, dir = cos >= 0 ? 1 : -1, sqrSin = 1 - cos * cos;
3965	            // Skip the Slerp for tiny steps to avoid numeric problems:
3966	            if (sqrSin > Number.EPSILON) {
3967	                const sin = Math.sqrt(sqrSin), len = Math.atan2(sin, cos * dir);
3968	                s = Math.sin(s * len) / sin;
3969	                t = Math.sin(t * len) / sin;
3970	            }
3971	            const tDir = t * dir;
3972	            x0 = x0 * s + x1 * tDir;
3973	            y0 = y0 * s + y1 * tDir;
3974	            z0 = z0 * s + z1 * tDir;
3975	            w0 = w0 * s + w1 * tDir;
3976	            // Normalize in case we just did a lerp:
3977	            if (s === 1 - t) {
3978	                const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
3979	                x0 *= f;
3980	                y0 *= f;
3981	                z0 *= f;
3982	                w0 *= f;
3983	            }
3984	        }
3985	        dst[dstOffset] = x0;
3986	        dst[dstOffset + 1] = y0;
3987	        dst[dstOffset + 2] = z0;
3988	        dst[dstOffset + 3] = w0;
3989	    }
3990	    /**
3991		 * Multiplies two quaternions. This implementation assumes the quaternion data are managed
3992		 * in flat arrays.
3993		 *
3994		 * @param {Array<number>} dst - The destination array.
3995		 * @param {number} dstOffset - An offset into the destination array.
3996		 * @param {Array<number>} src0 - The source array of the first quaternion.
3997		 * @param {number} srcOffset0 - An offset into the first source array.
3998		 * @param {Array<number>} src1 -  The source array of the second quaternion.
3999		 * @param {number} srcOffset1 - An offset into the second source array.
4000		 * @return {Array<number>} The destination array.
4001		 * @see {@link Quaternion#multiplyQuaternions}.
4002		 */ static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
4003	        const x0 = src0[srcOffset0];
4004	        const y0 = src0[srcOffset0 + 1];
4005	        const z0 = src0[srcOffset0 + 2];
4006	        const w0 = src0[srcOffset0 + 3];
4007	        const x1 = src1[srcOffset1];
4008	        const y1 = src1[srcOffset1 + 1];
4009	        const z1 = src1[srcOffset1 + 2];
4010	        const w1 = src1[srcOffset1 + 3];
4011	        dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
4012	        dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
4013	        dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
4014	        dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
4015	        return dst;
4016	    }
4017	    /**
4018		 * The x value of this quaternion.
4019		 *
4020		 * @type {number}
4021		 * @default 0
4022		 */ get x() {
4023	        return this._x;
4024	    }
4025	    set x(value) {
4026	        this._x = value;
4027	        this._onChangeCallback();
4028	    }
4029	    /**
4030		 * The y value of this quaternion.
4031		 *
4032		 * @type {number}
4033		 * @default 0
4034		 */ get y() {
4035	        return this._y;
4036	    }
4037	    set y(value) {
4038	        this._y = value;
4039	        this._onChangeCallback();
4040	    }
4041	    /**
4042		 * The z value of this quaternion.
4043		 *
4044		 * @type {number}
4045		 * @default 0
4046		 */ get z() {
4047	        return this._z;
4048	    }
4049	    set z(value) {
4050	        this._z = value;
4051	        this._onChangeCallback();
4052	    }
4053	    /**
4054		 * The w value of this quaternion.
4055		 *
4056		 * @type {number}
4057		 * @default 1
4058		 */ get w() {
4059	        return this._w;
4060	    }
4061	    set w(value) {
4062	        this._w = value;
4063	        this._onChangeCallback();
4064	    }
4065	    /**
4066		 * Sets the quaternion components.
4067		 *
4068		 * @param {number} x - The x value of this quaternion.
4069		 * @param {number} y - The y value of this quaternion.
4070		 * @param {number} z - The z value of this quaternion.
4071		 * @param {number} w - The w value of this quaternion.
4072		 * @return {Quaternion} A reference to this quaternion.
4073		 */ set(x, y, z, w) {
4074	        this._x = x;
4075	        this._y = y;
4076	        this._z = z;
4077	        this._w = w;
4078	        this._onChangeCallback();
4079	        return this;
4080	    }
4081	    /**
4082		 * Returns a new quaternion with copied values from this instance.
4083		 *
4084		 * @return {Quaternion} A clone of this instance.
4085		 */ clone() {
4086	        return new this.constructor(this._x, this._y, this._z, this._w);
4087	    }
4088	    /**
4089		 * Copies the values of the given quaternion to this instance.
4090		 *
4091		 * @param {Quaternion} quaternion - The quaternion to copy.
4092		 * @return {Quaternion} A reference to this quaternion.
4093		 */ copy(quaternion) {
4094	        this._x = quaternion.x;
4095	        this._y = quaternion.y;
4096	        this._z = quaternion.z;
4097	        this._w = quaternion.w;
4098	        this._onChangeCallback();
4099	        return this;
4100	    }
4101	    /**
4102		 * Sets this quaternion from the rotation specified by the given
4103		 * Euler angles.
4104		 *
4105		 * @param {Euler} euler - The Euler angles.
4106		 * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
4107		 * @return {Quaternion} A reference to this quaternion.
4108		 */ setFromEuler(euler, update = true) {
4109	        const x = euler._x, y = euler._y, z = euler._z, order = euler._order;
4110	        // http://www.mathworks.com/matlabcentral/fileexchange/
4111	        // 	20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
4112	        //	content/SpinCalc.m
4113	        const cos = Math.cos;
4114	        const sin = Math.sin;
4115	        const c1 = cos(x / 2);
4116	        const c2 = cos(y / 2);
4117	        const c3 = cos(z / 2);
4118	        const s1 = sin(x / 2);
4119	        const s2 = sin(y / 2);
4120	        const s3 = sin(z / 2);
4121	        switch(order){
4122	            case 'XYZ':
4123	                this._x = s1 * c2 * c3 + c1 * s2 * s3;
4124	                this._y = c1 * s2 * c3 - s1 * c2 * s3;
4125	                this._z = c1 * c2 * s3 + s1 * s2 * c3;
4126	                this._w = c1 * c2 * c3 - s1 * s2 * s3;
4127	                break;
4128	            case 'YXZ':
4129	                this._x = s1 * c2 * c3 + c1 * s2 * s3;
4130	                this._y = c1 * s2 * c3 - s1 * c2 * s3;
4131	                this._z = c1 * c2 * s3 - s1 * s2 * c3;
4132	                this._w = c1 * c2 * c3 + s1 * s2 * s3;
4133	                break;
4134	            case 'ZXY':
4135	                this._x = s1 * c2 * c3 - c1 * s2 * s3;
4136	                this._y = c1 * s2 * c3 + s1 * c2 * s3;
4137	                this._z = c1 * c2 * s3 + s1 * s2 * c3;
4138	                this._w = c1 * c2 * c3 - s1 * s2 * s3;
4139	                break;
4140	            case 'ZYX':
4141	                this._x = s1 * c2 * c3 - c1 * s2 * s3;
4142	                this._y = c1 * s2 * c3 + s1 * c2 * s3;
4143	                this._z = c1 * c2 * s3 - s1 * s2 * c3;
4144	                this._w = c1 * c2 * c3 + s1 * s2 * s3;
4145	                break;
4146	            case 'YZX':
4147	                this._x = s1 * c2 * c3 + c1 * s2 * s3;
4148	                this._y = c1 * s2 * c3 + s1 * c2 * s3;
4149	                this._z = c1 * c2 * s3 - s1 * s2 * c3;
4150	                this._w = c1 * c2 * c3 - s1 * s2 * s3;
4151	                break;
4152	            case 'XZY':
4153	                this._x = s1 * c2 * c3 - c1 * s2 * s3;
4154	                this._y = c1 * s2 * c3 - s1 * c2 * s3;
4155	                this._z = c1 * c2 * s3 + s1 * s2 * c3;
4156	                this._w = c1 * c2 * c3 + s1 * s2 * s3;
4157	                break;
4158	            default:
4159	                console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order);
4160	        }
4161	        if (update === true) this._onChangeCallback();
4162	        return this;
4163	    }
4164	    /**
4165		 * Sets this quaternion from the given axis and angle.
4166		 *
4167		 * @param {Vector3} axis - The normalized axis.
4168		 * @param {number} angle - The angle in radians.
4169		 * @return {Quaternion} A reference to this quaternion.
4170		 */ setFromAxisAngle(axis, angle) {
4171	        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
4172	        const halfAngle = angle / 2, s = Math.sin(halfAngle);
4173	        this._x = axis.x * s;
4174	        this._y = axis.y * s;
4175	        this._z = axis.z * s;
4176	        this._w = Math.cos(halfAngle);
4177	        this._onChangeCallback();
4178	        return this;
4179	    }
4180	    /**
4181		 * Sets this quaternion from the given rotation matrix.
4182		 *
4183		 * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
4184		 * @return {Quaternion} A reference to this quaternion.
4185		 */ setFromRotationMatrix(m) {
4186	        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
4187	        // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
4188	        const te = m.elements, m11 = te[0], m12 = te[4], m13 = te[8], m21 = te[1], m22 = te[5], m23 = te[9], m31 = te[2], m32 = te[6], m33 = te[10], trace = m11 + m22 + m33;
4189	        if (trace > 0) {
4190	            const s = 0.5 / Math.sqrt(trace + 1.0);
4191	            this._w = 0.25 / s;
4192	            this._x = (m32 - m23) * s;
4193	            this._y = (m13 - m31) * s;
4194	            this._z = (m21 - m12) * s;
4195	        } else if (m11 > m22 && m11 > m33) {
4196	            const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
4197	            this._w = (m32 - m23) / s;
4198	            this._x = 0.25 * s;
4199	            this._y = (m12 + m21) / s;
4200	            this._z = (m13 + m31) / s;
4201	        } else if (m22 > m33) {
4202	            const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
4203	            this._w = (m13 - m31) / s;
4204	            this._x = (m12 + m21) / s;
4205	            this._y = 0.25 * s;
4206	            this._z = (m23 + m32) / s;
4207	        } else {
4208	            const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
4209	            this._w = (m21 - m12) / s;
4210	            this._x = (m13 + m31) / s;
4211	            this._y = (m23 + m32) / s;
4212	            this._z = 0.25 * s;
4213	        }
4214	        this._onChangeCallback();
4215	        return this;
4216	    }
4217	    /**
4218		 * Sets this quaternion to the rotation required to rotate the direction vector
4219		 * `vFrom` to the direction vector `vTo`.
4220		 *
4221		 * @param {Vector3} vFrom - The first (normalized) direction vector.
4222		 * @param {Vector3} vTo - The second (normalized) direction vector.
4223		 * @return {Quaternion} A reference to this quaternion.
4224		 */ setFromUnitVectors(vFrom, vTo) {
4225	        // assumes direction vectors vFrom and vTo are normalized
4226	        let r = vFrom.dot(vTo) + 1;
4227	        if (r < Number.EPSILON) {
4228	            // vFrom and vTo point in opposite directions
4229	            r = 0;
4230	            if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
4231	                this._x = -vFrom.y;
4232	                this._y = vFrom.x;
4233	                this._z = 0;
4234	                this._w = r;
4235	            } else {
4236	                this._x = 0;
4237	                this._y = -vFrom.z;
4238	                this._z = vFrom.y;
4239	                this._w = r;
4240	            }
4241	        } else {
4242	            // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
4243	            this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
4244	            this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
4245	            this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
4246	            this._w = r;
4247	        }
4248	        return this.normalize();
4249	    }
4250	    /**
4251		 * Returns the angle between this quaternion and the given one in radians.
4252		 *
4253		 * @param {Quaternion} q - The quaternion to compute the angle with.
4254		 * @return {number} The angle in radians.
4255		 */ angleTo(q) {
4256	        return 2 * Math.acos(Math.abs(clamp$1(this.dot(q), -1, 1)));
4257	    }
4258	    /**
4259		 * Rotates this quaternion by a given angular step to the given quaternion.
4260		 * The method ensures that the final quaternion will not overshoot `q`.
4261		 *
4262		 * @param {Quaternion} q - The target quaternion.
4263		 * @param {number} step - The angular step in radians.
4264		 * @return {Quaternion} A reference to this quaternion.
4265		 */ rotateTowards(q, step) {
4266	        const angle = this.angleTo(q);
4267	        if (angle === 0) return this;
4268	        const t = Math.min(1, step / angle);
4269	        this.slerp(q, t);
4270	        return this;
4271	    }
4272	    /**
4273		 * Sets this quaternion to the identity quaternion; that is, to the
4274		 * quaternion that represents "no rotation".
4275		 *
4276		 * @return {Quaternion} A reference to this quaternion.
4277		 */ identity() {
4278	        return this.set(0, 0, 0, 1);
4279	    }
4280	    /**
4281		 * Inverts this quaternion via {@link Quaternion#conjugate}. The
4282		 * quaternion is assumed to have unit length.
4283		 *
4284		 * @return {Quaternion} A reference to this quaternion.
4285		 */ invert() {
4286	        return this.conjugate();
4287	    }
4288	    /**
4289		 * Returns the rotational conjugate of this quaternion. The conjugate of a
4290		 * quaternion represents the same rotation in the opposite direction about
4291		 * the rotational axis.
4292		 *
4293		 * @return {Quaternion} A reference to this quaternion.
4294		 */ conjugate() {
4295	        this._x *= -1;
4296	        this._y *= -1;
4297	        this._z *= -1;
4298	        this._onChangeCallback();
4299	        return this;
4300	    }
4301	    /**
4302		 * Calculates the dot product of this quaternion and the given one.
4303		 *
4304		 * @param {Quaternion} v - The quaternion to compute the dot product with.
4305		 * @return {number} The result of the dot product.
4306		 */ dot(v) {
4307	        return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
4308	    }
4309	    /**
4310		 * Computes the squared Euclidean length (straight-line length) of this quaternion,
4311		 * considered as a 4 dimensional vector. This can be useful if you are comparing the
4312		 * lengths of two quaternions, as this is a slightly more efficient calculation than
4313		 * {@link Quaternion#length}.
4314		 *
4315		 * @return {number} The squared Euclidean length.
4316		 */ lengthSq() {
4317	        return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
4318	    }
4319	    /**
4320		 * Computes the Euclidean length (straight-line length) of this quaternion,
4321		 * considered as a 4 dimensional vector.
4322		 *
4323		 * @return {number} The Euclidean length.
4324		 */ length() {
4325	        return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
4326	    }
4327	    /**
4328		 * Normalizes this quaternion - that is, calculated the quaternion that performs
4329		 * the same rotation as this one, but has a length equal to `1`.
4330		 *
4331		 * @return {Quaternion} A reference to this quaternion.
4332		 */ normalize() {
4333	        let l = this.length();
4334	        if (l === 0) {
4335	            this._x = 0;
4336	            this._y = 0;
4337	            this._z = 0;
4338	            this._w = 1;
4339	        } else {
4340	            l = 1 / l;
4341	            this._x = this._x * l;
4342	            this._y = this._y * l;
4343	            this._z = this._z * l;
4344	            this._w = this._w * l;
4345	        }
4346	        this._onChangeCallback();
4347	        return this;
4348	    }
4349	    /**
4350		 * Multiplies this quaternion by the given one.
4351		 *
4352		 * @param {Quaternion} q - The quaternion.
4353		 * @return {Quaternion} A reference to this quaternion.
4354		 */ multiply(q) {
4355	        return this.multiplyQuaternions(this, q);
4356	    }
4357	    /**
4358		 * Pre-multiplies this quaternion by the given one.
4359		 *
4360		 * @param {Quaternion} q - The quaternion.
4361		 * @return {Quaternion} A reference to this quaternion.
4362		 */ premultiply(q) {
4363	        return this.multiplyQuaternions(q, this);
4364	    }
4365	    /**
4366		 * Multiplies the given quaternions and stores the result in this instance.
4367		 *
4368		 * @param {Quaternion} a - The first quaternion.
4369		 * @param {Quaternion} b - The second quaternion.
4370		 * @return {Quaternion} A reference to this quaternion.
4371		 */ multiplyQuaternions(a, b) {
4372	        // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
4373	        const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
4374	        const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
4375	        this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
4376	        this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
4377	        this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
4378	        this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
4379	        this._onChangeCallback();
4380	        return this;
4381	    }
4382	    /**
4383		 * Performs a spherical linear interpolation between quaternions.
4384		 *
4385		 * @param {Quaternion} qb - The target quaternion.
4386		 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
4387		 * @return {Quaternion} A reference to this quaternion.
4388		 */ slerp(qb, t) {
4389	        if (t === 0) return this;
4390	        if (t === 1) return this.copy(qb);
4391	        const x = this._x, y = this._y, z = this._z, w = this._w;
4392	        // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
4393	        let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
4394	        if (cosHalfTheta < 0) {
4395	            this._w = -qb._w;
4396	            this._x = -qb._x;
4397	            this._y = -qb._y;
4398	            this._z = -qb._z;
4399	            cosHalfTheta = -cosHalfTheta;
4400	        } else {
4401	            this.copy(qb);
4402	        }
4403	        if (cosHalfTheta >= 1.0) {
4404	            this._w = w;
4405	            this._x = x;
4406	            this._y = y;
4407	            this._z = z;
4408	            return this;
4409	        }
4410	        const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
4411	        if (sqrSinHalfTheta <= Number.EPSILON) {
4412	            const s = 1 - t;
4413	            this._w = s * w + t * this._w;
4414	            this._x = s * x + t * this._x;
4415	            this._y = s * y + t * this._y;
4416	            this._z = s * z + t * this._z;
4417	            this.normalize(); // normalize calls _onChangeCallback()
4418	            return this;
4419	        }
vendor: 5,430 bytes, lines 4420-4556
4420	        const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
4421	        const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
4422	        const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta, ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
4423	        this._w = w * ratioA + this._w * ratioB;
4424	        this._x = x * ratioA + this._x * ratioB;
4425	        this._y = y * ratioA + this._y * ratioB;
4426	        this._z = z * ratioA + this._z * ratioB;
4427	        this._onChangeCallback();
4428	        return this;
4429	    }
4430	    /**
4431		 * Performs a spherical linear interpolation between the given quaternions
4432		 * and stores the result in this quaternion.
4433		 *
4434		 * @param {Quaternion} qa - The source quaternion.
4435		 * @param {Quaternion} qb - The target quaternion.
4436		 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
4437		 * @return {Quaternion} A reference to this quaternion.
4438		 */ slerpQuaternions(qa, qb, t) {
4439	        return this.copy(qa).slerp(qb, t);
4440	    }
4441	    /**
4442		 * Sets this quaternion to a uniformly random, normalized quaternion.
4443		 *
4444		 * @return {Quaternion} A reference to this quaternion.
4445		 */ random() {
4446	        // Ken Shoemake
4447	        // Uniform random rotations
4448	        // D. Kirk, editor, Graphics Gems III, pages 124-132. Academic Press, New York, 1992.
4449	        const theta1 = 2 * Math.PI * Math.random();
4450	        const theta2 = 2 * Math.PI * Math.random();
4451	        const x0 = Math.random();
4452	        const r1 = Math.sqrt(1 - x0);
4453	        const r2 = Math.sqrt(x0);
4454	        return this.set(r1 * Math.sin(theta1), r1 * Math.cos(theta1), r2 * Math.sin(theta2), r2 * Math.cos(theta2));
4455	    }
4456	    /**
4457		 * Returns `true` if this quaternion is equal with the given one.
4458		 *
4459		 * @param {Quaternion} quaternion - The quaternion to test for equality.
4460		 * @return {boolean} Whether this quaternion is equal with the given one.
4461		 */ equals(quaternion) {
4462	        return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
4463	    }
4464	    /**
4465		 * Sets this quaternion's components from the given array.
4466		 *
4467		 * @param {Array<number>} array - An array holding the quaternion component values.
4468		 * @param {number} [offset=0] - The offset into the array.
4469		 * @return {Quaternion} A reference to this quaternion.
4470		 */ fromArray(array, offset = 0) {
4471	        this._x = array[offset];
4472	        this._y = array[offset + 1];
4473	        this._z = array[offset + 2];
4474	        this._w = array[offset + 3];
4475	        this._onChangeCallback();
4476	        return this;
4477	    }
4478	    /**
4479		 * Writes the components of this quaternion to the given array. If no array is provided,
4480		 * the method returns a new instance.
4481		 *
4482		 * @param {Array<number>} [array=[]] - The target array holding the quaternion components.
4483		 * @param {number} [offset=0] - Index of the first element in the array.
4484		 * @return {Array<number>} The quaternion components.
4485		 */ toArray(array = [], offset = 0) {
4486	        array[offset] = this._x;
4487	        array[offset + 1] = this._y;
4488	        array[offset + 2] = this._z;
4489	        array[offset + 3] = this._w;
4490	        return array;
4491	    }
4492	    /**
4493		 * Sets the components of this quaternion from the given buffer attribute.
4494		 *
4495		 * @param {BufferAttribute} attribute - The buffer attribute holding quaternion data.
4496		 * @param {number} index - The index into the attribute.
4497		 * @return {Quaternion} A reference to this quaternion.
4498		 */ fromBufferAttribute(attribute, index) {
4499	        this._x = attribute.getX(index);
4500	        this._y = attribute.getY(index);
4501	        this._z = attribute.getZ(index);
4502	        this._w = attribute.getW(index);
4503	        this._onChangeCallback();
4504	        return this;
4505	    }
4506	    /**
4507		 * This methods defines the serialization result of this class. Returns the
4508		 * numerical elements of this quaternion in an array of format `[x, y, z, w]`.
4509		 *
4510		 * @return {Array<number>} The serialized quaternion.
4511		 */ toJSON() {
4512	        return this.toArray();
4513	    }
4514	    _onChange(callback) {
4515	        this._onChangeCallback = callback;
4516	        return this;
4517	    }
4518	    _onChangeCallback() {}
4519	    *[Symbol.iterator]() {
4520	        yield this._x;
4521	        yield this._y;
4522	        yield this._z;
4523	        yield this._w;
4524	    }
4525	    /**
4526		 * Constructs a new quaternion.
4527		 *
4528		 * @param {number} [x=0] - The x value of this quaternion.
4529		 * @param {number} [y=0] - The y value of this quaternion.
4530		 * @param {number} [z=0] - The z value of this quaternion.
4531		 * @param {number} [w=1] - The w value of this quaternion.
4532		 */ constructor(x = 0, y = 0, z = 0, w = 1){
4533	        /**
4534			 * This flag can be used for type testing.
4535			 *
4536			 * @type {boolean}
4537			 * @readonly
4538			 * @default true
4539			 */ this.isQuaternion = true;
4540	        this._x = x;
4541	        this._y = y;
4542	        this._z = z;
4543	        this._w = w;
4544	    }
4545	}
4546	/**
4547	 * Class representing a 3D vector. A 3D vector is an ordered triplet of numbers
4548	 * (labeled x, y and z), which can be used to represent a number of things, such as:
4549	 *
4550	 * - A point in 3D space.
4551	 * - A direction and length in 3D space. In three.js the length will
4552	 * always be the Euclidean distance(straight-line distance) from `(0, 0, 0)` to `(x, y, z)`
4553	 * and the direction is also measured from `(0, 0, 0)` towards `(x, y, z)`.
4554	 * - Any arbitrary ordered triplet of numbers.
4555	 *
4556	 * There are other things a 3D vector can be used to represent, such as
vendor: 23,989 bytes, lines 4557-5245
4557	 * momentum vectors and so on, however these are the most
4558	 * common uses in three.js.
4559	 *
4560	 * Iterating through a vector instance will yield its components `(x, y, z)` in
4561	 * the corresponding order.
4562	 * ```js
4563	 * const a = new THREE.Vector3( 0, 1, 0 );
4564	 *
4565	 * //no arguments; will be initialised to (0, 0, 0)
4566	 * const b = new THREE.Vector3( );
4567	 *
4568	 * const d = a.distanceTo( b );
4569	 * ```
4570	 */ class Vector3 {
4571	    /**
4572		 * Sets the vector components.
4573		 *
4574		 * @param {number} x - The value of the x component.
4575		 * @param {number} y - The value of the y component.
4576		 * @param {number} z - The value of the z component.
4577		 * @return {Vector3} A reference to this vector.
4578		 */ set(x, y, z) {
4579	        if (z === undefined) z = this.z; // sprite.scale.set(x,y)
4580	        this.x = x;
4581	        this.y = y;
4582	        this.z = z;
4583	        return this;
4584	    }
4585	    /**
4586		 * Sets the vector components to the same value.
4587		 *
4588		 * @param {number} scalar - The value to set for all vector components.
4589		 * @return {Vector3} A reference to this vector.
4590		 */ setScalar(scalar) {
4591	        this.x = scalar;
4592	        this.y = scalar;
4593	        this.z = scalar;
4594	        return this;
4595	    }
4596	    /**
4597		 * Sets the vector's x component to the given value
4598		 *
4599		 * @param {number} x - The value to set.
4600		 * @return {Vector3} A reference to this vector.
4601		 */ setX(x) {
4602	        this.x = x;
4603	        return this;
4604	    }
4605	    /**
4606		 * Sets the vector's y component to the given value
4607		 *
4608		 * @param {number} y - The value to set.
4609		 * @return {Vector3} A reference to this vector.
4610		 */ setY(y) {
4611	        this.y = y;
4612	        return this;
4613	    }
4614	    /**
4615		 * Sets the vector's z component to the given value
4616		 *
4617		 * @param {number} z - The value to set.
4618		 * @return {Vector3} A reference to this vector.
4619		 */ setZ(z) {
4620	        this.z = z;
4621	        return this;
4622	    }
4623	    /**
4624		 * Allows to set a vector component with an index.
4625		 *
4626		 * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
4627		 * @param {number} value - The value to set.
4628		 * @return {Vector3} A reference to this vector.
4629		 */ setComponent(index, value) {
4630	        switch(index){
4631	            case 0:
4632	                this.x = value;
4633	                break;
4634	            case 1:
4635	                this.y = value;
4636	                break;
4637	            case 2:
4638	                this.z = value;
4639	                break;
4640	            default:
4641	                throw new Error('index is out of range: ' + index);
4642	        }
4643	        return this;
4644	    }
4645	    /**
4646		 * Returns the value of the vector component which matches the given index.
4647		 *
4648		 * @param {number} index - The component index. `0` equals to x, `1` equals to y, `2` equals to z.
4649		 * @return {number} A vector component value.
4650		 */ getComponent(index) {
4651	        switch(index){
4652	            case 0:
4653	                return this.x;
4654	            case 1:
4655	                return this.y;
4656	            case 2:
4657	                return this.z;
4658	            default:
4659	                throw new Error('index is out of range: ' + index);
4660	        }
4661	    }
4662	    /**
4663		 * Returns a new vector with copied values from this instance.
4664		 *
4665		 * @return {Vector3} A clone of this instance.
4666		 */ clone() {
4667	        return new this.constructor(this.x, this.y, this.z);
4668	    }
4669	    /**
4670		 * Copies the values of the given vector to this instance.
4671		 *
4672		 * @param {Vector3} v - The vector to copy.
4673		 * @return {Vector3} A reference to this vector.
4674		 */ copy(v) {
4675	        this.x = v.x;
4676	        this.y = v.y;
4677	        this.z = v.z;
4678	        return this;
4679	    }
4680	    /**
4681		 * Adds the given vector to this instance.
4682		 *
4683		 * @param {Vector3} v - The vector to add.
4684		 * @return {Vector3} A reference to this vector.
4685		 */ add(v) {
4686	        this.x += v.x;
4687	        this.y += v.y;
4688	        this.z += v.z;
4689	        return this;
4690	    }
4691	    /**
4692		 * Adds the given scalar value to all components of this instance.
4693		 *
4694		 * @param {number} s - The scalar to add.
4695		 * @return {Vector3} A reference to this vector.
4696		 */ addScalar(s) {
4697	        this.x += s;
4698	        this.y += s;
4699	        this.z += s;
4700	        return this;
4701	    }
4702	    /**
4703		 * Adds the given vectors and stores the result in this instance.
4704		 *
4705		 * @param {Vector3} a - The first vector.
4706		 * @param {Vector3} b - The second vector.
4707		 * @return {Vector3} A reference to this vector.
4708		 */ addVectors(a, b) {
4709	        this.x = a.x + b.x;
4710	        this.y = a.y + b.y;
4711	        this.z = a.z + b.z;
4712	        return this;
4713	    }
4714	    /**
4715		 * Adds the given vector scaled by the given factor to this instance.
4716		 *
4717		 * @param {Vector3|Vector4} v - The vector.
4718		 * @param {number} s - The factor that scales `v`.
4719		 * @return {Vector3} A reference to this vector.
4720		 */ addScaledVector(v, s) {
4721	        this.x += v.x * s;
4722	        this.y += v.y * s;
4723	        this.z += v.z * s;
4724	        return this;
4725	    }
4726	    /**
4727		 * Subtracts the given vector from this instance.
4728		 *
4729		 * @param {Vector3} v - The vector to subtract.
4730		 * @return {Vector3} A reference to this vector.
4731		 */ sub(v) {
4732	        this.x -= v.x;
4733	        this.y -= v.y;
4734	        this.z -= v.z;
4735	        return this;
4736	    }
4737	    /**
4738		 * Subtracts the given scalar value from all components of this instance.
4739		 *
4740		 * @param {number} s - The scalar to subtract.
4741		 * @return {Vector3} A reference to this vector.
4742		 */ subScalar(s) {
4743	        this.x -= s;
4744	        this.y -= s;
4745	        this.z -= s;
4746	        return this;
4747	    }
4748	    /**
4749		 * Subtracts the given vectors and stores the result in this instance.
4750		 *
4751		 * @param {Vector3} a - The first vector.
4752		 * @param {Vector3} b - The second vector.
4753		 * @return {Vector3} A reference to this vector.
4754		 */ subVectors(a, b) {
4755	        this.x = a.x - b.x;
4756	        this.y = a.y - b.y;
4757	        this.z = a.z - b.z;
4758	        return this;
4759	    }
4760	    /**
4761		 * Multiplies the given vector with this instance.
4762		 *
4763		 * @param {Vector3} v - The vector to multiply.
4764		 * @return {Vector3} A reference to this vector.
4765		 */ multiply(v) {
4766	        this.x *= v.x;
4767	        this.y *= v.y;
4768	        this.z *= v.z;
4769	        return this;
4770	    }
4771	    /**
4772		 * Multiplies the given scalar value with all components of this instance.
4773		 *
4774		 * @param {number} scalar - The scalar to multiply.
4775		 * @return {Vector3} A reference to this vector.
4776		 */ multiplyScalar(scalar) {
4777	        this.x *= scalar;
4778	        this.y *= scalar;
4779	        this.z *= scalar;
4780	        return this;
4781	    }
4782	    /**
4783		 * Multiplies the given vectors and stores the result in this instance.
4784		 *
4785		 * @param {Vector3} a - The first vector.
4786		 * @param {Vector3} b - The second vector.
4787		 * @return {Vector3} A reference to this vector.
4788		 */ multiplyVectors(a, b) {
4789	        this.x = a.x * b.x;
4790	        this.y = a.y * b.y;
4791	        this.z = a.z * b.z;
4792	        return this;
4793	    }
4794	    /**
4795		 * Applies the given Euler rotation to this vector.
4796		 *
4797		 * @param {Euler} euler - The Euler angles.
4798		 * @return {Vector3} A reference to this vector.
4799		 */ applyEuler(euler) {
4800	        return this.applyQuaternion(_quaternion$4.setFromEuler(euler));
4801	    }
4802	    /**
4803		 * Applies a rotation specified by an axis and an angle to this vector.
4804		 *
4805		 * @param {Vector3} axis - A normalized vector representing the rotation axis.
4806		 * @param {number} angle - The angle in radians.
4807		 * @return {Vector3} A reference to this vector.
4808		 */ applyAxisAngle(axis, angle) {
4809	        return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));
4810	    }
4811	    /**
4812		 * Multiplies this vector with the given 3x3 matrix.
4813		 *
4814		 * @param {Matrix3} m - The 3x3 matrix.
4815		 * @return {Vector3} A reference to this vector.
4816		 */ applyMatrix3(m) {
4817	        const x = this.x, y = this.y, z = this.z;
4818	        const e = m.elements;
4819	        this.x = e[0] * x + e[3] * y + e[6] * z;
4820	        this.y = e[1] * x + e[4] * y + e[7] * z;
4821	        this.z = e[2] * x + e[5] * y + e[8] * z;
4822	        return this;
4823	    }
4824	    /**
4825		 * Multiplies this vector by the given normal matrix and normalizes
4826		 * the result.
4827		 *
4828		 * @param {Matrix3} m - The normal matrix.
4829		 * @return {Vector3} A reference to this vector.
4830		 */ applyNormalMatrix(m) {
4831	        return this.applyMatrix3(m).normalize();
4832	    }
4833	    /**
4834		 * Multiplies this vector (with an implicit 1 in the 4th dimension) by m, and
4835		 * divides by perspective.
4836		 *
4837		 * @param {Matrix4} m - The matrix to apply.
4838		 * @return {Vector3} A reference to this vector.
4839		 */ applyMatrix4(m) {
4840	        const x = this.x, y = this.y, z = this.z;
4841	        const e = m.elements;
4842	        const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
4843	        this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w;
4844	        this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w;
4845	        this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w;
4846	        return this;
4847	    }
4848	    /**
4849		 * Applies the given Quaternion to this vector.
4850		 *
4851		 * @param {Quaternion} q - The Quaternion.
4852		 * @return {Vector3} A reference to this vector.
4853		 */ applyQuaternion(q) {
4854	        // quaternion q is assumed to have unit length
4855	        const vx = this.x, vy = this.y, vz = this.z;
4856	        const qx = q.x, qy = q.y, qz = q.z, qw = q.w;
4857	        // t = 2 * cross( q.xyz, v );
4858	        const tx = 2 * (qy * vz - qz * vy);
4859	        const ty = 2 * (qz * vx - qx * vz);
4860	        const tz = 2 * (qx * vy - qy * vx);
4861	        // v + q.w * t + cross( q.xyz, t );
4862	        this.x = vx + qw * tx + qy * tz - qz * ty;
4863	        this.y = vy + qw * ty + qz * tx - qx * tz;
4864	        this.z = vz + qw * tz + qx * ty - qy * tx;
4865	        return this;
4866	    }
4867	    /**
4868		 * Projects this vector from world space into the camera's normalized
4869		 * device coordinate (NDC) space.
4870		 *
4871		 * @param {Camera} camera - The camera.
4872		 * @return {Vector3} A reference to this vector.
4873		 */ project(camera) {
4874	        return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
4875	    }
4876	    /**
4877		 * Unprojects this vector from the camera's normalized device coordinate (NDC)
4878		 * space into world space.
4879		 *
4880		 * @param {Camera} camera - The camera.
4881		 * @return {Vector3} A reference to this vector.
4882		 */ unproject(camera) {
4883	        return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
4884	    }
4885	    /**
4886		 * Transforms the direction of this vector by a matrix (the upper left 3 x 3
4887		 * subset of the given 4x4 matrix and then normalizes the result.
4888		 *
4889		 * @param {Matrix4} m - The matrix.
4890		 * @return {Vector3} A reference to this vector.
4891		 */ transformDirection(m) {
4892	        // input: THREE.Matrix4 affine matrix
4893	        // vector interpreted as a direction
4894	        const x = this.x, y = this.y, z = this.z;
4895	        const e = m.elements;
4896	        this.x = e[0] * x + e[4] * y + e[8] * z;
4897	        this.y = e[1] * x + e[5] * y + e[9] * z;
4898	        this.z = e[2] * x + e[6] * y + e[10] * z;
4899	        return this.normalize();
4900	    }
4901	    /**
4902		 * Divides this instance by the given vector.
4903		 *
4904		 * @param {Vector3} v - The vector to divide.
4905		 * @return {Vector3} A reference to this vector.
4906		 */ divide(v) {
4907	        this.x /= v.x;
4908	        this.y /= v.y;
4909	        this.z /= v.z;
4910	        return this;
4911	    }
4912	    /**
4913		 * Divides this vector by the given scalar.
4914		 *
4915		 * @param {number} scalar - The scalar to divide.
4916		 * @return {Vector3} A reference to this vector.
4917		 */ divideScalar(scalar) {
4918	        return this.multiplyScalar(1 / scalar);
4919	    }
4920	    /**
4921		 * If this vector's x, y or z value is greater than the given vector's x, y or z
4922		 * value, replace that value with the corresponding min value.
4923		 *
4924		 * @param {Vector3} v - The vector.
4925		 * @return {Vector3} A reference to this vector.
4926		 */ min(v) {
4927	        this.x = Math.min(this.x, v.x);
4928	        this.y = Math.min(this.y, v.y);
4929	        this.z = Math.min(this.z, v.z);
4930	        return this;
4931	    }
4932	    /**
4933		 * If this vector's x, y or z value is less than the given vector's x, y or z
4934		 * value, replace that value with the corresponding max value.
4935		 *
4936		 * @param {Vector3} v - The vector.
4937		 * @return {Vector3} A reference to this vector.
4938		 */ max(v) {
4939	        this.x = Math.max(this.x, v.x);
4940	        this.y = Math.max(this.y, v.y);
4941	        this.z = Math.max(this.z, v.z);
4942	        return this;
4943	    }
4944	    /**
4945		 * If this vector's x, y or z value is greater than the max vector's x, y or z
4946		 * value, it is replaced by the corresponding value.
4947		 * If this vector's x, y or z value is less than the min vector's x, y or z value,
4948		 * it is replaced by the corresponding value.
4949		 *
4950		 * @param {Vector3} min - The minimum x, y and z values.
4951		 * @param {Vector3} max - The maximum x, y and z values in the desired range.
4952		 * @return {Vector3} A reference to this vector.
4953		 */ clamp(min, max) {
4954	        // assumes min < max, componentwise
4955	        this.x = clamp$1(this.x, min.x, max.x);
4956	        this.y = clamp$1(this.y, min.y, max.y);
4957	        this.z = clamp$1(this.z, min.z, max.z);
4958	        return this;
4959	    }
4960	    /**
4961		 * If this vector's x, y or z values are greater than the max value, they are
4962		 * replaced by the max value.
4963		 * If this vector's x, y or z values are less than the min value, they are
4964		 * replaced by the min value.
4965		 *
4966		 * @param {number} minVal - The minimum value the components will be clamped to.
4967		 * @param {number} maxVal - The maximum value the components will be clamped to.
4968		 * @return {Vector3} A reference to this vector.
4969		 */ clampScalar(minVal, maxVal) {
4970	        this.x = clamp$1(this.x, minVal, maxVal);
4971	        this.y = clamp$1(this.y, minVal, maxVal);
4972	        this.z = clamp$1(this.z, minVal, maxVal);
4973	        return this;
4974	    }
4975	    /**
4976		 * If this vector's length is greater than the max value, it is replaced by
4977		 * the max value.
4978		 * If this vector's length is less than the min value, it is replaced by the
4979		 * min value.
4980		 *
4981		 * @param {number} min - The minimum value the vector length will be clamped to.
4982		 * @param {number} max - The maximum value the vector length will be clamped to.
4983		 * @return {Vector3} A reference to this vector.
4984		 */ clampLength(min, max) {
4985	        const length = this.length();
4986	        return this.divideScalar(length || 1).multiplyScalar(clamp$1(length, min, max));
4987	    }
4988	    /**
4989		 * The components of this vector are rounded down to the nearest integer value.
4990		 *
4991		 * @return {Vector3} A reference to this vector.
4992		 */ floor() {
4993	        this.x = Math.floor(this.x);
4994	        this.y = Math.floor(this.y);
4995	        this.z = Math.floor(this.z);
4996	        return this;
4997	    }
4998	    /**
4999		 * The components of this vector are rounded up to the nearest integer value.
5000		 *
5001		 * @return {Vector3} A reference to this vector.
5002		 */ ceil() {
5003	        this.x = Math.ceil(this.x);
5004	        this.y = Math.ceil(this.y);
5005	        this.z = Math.ceil(this.z);
5006	        return this;
5007	    }
5008	    /**
5009		 * The components of this vector are rounded to the nearest integer value
5010		 *
5011		 * @return {Vector3} A reference to this vector.
5012		 */ round() {
5013	        this.x = Math.round(this.x);
5014	        this.y = Math.round(this.y);
5015	        this.z = Math.round(this.z);
5016	        return this;
5017	    }
5018	    /**
5019		 * The components of this vector are rounded towards zero (up if negative,
5020		 * down if positive) to an integer value.
5021		 *
5022		 * @return {Vector3} A reference to this vector.
5023		 */ roundToZero() {
5024	        this.x = Math.trunc(this.x);
5025	        this.y = Math.trunc(this.y);
5026	        this.z = Math.trunc(this.z);
5027	        return this;
5028	    }
5029	    /**
5030		 * Inverts this vector - i.e. sets x = -x, y = -y and z = -z.
5031		 *
5032		 * @return {Vector3} A reference to this vector.
5033		 */ negate() {
5034	        this.x = -this.x;
5035	        this.y = -this.y;
5036	        this.z = -this.z;
5037	        return this;
5038	    }
5039	    /**
5040		 * Calculates the dot product of the given vector with this instance.
5041		 *
5042		 * @param {Vector3} v - The vector to compute the dot product with.
5043		 * @return {number} The result of the dot product.
5044		 */ dot(v) {
5045	        return this.x * v.x + this.y * v.y + this.z * v.z;
5046	    }
5047	    // TODO lengthSquared?
5048	    /**
5049		 * Computes the square of the Euclidean length (straight-line length) from
5050		 * (0, 0, 0) to (x, y, z). If you are comparing the lengths of vectors, you should
5051		 * compare the length squared instead as it is slightly more efficient to calculate.
5052		 *
5053		 * @return {number} The square length of this vector.
5054		 */ lengthSq() {
5055	        return this.x * this.x + this.y * this.y + this.z * this.z;
5056	    }
5057	    /**
5058		 * Computes the  Euclidean length (straight-line length) from (0, 0, 0) to (x, y, z).
5059		 *
5060		 * @return {number} The length of this vector.
5061		 */ length() {
5062	        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
5063	    }
5064	    /**
5065		 * Computes the Manhattan length of this vector.
5066		 *
5067		 * @return {number} The length of this vector.
5068		 */ manhattanLength() {
5069	        return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
5070	    }
5071	    /**
5072		 * Converts this vector to a unit vector - that is, sets it equal to a vector
5073		 * with the same direction as this one, but with a vector length of `1`.
5074		 *
5075		 * @return {Vector3} A reference to this vector.
5076		 */ normalize() {
5077	        return this.divideScalar(this.length() || 1);
5078	    }
5079	    /**
5080		 * Sets this vector to a vector with the same direction as this one, but
5081		 * with the specified length.
5082		 *
5083		 * @param {number} length - The new length of this vector.
5084		 * @return {Vector3} A reference to this vector.
5085		 */ setLength(length) {
5086	        return this.normalize().multiplyScalar(length);
5087	    }
5088	    /**
5089		 * Linearly interpolates between the given vector and this instance, where
5090		 * alpha is the percent distance along the line - alpha = 0 will be this
5091		 * vector, and alpha = 1 will be the given one.
5092		 *
5093		 * @param {Vector3} v - The vector to interpolate towards.
5094		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
5095		 * @return {Vector3} A reference to this vector.
5096		 */ lerp(v, alpha) {
5097	        this.x += (v.x - this.x) * alpha;
5098	        this.y += (v.y - this.y) * alpha;
5099	        this.z += (v.z - this.z) * alpha;
5100	        return this;
5101	    }
5102	    /**
5103		 * Linearly interpolates between the given vectors, where alpha is the percent
5104		 * distance along the line - alpha = 0 will be first vector, and alpha = 1 will
5105		 * be the second one. The result is stored in this instance.
5106		 *
5107		 * @param {Vector3} v1 - The first vector.
5108		 * @param {Vector3} v2 - The second vector.
5109		 * @param {number} alpha - The interpolation factor, typically in the closed interval `[0, 1]`.
5110		 * @return {Vector3} A reference to this vector.
5111		 */ lerpVectors(v1, v2, alpha) {
5112	        this.x = v1.x + (v2.x - v1.x) * alpha;
5113	        this.y = v1.y + (v2.y - v1.y) * alpha;
5114	        this.z = v1.z + (v2.z - v1.z) * alpha;
5115	        return this;
5116	    }
5117	    /**
5118		 * Calculates the cross product of the given vector with this instance.
5119		 *
5120		 * @param {Vector3} v - The vector to compute the cross product with.
5121		 * @return {Vector3} The result of the cross product.
5122		 */ cross(v) {
5123	        return this.crossVectors(this, v);
5124	    }
5125	    /**
5126		 * Calculates the cross product of the given vectors and stores the result
5127		 * in this instance.
5128		 *
5129		 * @param {Vector3} a - The first vector.
5130		 * @param {Vector3} b - The second vector.
5131		 * @return {Vector3} A reference to this vector.
5132		 */ crossVectors(a, b) {
5133	        const ax = a.x, ay = a.y, az = a.z;
5134	        const bx = b.x, by = b.y, bz = b.z;
5135	        this.x = ay * bz - az * by;
5136	        this.y = az * bx - ax * bz;
5137	        this.z = ax * by - ay * bx;
5138	        return this;
5139	    }
5140	    /**
5141		 * Projects this vector onto the given one.
5142		 *
5143		 * @param {Vector3} v - The vector to project to.
5144		 * @return {Vector3} A reference to this vector.
5145		 */ projectOnVector(v) {
5146	        const denominator = v.lengthSq();
5147	        if (denominator === 0) return this.set(0, 0, 0);
5148	        const scalar = v.dot(this) / denominator;
5149	        return this.copy(v).multiplyScalar(scalar);
5150	    }
5151	    /**
5152		 * Projects this vector onto a plane by subtracting this
5153		 * vector projected onto the plane's normal from this vector.
5154		 *
5155		 * @param {Vector3} planeNormal - The plane normal.
5156		 * @return {Vector3} A reference to this vector.
5157		 */ projectOnPlane(planeNormal) {
5158	        _vector$c.copy(this).projectOnVector(planeNormal);
5159	        return this.sub(_vector$c);
5160	    }
5161	    /**
5162		 * Reflects this vector off a plane orthogonal to the given normal vector.
5163		 *
5164		 * @param {Vector3} normal - The (normalized) normal vector.
5165		 * @return {Vector3} A reference to this vector.
5166		 */ reflect(normal) {
5167	        return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));
5168	    }
5169	    /**
5170		 * Returns the angle between the given vector and this instance in radians.
5171		 *
5172		 * @param {Vector3} v - The vector to compute the angle with.
5173		 * @return {number} The angle in radians.
5174		 */ angleTo(v) {
5175	        const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
5176	        if (denominator === 0) return Math.PI / 2;
5177	        const theta = this.dot(v) / denominator;
5178	        // clamp, to handle numerical problems
5179	        return Math.acos(clamp$1(theta, -1, 1));
5180	    }
5181	    /**
5182		 * Computes the distance from the given vector to this instance.
5183		 *
5184		 * @param {Vector3} v - The vector to compute the distance to.
5185		 * @return {number} The distance.
5186		 */ distanceTo(v) {
5187	        return Math.sqrt(this.distanceToSquared(v));
5188	    }
5189	    /**
5190		 * Computes the squared distance from the given vector to this instance.
5191		 * If you are just comparing the distance with another distance, you should compare
5192		 * the distance squared instead as it is slightly more efficient to calculate.
5193		 *
5194		 * @param {Vector3} v - The vector to compute the squared distance to.
5195		 * @return {number} The squared distance.
5196		 */ distanceToSquared(v) {
5197	        const dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z;
5198	        return dx * dx + dy * dy + dz * dz;
5199	    }
5200	    /**
5201		 * Computes the Manhattan distance from the given vector to this instance.
5202		 *
5203		 * @param {Vector3} v - The vector to compute the Manhattan distance to.
5204		 * @return {number} The Manhattan distance.
5205		 */ manhattanDistanceTo(v) {
5206	        return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);
5207	    }
5208	    /**
5209		 * Sets the vector components from the given spherical coordinates.
5210		 *
5211		 * @param {Spherical} s - The spherical coordinates.
5212		 * @return {Vector3} A reference to this vector.
5213		 */ setFromSpherical(s) {
5214	        return this.setFromSphericalCoords(s.radius, s.phi, s.theta);
5215	    }
5216	    /**
5217		 * Sets the vector components from the given spherical coordinates.
5218		 *
5219		 * @param {number} radius - The radius.
5220		 * @param {number} phi - The phi angle in radians.
5221		 * @param {number} theta - The theta angle in radians.
5222		 * @return {Vector3} A reference to this vector.
5223		 */ setFromSphericalCoords(radius, phi, theta) {
5224	        const sinPhiRadius = Math.sin(phi) * radius;
5225	        this.x = sinPhiRadius * Math.sin(theta);
5226	        this.y = Math.cos(phi) * radius;
5227	        this.z = sinPhiRadius * Math.cos(theta);
5228	        return this;
5229	    }
5230	    /**
5231		 * Sets the vector components from the given cylindrical coordinates.
5232		 *
5233		 * @param {Cylindrical} c - The cylindrical coordinates.
5234		 * @return {Vector3} A reference to this vector.
5235		 */ setFromCylindrical(c) {
5236	        return this.setFromCylindricalCoords(c.radius, c.theta, c.y);
5237	    }
5238	    /**
5239		 * Sets the vector components from the given cylindrical coordinates.
5240		 *
5241		 * @param {number} radius - The radius.
5242		 * @param {number} theta - The theta angle in radians.
5243		 * @param {number} y - The y value.
5244		 * @return {Vector3} A reference to this vector.
5245		 */ setFromCylindricalCoords(radius, theta, y) {
vendor: 10,316 bytes, lines 5246-5543
5246	        this.x = radius * Math.sin(theta);
5247	        this.y = y;
5248	        this.z = radius * Math.cos(theta);
5249	        return this;
5250	    }
5251	    /**
5252		 * Sets the vector components to the position elements of the
5253		 * given transformation matrix.
5254		 *
5255		 * @param {Matrix4} m - The 4x4 matrix.
5256		 * @return {Vector3} A reference to this vector.
5257		 */ setFromMatrixPosition(m) {
5258	        const e = m.elements;
5259	        this.x = e[12];
5260	        this.y = e[13];
5261	        this.z = e[14];
5262	        return this;
5263	    }
5264	    /**
5265		 * Sets the vector components to the scale elements of the
5266		 * given transformation matrix.
5267		 *
5268		 * @param {Matrix4} m - The 4x4 matrix.
5269		 * @return {Vector3} A reference to this vector.
5270		 */ setFromMatrixScale(m) {
5271	        const sx = this.setFromMatrixColumn(m, 0).length();
5272	        const sy = this.setFromMatrixColumn(m, 1).length();
5273	        const sz = this.setFromMatrixColumn(m, 2).length();
5274	        this.x = sx;
5275	        this.y = sy;
5276	        this.z = sz;
5277	        return this;
5278	    }
5279	    /**
5280		 * Sets the vector components from the specified matrix column.
5281		 *
5282		 * @param {Matrix4} m - The 4x4 matrix.
5283		 * @param {number} index - The column index.
5284		 * @return {Vector3} A reference to this vector.
5285		 */ setFromMatrixColumn(m, index) {
5286	        return this.fromArray(m.elements, index * 4);
5287	    }
5288	    /**
5289		 * Sets the vector components from the specified matrix column.
5290		 *
5291		 * @param {Matrix3} m - The 3x3 matrix.
5292		 * @param {number} index - The column index.
5293		 * @return {Vector3} A reference to this vector.
5294		 */ setFromMatrix3Column(m, index) {
5295	        return this.fromArray(m.elements, index * 3);
5296	    }
5297	    /**
5298		 * Sets the vector components from the given Euler angles.
5299		 *
5300		 * @param {Euler} e - The Euler angles to set.
5301		 * @return {Vector3} A reference to this vector.
5302		 */ setFromEuler(e) {
5303	        this.x = e._x;
5304	        this.y = e._y;
5305	        this.z = e._z;
5306	        return this;
5307	    }
5308	    /**
5309		 * Sets the vector components from the RGB components of the
5310		 * given color.
5311		 *
5312		 * @param {Color} c - The color to set.
5313		 * @return {Vector3} A reference to this vector.
5314		 */ setFromColor(c) {
5315	        this.x = c.r;
5316	        this.y = c.g;
5317	        this.z = c.b;
5318	        return this;
5319	    }
5320	    /**
5321		 * Returns `true` if this vector is equal with the given one.
5322		 *
5323		 * @param {Vector3} v - The vector to test for equality.
5324		 * @return {boolean} Whether this vector is equal with the given one.
5325		 */ equals(v) {
5326	        return v.x === this.x && v.y === this.y && v.z === this.z;
5327	    }
5328	    /**
5329		 * Sets this vector's x value to be `array[ offset ]`, y value to be `array[ offset + 1 ]`
5330		 * and z value to be `array[ offset + 2 ]`.
5331		 *
5332		 * @param {Array<number>} array - An array holding the vector component values.
5333		 * @param {number} [offset=0] - The offset into the array.
5334		 * @return {Vector3} A reference to this vector.
5335		 */ fromArray(array, offset = 0) {
5336	        this.x = array[offset];
5337	        this.y = array[offset + 1];
5338	        this.z = array[offset + 2];
5339	        return this;
5340	    }
5341	    /**
5342		 * Writes the components of this vector to the given array. If no array is provided,
5343		 * the method returns a new instance.
5344		 *
5345		 * @param {Array<number>} [array=[]] - The target array holding the vector components.
5346		 * @param {number} [offset=0] - Index of the first element in the array.
5347		 * @return {Array<number>} The vector components.
5348		 */ toArray(array = [], offset = 0) {
5349	        array[offset] = this.x;
5350	        array[offset + 1] = this.y;
5351	        array[offset + 2] = this.z;
5352	        return array;
5353	    }
5354	    /**
5355		 * Sets the components of this vector from the given buffer attribute.
5356		 *
5357		 * @param {BufferAttribute} attribute - The buffer attribute holding vector data.
5358		 * @param {number} index - The index into the attribute.
5359		 * @return {Vector3} A reference to this vector.
5360		 */ fromBufferAttribute(attribute, index) {
5361	        this.x = attribute.getX(index);
5362	        this.y = attribute.getY(index);
5363	        this.z = attribute.getZ(index);
5364	        return this;
5365	    }
5366	    /**
5367		 * Sets each component of this vector to a pseudo-random value between `0` and
5368		 * `1`, excluding `1`.
5369		 *
5370		 * @return {Vector3} A reference to this vector.
5371		 */ random() {
5372	        this.x = Math.random();
5373	        this.y = Math.random();
5374	        this.z = Math.random();
5375	        return this;
5376	    }
5377	    /**
5378		 * Sets this vector to a uniformly random point on a unit sphere.
5379		 *
5380		 * @return {Vector3} A reference to this vector.
5381		 */ randomDirection() {
5382	        // https://mathworld.wolfram.com/SpherePointPicking.html
5383	        const theta = Math.random() * Math.PI * 2;
5384	        const u = Math.random() * 2 - 1;
5385	        const c = Math.sqrt(1 - u * u);
5386	        this.x = c * Math.cos(theta);
5387	        this.y = u;
5388	        this.z = c * Math.sin(theta);
5389	        return this;
5390	    }
5391	    *[Symbol.iterator]() {
5392	        yield this.x;
5393	        yield this.y;
5394	        yield this.z;
5395	    }
5396	    /**
5397		 * Constructs a new 3D vector.
5398		 *
5399		 * @param {number} [x=0] - The x value of this vector.
5400		 * @param {number} [y=0] - The y value of this vector.
5401		 * @param {number} [z=0] - The z value of this vector.
5402		 */ constructor(x = 0, y = 0, z = 0){
5403	        /**
5404			 * This flag can be used for type testing.
5405			 *
5406			 * @type {boolean}
5407			 * @readonly
5408			 * @default true
5409			 */ Vector3.prototype.isVector3 = true;
5410	        /**
5411			 * The x value of this vector.
5412			 *
5413			 * @type {number}
5414			 */ this.x = x;
5415	        /**
5416			 * The y value of this vector.
5417			 *
5418			 * @type {number}
5419			 */ this.y = y;
5420	        /**
5421			 * The z value of this vector.
5422			 *
5423			 * @type {number}
5424			 */ this.z = z;
5425	    }
5426	}
5427	const _vector$c = /*@__PURE__*/ new Vector3();
5428	const _quaternion$4 = /*@__PURE__*/ new Quaternion();
5429	/**
5430	 * Represents an axis-aligned bounding box (AABB) in 3D space.
5431	 */ class Box3 {
5432	    /**
5433		 * Sets the lower and upper boundaries of this box.
5434		 * Please note that this method only copies the values from the given objects.
5435		 *
5436		 * @param {Vector3} min - The lower boundary of the box.
5437		 * @param {Vector3} max - The upper boundary of the box.
5438		 * @return {Box3} A reference to this bounding box.
5439		 */ set(min, max) {
5440	        this.min.copy(min);
5441	        this.max.copy(max);
5442	        return this;
5443	    }
5444	    /**
5445		 * Sets the upper and lower bounds of this box so it encloses the position data
5446		 * in the given array.
5447		 *
5448		 * @param {Array<number>} array - An array holding 3D position data.
5449		 * @return {Box3} A reference to this bounding box.
5450		 */ setFromArray(array) {
5451	        this.makeEmpty();
5452	        for(let i = 0, il = array.length; i < il; i += 3){
5453	            this.expandByPoint(_vector$b.fromArray(array, i));
5454	        }
5455	        return this;
5456	    }
5457	    /**
5458		 * Sets the upper and lower bounds of this box so it encloses the position data
5459		 * in the given buffer attribute.
5460		 *
5461		 * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data.
5462		 * @return {Box3} A reference to this bounding box.
5463		 */ setFromBufferAttribute(attribute) {
5464	        this.makeEmpty();
5465	        for(let i = 0, il = attribute.count; i < il; i++){
5466	            this.expandByPoint(_vector$b.fromBufferAttribute(attribute, i));
5467	        }
5468	        return this;
5469	    }
5470	    /**
5471		 * Sets the upper and lower bounds of this box so it encloses the position data
5472		 * in the given array.
5473		 *
5474		 * @param {Array<Vector3>} points - An array holding 3D position data as instances of {@link Vector3}.
5475		 * @return {Box3} A reference to this bounding box.
5476		 */ setFromPoints(points) {
5477	        this.makeEmpty();
5478	        for(let i = 0, il = points.length; i < il; i++){
5479	            this.expandByPoint(points[i]);
5480	        }
5481	        return this;
5482	    }
5483	    /**
5484		 * Centers this box on the given center vector and sets this box's width, height and
5485		 * depth to the given size values.
5486		 *
5487		 * @param {Vector3} center - The center of the box.
5488		 * @param {Vector3} size - The x, y and z dimensions of the box.
5489		 * @return {Box3} A reference to this bounding box.
5490		 */ setFromCenterAndSize(center, size) {
5491	        const halfSize = _vector$b.copy(size).multiplyScalar(0.5);
5492	        this.min.copy(center).sub(halfSize);
5493	        this.max.copy(center).add(halfSize);
5494	        return this;
5495	    }
5496	    /**
5497		 * Computes the world-axis-aligned bounding box for the given 3D object
5498		 * (including its children), accounting for the object's, and children's,
5499		 * world transforms. The function may result in a larger box than strictly necessary.
5500		 *
5501		 * @param {Object3D} object - The 3D object to compute the bounding box for.
5502		 * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest
5503		 * world-axis-aligned bounding box at the expense of more computation.
5504		 * @return {Box3} A reference to this bounding box.
5505		 */ setFromObject(object, precise = false) {
5506	        this.makeEmpty();
5507	        return this.expandByObject(object, precise);
5508	    }
5509	    /**
5510		 * Returns a new box with copied values from this instance.
5511		 *
5512		 * @return {Box3} A clone of this instance.
5513		 */ clone() {
5514	        return new this.constructor().copy(this);
5515	    }
5516	    /**
5517		 * Copies the values of the given box to this instance.
5518		 *
5519		 * @param {Box3} box - The box to copy.
5520		 * @return {Box3} A reference to this bounding box.
5521		 */ copy(box) {
5522	        this.min.copy(box.min);
5523	        this.max.copy(box.max);
5524	        return this;
5525	    }
5526	    /**
5527		 * Makes this box empty which means in encloses a zero space in 3D.
5528		 *
5529		 * @return {Box3} A reference to this bounding box.
5530		 */ makeEmpty() {
5531	        this.min.x = this.min.y = this.min.z = +Infinity;
5532	        this.max.x = this.max.y = this.max.z = -Infinity;
5533	        return this;
5534	    }
5535	    /**
5536		 * Returns true if this box includes zero points within its bounds.
5537		 * Note that a box with equal lower and upper bounds still includes one
5538		 * point, the one both bounds share.
5539		 *
5540		 * @return {boolean} Whether this box is empty or not.
5541		 */ isEmpty() {
5542	        // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
5543	        return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
vendor: 4,397 bytes, lines 5544-5638
5544	    }
5545	    /**
5546		 * Returns the center point of this box.
5547		 *
5548		 * @param {Vector3} target - The target vector that is used to store the method's result.
5549		 * @return {Vector3} The center point.
5550		 */ getCenter(target) {
5551	        return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
5552	    }
5553	    /**
5554		 * Returns the dimensions of this box.
5555		 *
5556		 * @param {Vector3} target - The target vector that is used to store the method's result.
5557		 * @return {Vector3} The size.
5558		 */ getSize(target) {
5559	        return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);
5560	    }
5561	    /**
5562		 * Expands the boundaries of this box to include the given point.
5563		 *
5564		 * @param {Vector3} point - The point that should be included by the bounding box.
5565		 * @return {Box3} A reference to this bounding box.
5566		 */ expandByPoint(point) {
5567	        this.min.min(point);
5568	        this.max.max(point);
5569	        return this;
5570	    }
5571	    /**
5572		 * Expands this box equilaterally by the given vector. The width of this
5573		 * box will be expanded by the x component of the vector in both
5574		 * directions. The height of this box will be expanded by the y component of
5575		 * the vector in both directions. The depth of this box will be
5576		 * expanded by the z component of the vector in both directions.
5577		 *
5578		 * @param {Vector3} vector - The vector that should expand the bounding box.
5579		 * @return {Box3} A reference to this bounding box.
5580		 */ expandByVector(vector) {
5581	        this.min.sub(vector);
5582	        this.max.add(vector);
5583	        return this;
5584	    }
5585	    /**
5586		 * Expands each dimension of the box by the given scalar. If negative, the
5587		 * dimensions of the box will be contracted.
5588		 *
5589		 * @param {number} scalar - The scalar value that should expand the bounding box.
5590		 * @return {Box3} A reference to this bounding box.
5591		 */ expandByScalar(scalar) {
5592	        this.min.addScalar(-scalar);
5593	        this.max.addScalar(scalar);
5594	        return this;
5595	    }
5596	    /**
5597		 * Expands the boundaries of this box to include the given 3D object and
5598		 * its children, accounting for the object's, and children's, world
5599		 * transforms. The function may result in a larger box than strictly
5600		 * necessary (unless the precise parameter is set to true).
5601		 *
5602		 * @param {Object3D} object - The 3D object that should expand the bounding box.
5603		 * @param {boolean} precise - If set to `true`, the method expands the bounding box
5604		 * as little as necessary at the expense of more computation.
5605		 * @return {Box3} A reference to this bounding box.
5606		 */ expandByObject(object, precise = false) {
5607	        // Computes the world-axis-aligned bounding box of an object (including its children),
5608	        // accounting for both the object's, and children's, world transforms
5609	        object.updateWorldMatrix(false, false);
5610	        const geometry = object.geometry;
5611	        if (geometry !== undefined) {
5612	            const positionAttribute = geometry.getAttribute('position');
5613	            // precise AABB computation based on vertex data requires at least a position attribute.
5614	            // instancing isn't supported so far and uses the normal (conservative) code path.
5615	            if (precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true) {
5616	                for(let i = 0, l = positionAttribute.count; i < l; i++){
5617	                    if (object.isMesh === true) {
5618	                        object.getVertexPosition(i, _vector$b);
5619	                    } else {
5620	                        _vector$b.fromBufferAttribute(positionAttribute, i);
5621	                    }
5622	                    _vector$b.applyMatrix4(object.matrixWorld);
5623	                    this.expandByPoint(_vector$b);
5624	                }
5625	            } else {
5626	                if (object.boundingBox !== undefined) {
5627	                    // object-level bounding box
5628	                    if (object.boundingBox === null) {
5629	                        object.computeBoundingBox();
5630	                    }
5631	                    _box$4.copy(object.boundingBox);
5632	                } else {
5633	                    // geometry-level bounding box
5634	                    if (geometry.boundingBox === null) {
5635	                        geometry.computeBoundingBox();
5636	                    }
5637	                    _box$4.copy(geometry.boundingBox);
5638	                }
vendor: 42,855 bytes, lines 5639-6694
5639	                _box$4.applyMatrix4(object.matrixWorld);
5640	                this.union(_box$4);
5641	            }
5642	        }
5643	        const children = object.children;
5644	        for(let i = 0, l = children.length; i < l; i++){
5645	            this.expandByObject(children[i], precise);
5646	        }
5647	        return this;
5648	    }
5649	    /**
5650		 * Returns `true` if the given point lies within or on the boundaries of this box.
5651		 *
5652		 * @param {Vector3} point - The point to test.
5653		 * @return {boolean} Whether the bounding box contains the given point or not.
5654		 */ containsPoint(point) {
5655	        return point.x >= this.min.x && point.x <= this.max.x && point.y >= this.min.y && point.y <= this.max.y && point.z >= this.min.z && point.z <= this.max.z;
5656	    }
5657	    /**
5658		 * Returns `true` if this bounding box includes the entirety of the given bounding box.
5659		 * If this box and the given one are identical, this function also returns `true`.
5660		 *
5661		 * @param {Box3} box - The bounding box to test.
5662		 * @return {boolean} Whether the bounding box contains the given bounding box or not.
5663		 */ containsBox(box) {
5664	        return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;
5665	    }
5666	    /**
5667		 * Returns a point as a proportion of this box's width, height and depth.
5668		 *
5669		 * @param {Vector3} point - A point in 3D space.
5670		 * @param {Vector3} target - The target vector that is used to store the method's result.
5671		 * @return {Vector3} A point as a proportion of this box's width, height and depth.
5672		 */ getParameter(point, target) {
5673	        // This can potentially have a divide by zero if the box
5674	        // has a size dimension of 0.
5675	        return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z));
5676	    }
5677	    /**
5678		 * Returns `true` if the given bounding box intersects with this bounding box.
5679		 *
5680		 * @param {Box3} box - The bounding box to test.
5681		 * @return {boolean} Whether the given bounding box intersects with this bounding box.
5682		 */ intersectsBox(box) {
5683	        // using 6 splitting planes to rule out intersections.
5684	        return box.max.x >= this.min.x && box.min.x <= this.max.x && box.max.y >= this.min.y && box.min.y <= this.max.y && box.max.z >= this.min.z && box.min.z <= this.max.z;
5685	    }
5686	    /**
5687		 * Returns `true` if the given bounding sphere intersects with this bounding box.
5688		 *
5689		 * @param {Sphere} sphere - The bounding sphere to test.
5690		 * @return {boolean} Whether the given bounding sphere intersects with this bounding box.
5691		 */ intersectsSphere(sphere) {
5692	        // Find the point on the AABB closest to the sphere center.
5693	        this.clampPoint(sphere.center, _vector$b);
5694	        // If that point is inside the sphere, the AABB and sphere intersect.
5695	        return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
5696	    }
5697	    /**
5698		 * Returns `true` if the given plane intersects with this bounding box.
5699		 *
5700		 * @param {Plane} plane - The plane to test.
5701		 * @return {boolean} Whether the given plane intersects with this bounding box.
5702		 */ intersectsPlane(plane) {
5703	        // We compute the minimum and maximum dot product values. If those values
5704	        // are on the same side (back or front) of the plane, then there is no intersection.
5705	        let min, max;
5706	        if (plane.normal.x > 0) {
5707	            min = plane.normal.x * this.min.x;
5708	            max = plane.normal.x * this.max.x;
5709	        } else {
5710	            min = plane.normal.x * this.max.x;
5711	            max = plane.normal.x * this.min.x;
5712	        }
5713	        if (plane.normal.y > 0) {
5714	            min += plane.normal.y * this.min.y;
5715	            max += plane.normal.y * this.max.y;
5716	        } else {
5717	            min += plane.normal.y * this.max.y;
5718	            max += plane.normal.y * this.min.y;
5719	        }
5720	        if (plane.normal.z > 0) {
5721	            min += plane.normal.z * this.min.z;
5722	            max += plane.normal.z * this.max.z;
5723	        } else {
5724	            min += plane.normal.z * this.max.z;
5725	            max += plane.normal.z * this.min.z;
5726	        }
5727	        return min <= -plane.constant && max >= -plane.constant;
5728	    }
5729	    /**
5730		 * Returns `true` if the given triangle intersects with this bounding box.
5731		 *
5732		 * @param {Triangle} triangle - The triangle to test.
5733		 * @return {boolean} Whether the given triangle intersects with this bounding box.
5734		 */ intersectsTriangle(triangle) {
5735	        if (this.isEmpty()) {
5736	            return false;
5737	        }
5738	        // compute box center and extents
5739	        this.getCenter(_center);
5740	        _extents.subVectors(this.max, _center);
5741	        // translate triangle to aabb origin
5742	        _v0$2.subVectors(triangle.a, _center);
5743	        _v1$7.subVectors(triangle.b, _center);
5744	        _v2$4.subVectors(triangle.c, _center);
5745	        // compute edge vectors for triangle
5746	        _f0.subVectors(_v1$7, _v0$2);
5747	        _f1.subVectors(_v2$4, _v1$7);
5748	        _f2.subVectors(_v0$2, _v2$4);
5749	        // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb
5750	        // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation
5751	        // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)
5752	        let axes = [
5753	            0,
5754	            -_f0.z,
5755	            _f0.y,
5756	            0,
5757	            -_f1.z,
5758	            _f1.y,
5759	            0,
5760	            -_f2.z,
5761	            _f2.y,
5762	            _f0.z,
5763	            0,
5764	            -_f0.x,
5765	            _f1.z,
5766	            0,
5767	            -_f1.x,
5768	            _f2.z,
5769	            0,
5770	            -_f2.x,
5771	            -_f0.y,
5772	            _f0.x,
5773	            0,
5774	            -_f1.y,
5775	            _f1.x,
5776	            0,
5777	            -_f2.y,
5778	            _f2.x,
5779	            0
5780	        ];
5781	        if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {
5782	            return false;
5783	        }
5784	        // test 3 face normals from the aabb
5785	        axes = [
5786	            1,
5787	            0,
5788	            0,
5789	            0,
5790	            1,
5791	            0,
5792	            0,
5793	            0,
5794	            1
5795	        ];
5796	        if (!satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents)) {
5797	            return false;
5798	        }
5799	        // finally testing the face normal of the triangle
5800	        // use already existing triangle edge vectors here
5801	        _triangleNormal.crossVectors(_f0, _f1);
5802	        axes = [
5803	            _triangleNormal.x,
5804	            _triangleNormal.y,
5805	            _triangleNormal.z
5806	        ];
5807	        return satForAxes(axes, _v0$2, _v1$7, _v2$4, _extents);
5808	    }
5809	    /**
5810		 * Clamps the given point within the bounds of this box.
5811		 *
5812		 * @param {Vector3} point - The point to clamp.
5813		 * @param {Vector3} target - The target vector that is used to store the method's result.
5814		 * @return {Vector3} The clamped point.
5815		 */ clampPoint(point, target) {
5816	        return target.copy(point).clamp(this.min, this.max);
5817	    }
5818	    /**
5819		 * Returns the euclidean distance from any edge of this box to the specified point. If
5820		 * the given point lies inside of this box, the distance will be `0`.
5821		 *
5822		 * @param {Vector3} point - The point to compute the distance to.
5823		 * @return {number} The euclidean distance.
5824		 */ distanceToPoint(point) {
5825	        return this.clampPoint(point, _vector$b).distanceTo(point);
5826	    }
5827	    /**
5828		 * Returns a bounding sphere that encloses this bounding box.
5829		 *
5830		 * @param {Sphere} target - The target sphere that is used to store the method's result.
5831		 * @return {Sphere} The bounding sphere that encloses this bounding box.
5832		 */ getBoundingSphere(target) {
5833	        if (this.isEmpty()) {
5834	            target.makeEmpty();
5835	        } else {
5836	            this.getCenter(target.center);
5837	            target.radius = this.getSize(_vector$b).length() * 0.5;
5838	        }
5839	        return target;
5840	    }
5841	    /**
5842		 * Computes the intersection of this bounding box and the given one, setting the upper
5843		 * bound of this box to the lesser of the two boxes' upper bounds and the
5844		 * lower bound of this box to the greater of the two boxes' lower bounds. If
5845		 * there's no overlap, makes this box empty.
5846		 *
5847		 * @param {Box3} box - The bounding box to intersect with.
5848		 * @return {Box3} A reference to this bounding box.
5849		 */ intersect(box) {
5850	        this.min.max(box.min);
5851	        this.max.min(box.max);
5852	        // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.
5853	        if (this.isEmpty()) this.makeEmpty();
5854	        return this;
5855	    }
5856	    /**
5857		 * Computes the union of this box and another and the given one, setting the upper
5858		 * bound of this box to the greater of the two boxes' upper bounds and the
5859		 * lower bound of this box to the lesser of the two boxes' lower bounds.
5860		 *
5861		 * @param {Box3} box - The bounding box that will be unioned with this instance.
5862		 * @return {Box3} A reference to this bounding box.
5863		 */ union(box) {
5864	        this.min.min(box.min);
5865	        this.max.max(box.max);
5866	        return this;
5867	    }
5868	    /**
5869		 * Transforms this bounding box by the given 4x4 transformation matrix.
5870		 *
5871		 * @param {Matrix4} matrix - The transformation matrix.
5872		 * @return {Box3} A reference to this bounding box.
5873		 */ applyMatrix4(matrix) {
5874	        // transform of empty box is an empty box.
5875	        if (this.isEmpty()) return this;
5876	        // NOTE: I am using a binary pattern to specify all 2^3 combinations below
5877	        _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000
5878	        _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001
5879	        _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010
5880	        _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011
5881	        _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100
5882	        _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101
5883	        _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110
5884	        _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111
5885	        this.setFromPoints(_points);
5886	        return this;
5887	    }
5888	    /**
5889		 * Adds the given offset to both the upper and lower bounds of this bounding box,
5890		 * effectively moving it in 3D space.
5891		 *
5892		 * @param {Vector3} offset - The offset that should be used to translate the bounding box.
5893		 * @return {Box3} A reference to this bounding box.
5894		 */ translate(offset) {
5895	        this.min.add(offset);
5896	        this.max.add(offset);
5897	        return this;
5898	    }
5899	    /**
5900		 * Returns `true` if this bounding box is equal with the given one.
5901		 *
5902		 * @param {Box3} box - The box to test for equality.
5903		 * @return {boolean} Whether this bounding box is equal with the given one.
5904		 */ equals(box) {
5905	        return box.min.equals(this.min) && box.max.equals(this.max);
5906	    }
5907	    /**
5908		 * Constructs a new bounding box.
5909		 *
5910		 * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box.
5911		 * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box.
5912		 */ constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)){
5913	        /**
5914			 * This flag can be used for type testing.
5915			 *
5916			 * @type {boolean}
5917			 * @readonly
5918			 * @default true
5919			 */ this.isBox3 = true;
5920	        /**
5921			 * The lower boundary of the box.
5922			 *
5923			 * @type {Vector3}
5924			 */ this.min = min;
5925	        /**
5926			 * The upper boundary of the box.
5927			 *
5928			 * @type {Vector3}
5929			 */ this.max = max;
5930	    }
5931	}
5932	const _points = [
5933	    /*@__PURE__*/ new Vector3(),
5934	    /*@__PURE__*/ new Vector3(),
5935	    /*@__PURE__*/ new Vector3(),
5936	    /*@__PURE__*/ new Vector3(),
5937	    /*@__PURE__*/ new Vector3(),
5938	    /*@__PURE__*/ new Vector3(),
5939	    /*@__PURE__*/ new Vector3(),
5940	    /*@__PURE__*/ new Vector3()
5941	];
5942	const _vector$b = /*@__PURE__*/ new Vector3();
5943	const _box$4 = /*@__PURE__*/ new Box3();
5944	// triangle centered vertices
5945	const _v0$2 = /*@__PURE__*/ new Vector3();
5946	const _v1$7 = /*@__PURE__*/ new Vector3();
5947	const _v2$4 = /*@__PURE__*/ new Vector3();
5948	// triangle edge vectors
5949	const _f0 = /*@__PURE__*/ new Vector3();
5950	const _f1 = /*@__PURE__*/ new Vector3();
5951	const _f2 = /*@__PURE__*/ new Vector3();
5952	const _center = /*@__PURE__*/ new Vector3();
5953	const _extents = /*@__PURE__*/ new Vector3();
5954	const _triangleNormal = /*@__PURE__*/ new Vector3();
5955	const _testAxis = /*@__PURE__*/ new Vector3();
5956	function satForAxes(axes, v0, v1, v2, extents) {
5957	    for(let i = 0, j = axes.length - 3; i <= j; i += 3){
5958	        _testAxis.fromArray(axes, i);
5959	        // project the aabb onto the separating axis
5960	        const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z);
5961	        // project all 3 vertices of the triangle onto the separating axis
5962	        const p0 = v0.dot(_testAxis);
5963	        const p1 = v1.dot(_testAxis);
5964	        const p2 = v2.dot(_testAxis);
5965	        // actual test, basically see if either of the most extreme of the triangle points intersects r
5966	        if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {
5967	            // points of the projected triangle are outside the projected half-length of the aabb
5968	            // the axis is separating and we can exit
5969	            return false;
5970	        }
5971	    }
5972	    return true;
5973	}
5974	const _box$3 = /*@__PURE__*/ new Box3();
5975	const _v1$6 = /*@__PURE__*/ new Vector3();
5976	const _v2$3 = /*@__PURE__*/ new Vector3();
5977	/**
5978	 * An analytical 3D sphere defined by a center and radius. This class is mainly
5979	 * used as a Bounding Sphere for 3D objects.
5980	 */ class Sphere {
5981	    /**
5982		 * Sets the sphere's components by copying the given values.
5983		 *
5984		 * @param {Vector3} center - The center.
5985		 * @param {number} radius - The radius.
5986		 * @return {Sphere} A reference to this sphere.
5987		 */ set(center, radius) {
5988	        this.center.copy(center);
5989	        this.radius = radius;
5990	        return this;
5991	    }
5992	    /**
5993		 * Computes the minimum bounding sphere for list of points.
5994		 * If the optional center point is given, it is used as the sphere's
5995		 * center. Otherwise, the center of the axis-aligned bounding box
5996		 * encompassing the points is calculated.
5997		 *
5998		 * @param {Array<Vector3>} points - A list of points in 3D space.
5999		 * @param {Vector3} [optionalCenter] - The center of the sphere.
6000		 * @return {Sphere} A reference to this sphere.
6001		 */ setFromPoints(points, optionalCenter) {
6002	        const center = this.center;
6003	        if (optionalCenter !== undefined) {
6004	            center.copy(optionalCenter);
6005	        } else {
6006	            _box$3.setFromPoints(points).getCenter(center);
6007	        }
6008	        let maxRadiusSq = 0;
6009	        for(let i = 0, il = points.length; i < il; i++){
6010	            maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i]));
6011	        }
6012	        this.radius = Math.sqrt(maxRadiusSq);
6013	        return this;
6014	    }
6015	    /**
6016		 * Copies the values of the given sphere to this instance.
6017		 *
6018		 * @param {Sphere} sphere - The sphere to copy.
6019		 * @return {Sphere} A reference to this sphere.
6020		 */ copy(sphere) {
6021	        this.center.copy(sphere.center);
6022	        this.radius = sphere.radius;
6023	        return this;
6024	    }
6025	    /**
6026		 * Returns `true` if the sphere is empty (the radius set to a negative number).
6027		 *
6028		 * Spheres with a radius of `0` contain only their center point and are not
6029		 * considered to be empty.
6030		 *
6031		 * @return {boolean} Whether this sphere is empty or not.
6032		 */ isEmpty() {
6033	        return this.radius < 0;
6034	    }
6035	    /**
6036		 * Makes this sphere empty which means in encloses a zero space in 3D.
6037		 *
6038		 * @return {Sphere} A reference to this sphere.
6039		 */ makeEmpty() {
6040	        this.center.set(0, 0, 0);
6041	        this.radius = -1;
6042	        return this;
6043	    }
6044	    /**
6045		 * Returns `true` if this sphere contains the given point inclusive of
6046		 * the surface of the sphere.
6047		 *
6048		 * @param {Vector3} point - The point to check.
6049		 * @return {boolean} Whether this sphere contains the given point or not.
6050		 */ containsPoint(point) {
6051	        return point.distanceToSquared(this.center) <= this.radius * this.radius;
6052	    }
6053	    /**
6054		 * Returns the closest distance from the boundary of the sphere to the
6055		 * given point. If the sphere contains the point, the distance will
6056		 * be negative.
6057		 *
6058		 * @param {Vector3} point - The point to compute the distance to.
6059		 * @return {number} The distance to the point.
6060		 */ distanceToPoint(point) {
6061	        return point.distanceTo(this.center) - this.radius;
6062	    }
6063	    /**
6064		 * Returns `true` if this sphere intersects with the given one.
6065		 *
6066		 * @param {Sphere} sphere - The sphere to test.
6067		 * @return {boolean} Whether this sphere intersects with the given one or not.
6068		 */ intersectsSphere(sphere) {
6069	        const radiusSum = this.radius + sphere.radius;
6070	        return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
6071	    }
6072	    /**
6073		 * Returns `true` if this sphere intersects with the given box.
6074		 *
6075		 * @param {Box3} box - The box to test.
6076		 * @return {boolean} Whether this sphere intersects with the given box or not.
6077		 */ intersectsBox(box) {
6078	        return box.intersectsSphere(this);
6079	    }
6080	    /**
6081		 * Returns `true` if this sphere intersects with the given plane.
6082		 *
6083		 * @param {Plane} plane - The plane to test.
6084		 * @return {boolean} Whether this sphere intersects with the given plane or not.
6085		 */ intersectsPlane(plane) {
6086	        return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
6087	    }
6088	    /**
6089		 * Clamps a point within the sphere. If the point is outside the sphere, it
6090		 * will clamp it to the closest point on the edge of the sphere. Points
6091		 * already inside the sphere will not be affected.
6092		 *
6093		 * @param {Vector3} point - The plane to clamp.
6094		 * @param {Vector3} target - The target vector that is used to store the method's result.
6095		 * @return {Vector3} The clamped point.
6096		 */ clampPoint(point, target) {
6097	        const deltaLengthSq = this.center.distanceToSquared(point);
6098	        target.copy(point);
6099	        if (deltaLengthSq > this.radius * this.radius) {
6100	            target.sub(this.center).normalize();
6101	            target.multiplyScalar(this.radius).add(this.center);
6102	        }
6103	        return target;
6104	    }
6105	    /**
6106		 * Returns a bounding box that encloses this sphere.
6107		 *
6108		 * @param {Box3} target - The target box that is used to store the method's result.
6109		 * @return {Box3} The bounding box that encloses this sphere.
6110		 */ getBoundingBox(target) {
6111	        if (this.isEmpty()) {
6112	            // Empty sphere produces empty bounding box
6113	            target.makeEmpty();
6114	            return target;
6115	        }
6116	        target.set(this.center, this.center);
6117	        target.expandByScalar(this.radius);
6118	        return target;
6119	    }
6120	    /**
6121		 * Transforms this sphere with the given 4x4 transformation matrix.
6122		 *
6123		 * @param {Matrix4} matrix - The transformation matrix.
6124		 * @return {Sphere} A reference to this sphere.
6125		 */ applyMatrix4(matrix) {
6126	        this.center.applyMatrix4(matrix);
6127	        this.radius = this.radius * matrix.getMaxScaleOnAxis();
6128	        return this;
6129	    }
6130	    /**
6131		 * Translates the sphere's center by the given offset.
6132		 *
6133		 * @param {Vector3} offset - The offset.
6134		 * @return {Sphere} A reference to this sphere.
6135		 */ translate(offset) {
6136	        this.center.add(offset);
6137	        return this;
6138	    }
6139	    /**
6140		 * Expands the boundaries of this sphere to include the given point.
6141		 *
6142		 * @param {Vector3} point - The point to include.
6143		 * @return {Sphere} A reference to this sphere.
6144		 */ expandByPoint(point) {
6145	        if (this.isEmpty()) {
6146	            this.center.copy(point);
6147	            this.radius = 0;
6148	            return this;
6149	        }
6150	        _v1$6.subVectors(point, this.center);
6151	        const lengthSq = _v1$6.lengthSq();
6152	        if (lengthSq > this.radius * this.radius) {
6153	            // calculate the minimal sphere
6154	            const length = Math.sqrt(lengthSq);
6155	            const delta = (length - this.radius) * 0.5;
6156	            this.center.addScaledVector(_v1$6, delta / length);
6157	            this.radius += delta;
6158	        }
6159	        return this;
6160	    }
6161	    /**
6162		 * Expands this sphere to enclose both the original sphere and the given sphere.
6163		 *
6164		 * @param {Sphere} sphere - The sphere to include.
6165		 * @return {Sphere} A reference to this sphere.
6166		 */ union(sphere) {
6167	        if (sphere.isEmpty()) {
6168	            return this;
6169	        }
6170	        if (this.isEmpty()) {
6171	            this.copy(sphere);
6172	            return this;
6173	        }
6174	        if (this.center.equals(sphere.center) === true) {
6175	            this.radius = Math.max(this.radius, sphere.radius);
6176	        } else {
6177	            _v2$3.subVectors(sphere.center, this.center).setLength(sphere.radius);
6178	            this.expandByPoint(_v1$6.copy(sphere.center).add(_v2$3));
6179	            this.expandByPoint(_v1$6.copy(sphere.center).sub(_v2$3));
6180	        }
6181	        return this;
6182	    }
6183	    /**
6184		 * Returns `true` if this sphere is equal with the given one.
6185		 *
6186		 * @param {Sphere} sphere - The sphere to test for equality.
6187		 * @return {boolean} Whether this bounding sphere is equal with the given one.
6188		 */ equals(sphere) {
6189	        return sphere.center.equals(this.center) && sphere.radius === this.radius;
6190	    }
6191	    /**
6192		 * Returns a new sphere with copied values from this instance.
6193		 *
6194		 * @return {Sphere} A clone of this instance.
6195		 */ clone() {
6196	        return new this.constructor().copy(this);
6197	    }
6198	    /**
6199		 * Constructs a new sphere.
6200		 *
6201		 * @param {Vector3} [center=(0,0,0)] - The center of the sphere
6202		 * @param {number} [radius=-1] - The radius of the sphere.
6203		 */ constructor(center = new Vector3(), radius = -1){
6204	        /**
6205			 * This flag can be used for type testing.
6206			 *
6207			 * @type {boolean}
6208			 * @readonly
6209			 * @default true
6210			 */ this.isSphere = true;
6211	        /**
6212			 * The center of the sphere
6213			 *
6214			 * @type {Vector3}
6215			 */ this.center = center;
6216	        /**
6217			 * The radius of the sphere.
6218			 *
6219			 * @type {number}
6220			 */ this.radius = radius;
6221	    }
6222	}
6223	const _vector$a = /*@__PURE__*/ new Vector3();
6224	const _segCenter = /*@__PURE__*/ new Vector3();
6225	const _segDir = /*@__PURE__*/ new Vector3();
6226	const _diff = /*@__PURE__*/ new Vector3();
6227	const _edge1 = /*@__PURE__*/ new Vector3();
6228	const _edge2 = /*@__PURE__*/ new Vector3();
6229	const _normal$1 = /*@__PURE__*/ new Vector3();
6230	/**
6231	 * A ray that emits from an origin in a certain direction. The class is used by
6232	 * {@link Raycaster} to assist with raycasting. Raycasting is used for
6233	 * mouse picking (working out what objects in the 3D space the mouse is over)
6234	 * amongst other things.
6235	 */ class Ray {
6236	    /**
6237		 * Sets the ray's components by copying the given values.
6238		 *
6239		 * @param {Vector3} origin - The origin.
6240		 * @param {Vector3} direction - The direction.
6241		 * @return {Ray} A reference to this ray.
6242		 */ set(origin, direction) {
6243	        this.origin.copy(origin);
6244	        this.direction.copy(direction);
6245	        return this;
6246	    }
6247	    /**
6248		 * Copies the values of the given ray to this instance.
6249		 *
6250		 * @param {Ray} ray - The ray to copy.
6251		 * @return {Ray} A reference to this ray.
6252		 */ copy(ray) {
6253	        this.origin.copy(ray.origin);
6254	        this.direction.copy(ray.direction);
6255	        return this;
6256	    }
6257	    /**
6258		 * Returns a vector that is located at a given distance along this ray.
6259		 *
6260		 * @param {number} t - The distance along the ray to retrieve a position for.
6261		 * @param {Vector3} target - The target vector that is used to store the method's result.
6262		 * @return {Vector3} A position on the ray.
6263		 */ at(t, target) {
6264	        return target.copy(this.origin).addScaledVector(this.direction, t);
6265	    }
6266	    /**
6267		 * Adjusts the direction of the ray to point at the given vector in world space.
6268		 *
6269		 * @param {Vector3} v - The target position.
6270		 * @return {Ray} A reference to this ray.
6271		 */ lookAt(v) {
6272	        this.direction.copy(v).sub(this.origin).normalize();
6273	        return this;
6274	    }
6275	    /**
6276		 * Shift the origin of this ray along its direction by the given distance.
6277		 *
6278		 * @param {number} t - The distance along the ray to interpolate.
6279		 * @return {Ray} A reference to this ray.
6280		 */ recast(t) {
6281	        this.origin.copy(this.at(t, _vector$a));
6282	        return this;
6283	    }
6284	    /**
6285		 * Returns the point along this ray that is closest to the given point.
6286		 *
6287		 * @param {Vector3} point - A point in 3D space to get the closet location on the ray for.
6288		 * @param {Vector3} target - The target vector that is used to store the method's result.
6289		 * @return {Vector3} The closest point on this ray.
6290		 */ closestPointToPoint(point, target) {
6291	        target.subVectors(point, this.origin);
6292	        const directionDistance = target.dot(this.direction);
6293	        if (directionDistance < 0) {
6294	            return target.copy(this.origin);
6295	        }
6296	        return target.copy(this.origin).addScaledVector(this.direction, directionDistance);
6297	    }
6298	    /**
6299		 * Returns the distance of the closest approach between this ray and the given point.
6300		 *
6301		 * @param {Vector3} point - A point in 3D space to compute the distance to.
6302		 * @return {number} The distance.
6303		 */ distanceToPoint(point) {
6304	        return Math.sqrt(this.distanceSqToPoint(point));
6305	    }
6306	    /**
6307		 * Returns the squared distance of the closest approach between this ray and the given point.
6308		 *
6309		 * @param {Vector3} point - A point in 3D space to compute the distance to.
6310		 * @return {number} The squared distance.
6311		 */ distanceSqToPoint(point) {
6312	        const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction);
6313	        // point behind the ray
6314	        if (directionDistance < 0) {
6315	            return this.origin.distanceToSquared(point);
6316	        }
6317	        _vector$a.copy(this.origin).addScaledVector(this.direction, directionDistance);
6318	        return _vector$a.distanceToSquared(point);
6319	    }
6320	    /**
6321		 * Returns the squared distance between this ray and the given line segment.
6322		 *
6323		 * @param {Vector3} v0 - The start point of the line segment.
6324		 * @param {Vector3} v1 - The end point of the line segment.
6325		 * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment.
6326		 * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray.
6327		 * @return {number} The squared distance.
6328		 */ distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) {
6329	        // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h
6330	        // It returns the min distance between the ray and the segment
6331	        // defined by v0 and v1
6332	        // It can also set two optional targets :
6333	        // - The closest point on the ray
6334	        // - The closest point on the segment
6335	        _segCenter.copy(v0).add(v1).multiplyScalar(0.5);
6336	        _segDir.copy(v1).sub(v0).normalize();
6337	        _diff.copy(this.origin).sub(_segCenter);
6338	        const segExtent = v0.distanceTo(v1) * 0.5;
6339	        const a01 = -this.direction.dot(_segDir);
6340	        const b0 = _diff.dot(this.direction);
6341	        const b1 = -_diff.dot(_segDir);
6342	        const c = _diff.lengthSq();
6343	        const det = Math.abs(1 - a01 * a01);
6344	        let s0, s1, sqrDist, extDet;
6345	        if (det > 0) {
6346	            // The ray and segment are not parallel.
6347	            s0 = a01 * b1 - b0;
6348	            s1 = a01 * b0 - b1;
6349	            extDet = segExtent * det;
6350	            if (s0 >= 0) {
6351	                if (s1 >= -extDet) {
6352	                    if (s1 <= extDet) {
6353	                        // region 0
6354	                        // Minimum at interior points of ray and segment.
6355	                        const invDet = 1 / det;
6356	                        s0 *= invDet;
6357	                        s1 *= invDet;
6358	                        sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c;
6359	                    } else {
6360	                        // region 1
6361	                        s1 = segExtent;
6362	                        s0 = Math.max(0, -(a01 * s1 + b0));
6363	                        sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
6364	                    }
6365	                } else {
6366	                    // region 5
6367	                    s1 = -segExtent;
6368	                    s0 = Math.max(0, -(a01 * s1 + b0));
6369	                    sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
6370	                }
6371	            } else {
6372	                if (s1 <= -extDet) {
6373	                    // region 4
6374	                    s0 = Math.max(0, -(-a01 * segExtent + b0));
6375	                    s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
6376	                    sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
6377	                } else if (s1 <= extDet) {
6378	                    // region 3
6379	                    s0 = 0;
6380	                    s1 = Math.min(Math.max(-segExtent, -b1), segExtent);
6381	                    sqrDist = s1 * (s1 + 2 * b1) + c;
6382	                } else {
6383	                    // region 2
6384	                    s0 = Math.max(0, -(a01 * segExtent + b0));
6385	                    s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
6386	                    sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
6387	                }
6388	            }
6389	        } else {
6390	            // Ray and segment are parallel.
6391	            s1 = a01 > 0 ? -segExtent : segExtent;
6392	            s0 = Math.max(0, -(a01 * s1 + b0));
6393	            sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
6394	        }
6395	        if (optionalPointOnRay) {
6396	            optionalPointOnRay.copy(this.origin).addScaledVector(this.direction, s0);
6397	        }
6398	        if (optionalPointOnSegment) {
6399	            optionalPointOnSegment.copy(_segCenter).addScaledVector(_segDir, s1);
6400	        }
6401	        return sqrDist;
6402	    }
6403	    /**
6404		 * Intersects this ray with the given sphere, returning the intersection
6405		 * point or `null` if there is no intersection.
6406		 *
6407		 * @param {Sphere} sphere - The sphere to intersect.
6408		 * @param {Vector3} target - The target vector that is used to store the method's result.
6409		 * @return {?Vector3} The intersection point.
6410		 */ intersectSphere(sphere, target) {
6411	        _vector$a.subVectors(sphere.center, this.origin);
6412	        const tca = _vector$a.dot(this.direction);
6413	        const d2 = _vector$a.dot(_vector$a) - tca * tca;
6414	        const radius2 = sphere.radius * sphere.radius;
6415	        if (d2 > radius2) return null;
6416	        const thc = Math.sqrt(radius2 - d2);
6417	        // t0 = first intersect point - entrance on front of sphere
6418	        const t0 = tca - thc;
6419	        // t1 = second intersect point - exit point on back of sphere
6420	        const t1 = tca + thc;
6421	        // test to see if t1 is behind the ray - if so, return null
6422	        if (t1 < 0) return null;
6423	        // test to see if t0 is behind the ray:
6424	        // if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
6425	        // in order to always return an intersect point that is in front of the ray.
6426	        if (t0 < 0) return this.at(t1, target);
6427	        // else t0 is in front of the ray, so return the first collision point scaled by t0
6428	        return this.at(t0, target);
6429	    }
6430	    /**
6431		 * Returns `true` if this ray intersects with the given sphere.
6432		 *
6433		 * @param {Sphere} sphere - The sphere to intersect.
6434		 * @return {boolean} Whether this ray intersects with the given sphere or not.
6435		 */ intersectsSphere(sphere) {
6436	        return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius;
6437	    }
6438	    /**
6439		 * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray
6440		 * does not intersect with the plane.
6441		 *
6442		 * @param {Plane} plane - The plane to compute the distance to.
6443		 * @return {?number} Whether this ray intersects with the given sphere or not.
6444		 */ distanceToPlane(plane) {
6445	        const denominator = plane.normal.dot(this.direction);
6446	        if (denominator === 0) {
6447	            // line is coplanar, return origin
6448	            if (plane.distanceToPoint(this.origin) === 0) {
6449	                return 0;
6450	            }
6451	            // Null is preferable to undefined since undefined means.... it is undefined
6452	            return null;
6453	        }
6454	        const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator;
6455	        // Return if the ray never intersects the plane
6456	        return t >= 0 ? t : null;
6457	    }
6458	    /**
6459		 * Intersects this ray with the given plane, returning the intersection
6460		 * point or `null` if there is no intersection.
6461		 *
6462		 * @param {Plane} plane - The plane to intersect.
6463		 * @param {Vector3} target - The target vector that is used to store the method's result.
6464		 * @return {?Vector3} The intersection point.
6465		 */ intersectPlane(plane, target) {
6466	        const t = this.distanceToPlane(plane);
6467	        if (t === null) {
6468	            return null;
6469	        }
6470	        return this.at(t, target);
6471	    }
6472	    /**
6473		 * Returns `true` if this ray intersects with the given plane.
6474		 *
6475		 * @param {Plane} plane - The plane to intersect.
6476		 * @return {boolean} Whether this ray intersects with the given plane or not.
6477		 */ intersectsPlane(plane) {
6478	        // check if the ray lies on the plane first
6479	        const distToPoint = plane.distanceToPoint(this.origin);
6480	        if (distToPoint === 0) {
6481	            return true;
6482	        }
6483	        const denominator = plane.normal.dot(this.direction);
6484	        if (denominator * distToPoint < 0) {
6485	            return true;
6486	        }
6487	        // ray origin is behind the plane (and is pointing behind it)
6488	        return false;
6489	    }
6490	    /**
6491		 * Intersects this ray with the given bounding box, returning the intersection
6492		 * point or `null` if there is no intersection.
6493		 *
6494		 * @param {Box3} box - The box to intersect.
6495		 * @param {Vector3} target - The target vector that is used to store the method's result.
6496		 * @return {?Vector3} The intersection point.
6497		 */ intersectBox(box, target) {
6498	        let tmin, tmax, tymin, tymax, tzmin, tzmax;
6499	        const invdirx = 1 / this.direction.x, invdiry = 1 / this.direction.y, invdirz = 1 / this.direction.z;
6500	        const origin = this.origin;
6501	        if (invdirx >= 0) {
6502	            tmin = (box.min.x - origin.x) * invdirx;
6503	            tmax = (box.max.x - origin.x) * invdirx;
6504	        } else {
6505	            tmin = (box.max.x - origin.x) * invdirx;
6506	            tmax = (box.min.x - origin.x) * invdirx;
6507	        }
6508	        if (invdiry >= 0) {
6509	            tymin = (box.min.y - origin.y) * invdiry;
6510	            tymax = (box.max.y - origin.y) * invdiry;
6511	        } else {
6512	            tymin = (box.max.y - origin.y) * invdiry;
6513	            tymax = (box.min.y - origin.y) * invdiry;
6514	        }
6515	        if (tmin > tymax || tymin > tmax) return null;
6516	        if (tymin > tmin || isNaN(tmin)) tmin = tymin;
6517	        if (tymax < tmax || isNaN(tmax)) tmax = tymax;
6518	        if (invdirz >= 0) {
6519	            tzmin = (box.min.z - origin.z) * invdirz;
6520	            tzmax = (box.max.z - origin.z) * invdirz;
6521	        } else {
6522	            tzmin = (box.max.z - origin.z) * invdirz;
6523	            tzmax = (box.min.z - origin.z) * invdirz;
6524	        }
6525	        if (tmin > tzmax || tzmin > tmax) return null;
6526	        if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
6527	        if (tzmax < tmax || tmax !== tmax) tmax = tzmax;
6528	        //return point closest to the ray (positive side)
6529	        if (tmax < 0) return null;
6530	        return this.at(tmin >= 0 ? tmin : tmax, target);
6531	    }
6532	    /**
6533		 * Returns `true` if this ray intersects with the given box.
6534		 *
6535		 * @param {Box3} box - The box to intersect.
6536		 * @return {boolean} Whether this ray intersects with the given box or not.
6537		 */ intersectsBox(box) {
6538	        return this.intersectBox(box, _vector$a) !== null;
6539	    }
6540	    /**
6541		 * Intersects this ray with the given triangle, returning the intersection
6542		 * point or `null` if there is no intersection.
6543		 *
6544		 * @param {Vector3} a - The first vertex of the triangle.
6545		 * @param {Vector3} b - The second vertex of the triangle.
6546		 * @param {Vector3} c - The third vertex of the triangle.
6547		 * @param {boolean} backfaceCulling - Whether to use backface culling or not.
6548		 * @param {Vector3} target - The target vector that is used to store the method's result.
6549		 * @return {?Vector3} The intersection point.
6550		 */ intersectTriangle(a, b, c, backfaceCulling, target) {
6551	        // Compute the offset origin, edges, and normal.
6552	        // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
6553	        _edge1.subVectors(b, a);
6554	        _edge2.subVectors(c, a);
6555	        _normal$1.crossVectors(_edge1, _edge2);
6556	        // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
6557	        // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
6558	        //   |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
6559	        //   |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
6560	        //   |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
6561	        let DdN = this.direction.dot(_normal$1);
6562	        let sign;
6563	        if (DdN > 0) {
6564	            if (backfaceCulling) return null;
6565	            sign = 1;
6566	        } else if (DdN < 0) {
6567	            sign = -1;
6568	            DdN = -DdN;
6569	        } else {
6570	            return null;
6571	        }
6572	        _diff.subVectors(this.origin, a);
6573	        const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2));
6574	        // b1 < 0, no intersection
6575	        if (DdQxE2 < 0) {
6576	            return null;
6577	        }
6578	        const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff));
6579	        // b2 < 0, no intersection
6580	        if (DdE1xQ < 0) {
6581	            return null;
6582	        }
6583	        // b1+b2 > 1, no intersection
6584	        if (DdQxE2 + DdE1xQ > DdN) {
6585	            return null;
6586	        }
6587	        // Line intersects triangle, check if ray does.
6588	        const QdN = -sign * _diff.dot(_normal$1);
6589	        // t < 0, no intersection
6590	        if (QdN < 0) {
6591	            return null;
6592	        }
6593	        // Ray intersects triangle.
6594	        return this.at(QdN / DdN, target);
6595	    }
6596	    /**
6597		 * Transforms this ray with the given 4x4 transformation matrix.
6598		 *
6599		 * @param {Matrix4} matrix4 - The transformation matrix.
6600		 * @return {Ray} A reference to this ray.
6601		 */ applyMatrix4(matrix4) {
6602	        this.origin.applyMatrix4(matrix4);
6603	        this.direction.transformDirection(matrix4);
6604	        return this;
6605	    }
6606	    /**
6607		 * Returns `true` if this ray is equal with the given one.
6608		 *
6609		 * @param {Ray} ray - The ray to test for equality.
6610		 * @return {boolean} Whether this ray is equal with the given one.
6611		 */ equals(ray) {
6612	        return ray.origin.equals(this.origin) && ray.direction.equals(this.direction);
6613	    }
6614	    /**
6615		 * Returns a new ray with copied values from this instance.
6616		 *
6617		 * @return {Ray} A clone of this instance.
6618		 */ clone() {
6619	        return new this.constructor().copy(this);
6620	    }
6621	    /**
6622		 * Constructs a new ray.
6623		 *
6624		 * @param {Vector3} [origin=(0,0,0)] - The origin of the ray.
6625		 * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray.
6626		 */ constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)){
6627	        /**
6628			 * The origin of the ray.
6629			 *
6630			 * @type {Vector3}
6631			 */ this.origin = origin;
6632	        /**
6633			 * The (normalized) direction of the ray.
6634			 *
6635			 * @type {Vector3}
6636			 */ this.direction = direction;
6637	    }
6638	}
6639	/**
6640	 * Represents a 4x4 matrix.
6641	 *
6642	 * The most common use of a 4x4 matrix in 3D computer graphics is as a transformation matrix.
6643	 * For an introduction to transformation matrices as used in WebGL, check out [this tutorial]{@link https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices}
6644	 *
6645	 * This allows a 3D vector representing a point in 3D space to undergo
6646	 * transformations such as translation, rotation, shear, scale, reflection,
6647	 * orthogonal or perspective projection and so on, by being multiplied by the
6648	 * matrix. This is known as `applying` the matrix to the vector.
6649	 *
6650	 * A Note on Row-Major and Column-Major Ordering:
6651	 *
6652	 * The constructor and {@link Matrix3#set} method take arguments in
6653	 * [row-major]{@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order}
6654	 * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order.
6655	 * This means that calling:
6656	 * ```js
6657	 * const m = new THREE.Matrix4();
6658	 * m.set( 11, 12, 13, 14,
6659	 *        21, 22, 23, 24,
6660	 *        31, 32, 33, 34,
6661	 *        41, 42, 43, 44 );
6662	 * ```
6663	 * will result in the elements array containing:
6664	 * ```js
6665	 * m.elements = [ 11, 21, 31, 41,
6666	 *                12, 22, 32, 42,
6667	 *                13, 23, 33, 43,
6668	 *                14, 24, 34, 44 ];
6669	 * ```
6670	 * and internally all calculations are performed using column-major ordering.
6671	 * However, as the actual ordering makes no difference mathematically and
6672	 * most people are used to thinking about matrices in row-major order, the
6673	 * three.js documentation shows matrices in row-major order. Just bear in
6674	 * mind that if you are reading the source code, you'll have to take the
6675	 * transpose of any matrices outlined here to make sense of the calculations.
6676	 */ class Matrix4 {
6677	    /**
6678		 * Sets the elements of the matrix.The arguments are supposed to be
6679		 * in row-major order.
6680		 *
6681		 * @param {number} [n11] - 1-1 matrix element.
6682		 * @param {number} [n12] - 1-2 matrix element.
6683		 * @param {number} [n13] - 1-3 matrix element.
6684		 * @param {number} [n14] - 1-4 matrix element.
6685		 * @param {number} [n21] - 2-1 matrix element.
6686		 * @param {number} [n22] - 2-2 matrix element.
6687		 * @param {number} [n23] - 2-3 matrix element.
6688		 * @param {number} [n24] - 2-4 matrix element.
6689		 * @param {number} [n31] - 3-1 matrix element.
6690		 * @param {number} [n32] - 3-2 matrix element.
6691		 * @param {number} [n33] - 3-3 matrix element.
6692		 * @param {number} [n34] - 3-4 matrix element.
6693		 * @param {number} [n41] - 4-1 matrix element.
6694		 * @param {number}
vendor: 4,617 bytes, lines 6694-6838
6694 [n42] - 4-2 matrix element.
6695		 * @param {number} [n43] - 4-3 matrix element.
6696		 * @param {number} [n44] - 4-4 matrix element.
6697		 * @return {Matrix4} A reference to this matrix.
6698		 */ set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
6699	        const te = this.elements;
6700	        te[0] = n11;
6701	        te[4] = n12;
6702	        te[8] = n13;
6703	        te[12] = n14;
6704	        te[1] = n21;
6705	        te[5] = n22;
6706	        te[9] = n23;
6707	        te[13] = n24;
6708	        te[2] = n31;
6709	        te[6] = n32;
6710	        te[10] = n33;
6711	        te[14] = n34;
6712	        te[3] = n41;
6713	        te[7] = n42;
6714	        te[11] = n43;
6715	        te[15] = n44;
6716	        return this;
6717	    }
6718	    /**
6719		 * Sets this matrix to the 4x4 identity matrix.
6720		 *
6721		 * @return {Matrix4} A reference to this matrix.
6722		 */ identity() {
6723	        this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
6724	        return this;
6725	    }
6726	    /**
6727		 * Returns a matrix with copied values from this instance.
6728		 *
6729		 * @return {Matrix4} A clone of this instance.
6730		 */ clone() {
6731	        return new Matrix4().fromArray(this.elements);
6732	    }
6733	    /**
6734		 * Copies the values of the given matrix to this instance.
6735		 *
6736		 * @param {Matrix4} m - The matrix to copy.
6737		 * @return {Matrix4} A reference to this matrix.
6738		 */ copy(m) {
6739	        const te = this.elements;
6740	        const me = m.elements;
6741	        te[0] = me[0];
6742	        te[1] = me[1];
6743	        te[2] = me[2];
6744	        te[3] = me[3];
6745	        te[4] = me[4];
6746	        te[5] = me[5];
6747	        te[6] = me[6];
6748	        te[7] = me[7];
6749	        te[8] = me[8];
6750	        te[9] = me[9];
6751	        te[10] = me[10];
6752	        te[11] = me[11];
6753	        te[12] = me[12];
6754	        te[13] = me[13];
6755	        te[14] = me[14];
6756	        te[15] = me[15];
6757	        return this;
6758	    }
6759	    /**
6760		 * Copies the translation component of the given matrix
6761		 * into this matrix's translation component.
6762		 *
6763		 * @param {Matrix4} m - The matrix to copy the translation component.
6764		 * @return {Matrix4} A reference to this matrix.
6765		 */ copyPosition(m) {
6766	        const te = this.elements, me = m.elements;
6767	        te[12] = me[12];
6768	        te[13] = me[13];
6769	        te[14] = me[14];
6770	        return this;
6771	    }
6772	    /**
6773		 * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix.
6774		 *
6775		 * @param {Matrix3} m - The 3x3 matrix.
6776		 * @return {Matrix4} A reference to this matrix.
6777		 */ setFromMatrix3(m) {
6778	        const me = m.elements;
6779	        this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1);
6780	        return this;
6781	    }
6782	    /**
6783		 * Extracts the basis of this matrix into the three axis vectors provided.
6784		 *
6785		 * @param {Vector3} xAxis - The basis's x axis.
6786		 * @param {Vector3} yAxis - The basis's y axis.
6787		 * @param {Vector3} zAxis - The basis's z axis.
6788		 * @return {Matrix4} A reference to this matrix.
6789		 */ extractBasis(xAxis, yAxis, zAxis) {
6790	        xAxis.setFromMatrixColumn(this, 0);
6791	        yAxis.setFromMatrixColumn(this, 1);
6792	        zAxis.setFromMatrixColumn(this, 2);
6793	        return this;
6794	    }
6795	    /**
6796		 * Sets the given basis vectors to this matrix.
6797		 *
6798		 * @param {Vector3} xAxis - The basis's x axis.
6799		 * @param {Vector3} yAxis - The basis's y axis.
6800		 * @param {Vector3} zAxis - The basis's z axis.
6801		 * @return {Matrix4} A reference to this matrix.
6802		 */ makeBasis(xAxis, yAxis, zAxis) {
6803	        this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1);
6804	        return this;
6805	    }
6806	    /**
6807		 * Extracts the rotation component of the given matrix
6808		 * into this matrix's rotation component.
6809		 *
6810		 * Note: This method does not support reflection matrices.
6811		 *
6812		 * @param {Matrix4} m - The matrix.
6813		 * @return {Matrix4} A reference to this matrix.
6814		 */ extractRotation(m) {
6815	        const te = this.elements;
6816	        const me = m.elements;
6817	        const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length();
6818	        const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length();
6819	        const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length();
6820	        te[0] = me[0] * scaleX;
6821	        te[1] = me[1] * scaleX;
6822	        te[2] = me[2] * scaleX;
6823	        te[3] = 0;
6824	        te[4] = me[4] * scaleY;
6825	        te[5] = me[5] * scaleY;
6826	        te[6] = me[6] * scaleY;
6827	        te[7] = 0;
6828	        te[8] = me[8] * scaleZ;
6829	        te[9] = me[9] * scaleZ;
6830	        te[10] = me[10] * scaleZ;
6831	        te[11] = 0;
6832	        te[12] = 0;
6833	        te[13] = 0;
6834	        te[14] = 0;
6835	        te[15] = 1;
6836	        return this;
6837	    }
6838	    /**
6839		 * Sets the rotation component (the upper left 3x3 matrix) of this matrix to
6840		 * the rotation specified by the given Euler angles. The rest of
6841		 * the matrix is set to the identity. Depending on the {@link Euler#order},
6842		 * there are six possible outcomes. See [this page]{@link https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix}
6843		 * for a complete list.
6844		 *
6845		 * @param {Euler} euler - The Euler angles.
6846		 * @return {Matrix4} A reference to this matrix.
6847		 */ makeRotationFromEuler(euler) {
6848	        const te = this.elements;
6849	        const x = euler.x, y = euler.y, z = euler.z;
6850	        const a = Math.cos(x), b = Math.sin(x);
6851	        const c = Math.cos(y), d = Math.sin(y);
6852	        const e = Math.cos(z), f = Math.sin(z);
6853	        if (euler.order === 'XYZ') {
6854	            const ae = a * e, af = a * f, be = b * e, bf = b * f;
6855	            te[0] = c * e;
6856	            te[4] = -c * f;
6857	            te[8] = d;
6858	            te[1] = af + be * d;
6859	            te[5] = ae - bf * d;
6860	            te[9] = -b * c;
6861	            te[2] = bf - ae * d;
6862	            te[6] = be + af * d;
6863	            te[10] = a * c;
6864	        } else if (euler.order === 'YXZ') {
6865	            const ce = c * e, cf = c * f, de = d * e, df = d * f;
6866	            te[0] = ce + df * b;
6867	            te[4] = de * b - cf;
6868	            te[8] = a * d;
6869	            te[1] = a * f;
6870	            te[5] = a * e;
6871	            te[9] = -b;
6872	            te[2] = cf * b - de;
6873	            te[6] = df + ce * b;
6874	            te[10] = a * c;
6875	        } else if (euler.order === 'ZXY') {
6876	            const ce = c * e, cf = c * f, de = d * e, df = d * f;
6877	            te[0] = ce - df * b;
6878	            te[4] = -a * f;
6879	            te[8] = de + cf * b;
6880	            te[1] = cf + de * b;
6881	            te[5] = a * e;
6882	            te[9] = df - ce * b;
6883	            te[2] = -a * d;
6884	            te[6] = b;
6885	            te[10] = a * c;
6886	        } else if (euler.order === 'ZYX') {
6887	            const ae = a * e, af = a * f, be = b * e, bf = b * f;
6888	            te[0] = c * e;
6889	            te[4] = be * d - af;
6890	            te[8] = ae * d + bf;
6891	            te[1] = c * f;
6892	            te[5] = bf * d + ae;
6893	            te[9] = af * d - be;
6894	            te[2] = -d;
6895	            te[6] = b * c;
6896	            te[10] = a * c;
6897	        } else if (euler.order === 'YZX') {
6898	            const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
6899	            te[0] = c * e;
6900	            te[4] = bd - ac * f;
6901	            te[8] = bc * f + ad;
6902	            te[1] = f;
6903	            te[5] = a * e;
6904	            te[9] = -b * e;
6905	            te[2] = -d * e;
6906	            te[6] = ad * f + bc;
6907	            te[10] = ac - bd * f;
6908	        } else if (euler.order === 'XZY') {
6909	            const ac = a * c, ad = a * d, bc = b * c, bd = b * d;
6910	            te[0] = c * e;
6911	            te[4] = -f;
6912	            te[8] = d * e;
6913	            te[1] = ac * f + bd;
6914	            te[5] = a * e;
6915	            te[9] = ad * f - bc;
6916	            te[2] = bc * f - ad;
6917	            te[6] = b * e;
6918	            te[10] = bd * f + ac;
6919	        }
6920	        // bottom row
6921	        te[3] = 0;
6922	        te[7] = 0;
6923	        te[11] = 0;
6924	        // last column
6925	        te[12] = 0;
6926	        te[13] = 0;
6927	        te[14] = 0;
6928	        te[15] = 1;
6929	        return this;
6930	    }
6931	    /**
6932		 * Sets the rotation component of this matrix to the rotation specified by
6933		 * the given Quaternion as outlined [here]{@link https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion}
6934		 * The rest of the matrix is set to the identity.
6935		 *
6936		 * @param {Quaternion} q - The Quaternion.
6937		 * @return {Matrix4} A reference to this matrix.
6938		 */ makeRotationFromQuaternion(q) {
6939	        return this.compose(_zero, q, _one);
6940	    }
6941	    /**
6942		 * Sets the rotation component of the transformation matrix, looking from `eye` towards
6943		 * `target`, and oriented by the up-direction.
6944		 *
6945		 * @param {Vector3} eye - The eye vector.
6946		 * @param {Vector3} target - The target vector.
6947		 * @param {Vector3} up - The up vector.
6948		 * @return {Matrix4} A reference to this matrix.
6949		 */ lookAt(eye, target, up) {
6950	        const te = this.elements;
6951	        _z.subVectors(eye, target);
6952	        if (_z.lengthSq() === 0) {
6953	            // eye and target are in the same position
6954	            _z.z = 1;
6955	        }
6956	        _z.normalize();
6957	        _x.crossVectors(up, _z);
6958	        if (_x.lengthSq() === 0) {
6959	            // up and z are parallel
6960	            if (Math.abs(up.z) === 1) {
6961	                _z.x += 0.0001;
6962	            } else {
6963	                _z.z += 0.0001;
6964	            }
6965	            _z.normalize();
6966	            _x.crossVectors(up, _z);
6967	        }
6968	        _x.normalize();
6969	        _y.crossVectors(_z, _x);
6970	        te[0] = _x.x;
6971	        te[4] = _y.x;
6972	        te[8] = _z.x;
6973	        te[1] = _x.y;
6974	        te[5] = _y.y;
6975	        te[9] = _z.y;
6976	        te[2] = _x.z;
vendor: 6,220 bytes, lines 6977-7130
6977	        te[6] = _y.z;
6978	        te[10] = _z.z;
6979	        return this;
6980	    }
6981	    /**
6982		 * Post-multiplies this matrix by the given 4x4 matrix.
6983		 *
6984		 * @param {Matrix4} m - The matrix to multiply with.
6985		 * @return {Matrix4} A reference to this matrix.
6986		 */ multiply(m) {
6987	        return this.multiplyMatrices(this, m);
6988	    }
6989	    /**
6990		 * Pre-multiplies this matrix by the given 4x4 matrix.
6991		 *
6992		 * @param {Matrix4} m - The matrix to multiply with.
6993		 * @return {Matrix4} A reference to this matrix.
6994		 */ premultiply(m) {
6995	        return this.multiplyMatrices(m, this);
6996	    }
6997	    /**
6998		 * Multiples the given 4x4 matrices and stores the result
6999		 * in this matrix.
7000		 *
7001		 * @param {Matrix4} a - The first matrix.
7002		 * @param {Matrix4} b - The second matrix.
7003		 * @return {Matrix4} A reference to this matrix.
7004		 */ multiplyMatrices(a, b) {
7005	        const ae = a.elements;
7006	        const be = b.elements;
7007	        const te = this.elements;
7008	        const a11 = ae[0], a12 = ae[4], a13 = ae[8], a14 = ae[12];
7009	        const a21 = ae[1], a22 = ae[5], a23 = ae[9], a24 = ae[13];
7010	        const a31 = ae[2], a32 = ae[6], a33 = ae[10], a34 = ae[14];
7011	        const a41 = ae[3], a42 = ae[7], a43 = ae[11], a44 = ae[15];
7012	        const b11 = be[0], b12 = be[4], b13 = be[8], b14 = be[12];
7013	        const b21 = be[1], b22 = be[5], b23 = be[9], b24 = be[13];
7014	        const b31 = be[2], b32 = be[6], b33 = be[10], b34 = be[14];
7015	        const b41 = be[3], b42 = be[7], b43 = be[11], b44 = be[15];
7016	        te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
7017	        te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
7018	        te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
7019	        te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
7020	        te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
7021	        te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
7022	        te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
7023	        te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
7024	        te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
7025	        te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
7026	        te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
7027	        te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
7028	        te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
7029	        te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
7030	        te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
7031	        te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
7032	        return this;
7033	    }
7034	    /**
7035		 * Multiplies every component of the matrix by the given scalar.
7036		 *
7037		 * @param {number} s - The scalar.
7038		 * @return {Matrix4} A reference to this matrix.
7039		 */ multiplyScalar(s) {
7040	        const te = this.elements;
7041	        te[0] *= s;
7042	        te[4] *= s;
7043	        te[8] *= s;
7044	        te[12] *= s;
7045	        te[1] *= s;
7046	        te[5] *= s;
7047	        te[9] *= s;
7048	        te[13] *= s;
7049	        te[2] *= s;
7050	        te[6] *= s;
7051	        te[10] *= s;
7052	        te[14] *= s;
7053	        te[3] *= s;
7054	        te[7] *= s;
7055	        te[11] *= s;
7056	        te[15] *= s;
7057	        return this;
7058	    }
7059	    /**
7060		 * Computes and returns the determinant of this matrix.
7061		 *
7062		 * Based on the method outlined [here]{@link http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html}.
7063		 *
7064		 * @return {number} The determinant.
7065		 */ determinant() {
7066	        const te = this.elements;
7067	        const n11 = te[0], n12 = te[4], n13 = te[8], n14 = te[12];
7068	        const n21 = te[1], n22 = te[5], n23 = te[9], n24 = te[13];
7069	        const n31 = te[2], n32 = te[6], n33 = te[10], n34 = te[14];
7070	        const n41 = te[3], n42 = te[7], n43 = te[11], n44 = te[15];
7071	        //TODO: make this more efficient
7072	        return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
7073	    }
7074	    /**
7075		 * Transposes this matrix in place.
7076		 *
7077		 * @return {Matrix4} A reference to this matrix.
7078		 */ transpose() {
7079	        const te = this.elements;
7080	        let tmp;
7081	        tmp = te[1];
7082	        te[1] = te[4];
7083	        te[4] = tmp;
7084	        tmp = te[2];
7085	        te[2] = te[8];
7086	        te[8] = tmp;
7087	        tmp = te[6];
7088	        te[6] = te[9];
7089	        te[9] = tmp;
7090	        tmp = te[3];
7091	        te[3] = te[12];
7092	        te[12] = tmp;
7093	        tmp = te[7];
7094	        te[7] = te[13];
7095	        te[13] = tmp;
7096	        tmp = te[11];
7097	        te[11] = te[14];
7098	        te[14] = tmp;
7099	        return this;
7100	    }
7101	    /**
7102		 * Sets the position component for this matrix from the given vector,
7103		 * without affecting the rest of the matrix.
7104		 *
7105		 * @param {number|Vector3} x - The x component of the vector or alternatively the vector object.
7106		 * @param {number} y - The y component of the vector.
7107		 * @param {number} z - The z component of the vector.
7108		 * @return {Matrix4} A reference to this matrix.
7109		 */ setPosition(x, y, z) {
7110	        const te = this.elements;
7111	        if (x.isVector3) {
7112	            te[12] = x.x;
7113	            te[13] = x.y;
7114	            te[14] = x.z;
7115	        } else {
7116	            te[12] = x;
7117	            te[13] = y;
7118	            te[14] = z;
7119	        }
7120	        return this;
7121	    }
7122	    /**
7123		 * Inverts this matrix, using the [analytic method]{@link https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution}.
7124		 * You can not invert with a determinant of zero. If you attempt this, the method produces
7125		 * a zero matrix instead.
7126		 *
7127		 * @return {Matrix4} A reference to this matrix.
7128		 */ invert() {
7129	        // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
7130	        const te = this.elements, n11 = te[0], n21 = te[1], n31 = te[2], n41 = te[3], n12 = te[4], n22 = te[5], n32 = te[6], n42 = te[7], n13 = te[8], n23 = te[9], n33 = te[10], n43 = te[11
vendor: 12,440 bytes, lines 7130-7402
7130], n14 = te[12], n24 = te[13], n34 = te[14], n44 = te[15], t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44, t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44, t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44, t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
7131	        const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
7132	        if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
7133	        const detInv = 1 / det;
7134	        te[0] = t11 * detInv;
7135	        te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
7136	        te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
7137	        te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
7138	        te[4] = t12 * detInv;
7139	        te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
7140	        te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
7141	        te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
7142	        te[8] = t13 * detInv;
7143	        te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
7144	        te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
7145	        te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
7146	        te[12] = t14 * detInv;
7147	        te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
7148	        te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
7149	        te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
7150	        return this;
7151	    }
7152	    /**
7153		 * Multiplies the columns of this matrix by the given vector.
7154		 *
7155		 * @param {Vector3} v - The scale vector.
7156		 * @return {Matrix4} A reference to this matrix.
7157		 */ scale(v) {
7158	        const te = this.elements;
7159	        const x = v.x, y = v.y, z = v.z;
7160	        te[0] *= x;
7161	        te[4] *= y;
7162	        te[8] *= z;
7163	        te[1] *= x;
7164	        te[5] *= y;
7165	        te[9] *= z;
7166	        te[2] *= x;
7167	        te[6] *= y;
7168	        te[10] *= z;
7169	        te[3] *= x;
7170	        te[7] *= y;
7171	        te[11] *= z;
7172	        return this;
7173	    }
7174	    /**
7175		 * Gets the maximum scale value of the three axes.
7176		 *
7177		 * @return {number} The maximum scale.
7178		 */ getMaxScaleOnAxis() {
7179	        const te = this.elements;
7180	        const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
7181	        const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
7182	        const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
7183	        return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
7184	    }
7185	    /**
7186		 * Sets this matrix as a translation transform from the given vector.
7187		 *
7188		 * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector.
7189		 * @param {number} y - The amount to translate in the Y axis.
7190		 * @param {number} z - The amount to translate in the z axis.
7191		 * @return {Matrix4} A reference to this matrix.
7192		 */ makeTranslation(x, y, z) {
7193	        if (x.isVector3) {
7194	            this.set(1, 0, 0, x.x, 0, 1, 0, x.y, 0, 0, 1, x.z, 0, 0, 0, 1);
7195	        } else {
7196	            this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
7197	        }
7198	        return this;
7199	    }
7200	    /**
7201		 * Sets this matrix as a rotational transformation around the X axis by
7202		 * the given angle.
7203		 *
7204		 * @param {number} theta - The rotation in radians.
7205		 * @return {Matrix4} A reference to this matrix.
7206		 */ makeRotationX(theta) {
7207	        const c = Math.cos(theta), s = Math.sin(theta);
7208	        this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
7209	        return this;
7210	    }
7211	    /**
7212		 * Sets this matrix as a rotational transformation around the Y axis by
7213		 * the given angle.
7214		 *
7215		 * @param {number} theta - The rotation in radians.
7216		 * @return {Matrix4} A reference to this matrix.
7217		 */ makeRotationY(theta) {
7218	        const c = Math.cos(theta), s = Math.sin(theta);
7219	        this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
7220	        return this;
7221	    }
7222	    /**
7223		 * Sets this matrix as a rotational transformation around the Z axis by
7224		 * the given angle.
7225		 *
7226		 * @param {number} theta - The rotation in radians.
7227		 * @return {Matrix4} A reference to this matrix.
7228		 */ makeRotationZ(theta) {
7229	        const c = Math.cos(theta), s = Math.sin(theta);
7230	        this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
7231	        return this;
7232	    }
7233	    /**
7234		 * Sets this matrix as a rotational transformation around the given axis by
7235		 * the given angle.
7236		 *
7237		 * This is a somewhat controversial but mathematically sound alternative to
7238		 * rotating via Quaternions. See the discussion [here]{@link https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199}.
7239		 *
7240		 * @param {Vector3} axis - The normalized rotation axis.
7241		 * @param {number} angle - The rotation in radians.
7242		 * @return {Matrix4} A reference to this matrix.
7243		 */ makeRotationAxis(axis, angle) {
7244	        // Based on http://www.gamedev.net/reference/articles/article1199.asp
7245	        const c = Math.cos(angle);
7246	        const s = Math.sin(angle);
7247	        const t = 1 - c;
7248	        const x = axis.x, y = axis.y, z = axis.z;
7249	        const tx = t * x, ty = t * y;
7250	        this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1);
7251	        return this;
7252	    }
7253	    /**
7254		 * Sets this matrix as a scale transformation.
7255		 *
7256		 * @param {number} x - The amount to scale in the X axis.
7257		 * @param {number} y - The amount to scale in the Y axis.
7258		 * @param {number} z - The amount to scale in the Z axis.
7259		 * @return {Matrix4} A reference to this matrix.
7260		 */ makeScale(x, y, z) {
7261	        this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1);
7262	        return this;
7263	    }
7264	    /**
7265		 * Sets this matrix as a shear transformation.
7266		 *
7267		 * @param {number} xy - The amount to shear X by Y.
7268		 * @param {number} xz - The amount to shear X by Z.
7269		 * @param {number} yx - The amount to shear Y by X.
7270		 * @param {number} yz - The amount to shear Y by Z.
7271		 * @param {number} zx - The amount to shear Z by X.
7272		 * @param {number} zy - The amount to shear Z by Y.
7273		 * @return {Matrix4} A reference to this matrix.
7274		 */ makeShear(xy, xz, yx, yz, zx, zy) {
7275	        this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1);
7276	        return this;
7277	    }
7278	    /**
7279		 * Sets this matrix to the transformation composed of the given position,
7280		 * rotation (Quaternion) and scale.
7281		 *
7282		 * @param {Vector3} position - The position vector.
7283		 * @param {Quaternion} quaternion - The rotation as a Quaternion.
7284		 * @param {Vector3} scale - The scale vector.
7285		 * @return {Matrix4} A reference to this matrix.
7286		 */ compose(position, quaternion, scale) {
7287	        const te = this.elements;
7288	        const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w;
7289	        const x2 = x + x, y2 = y + y, z2 = z + z;
7290	        const xx = x * x2, xy = x * y2, xz = x * z2;
7291	        const yy = y * y2, yz = y * z2, zz = z * z2;
7292	        const wx = w * x2, wy = w * y2, wz = w * z2;
7293	        const sx = scale.x, sy = scale.y, sz = scale.z;
7294	        te[0] = (1 - (yy + zz)) * sx;
7295	        te[1] = (xy + wz) * sx;
7296	        te[2] = (xz - wy) * sx;
7297	        te[3] = 0;
7298	        te[4] = (xy - wz) * sy;
7299	        te[5] = (1 - (xx + zz)) * sy;
7300	        te[6] = (yz + wx) * sy;
7301	        te[7] = 0;
7302	        te[8] = (xz + wy) * sz;
7303	        te[9] = (yz - wx) * sz;
7304	        te[10] = (1 - (xx + yy)) * sz;
7305	        te[11] = 0;
7306	        te[12] = position.x;
7307	        te[13] = position.y;
7308	        te[14] = position.z;
7309	        te[15] = 1;
7310	        return this;
7311	    }
7312	    /**
7313		 * Decomposes this matrix into its position, rotation and scale components
7314		 * and provides the result in the given objects.
7315		 *
7316		 * Note: Not all matrices are decomposable in this way. For example, if an
7317		 * object has a non-uniformly scaled parent, then the object's world matrix
7318		 * may not be decomposable, and this method may not be appropriate.
7319		 *
7320		 * @param {Vector3} position - The position vector.
7321		 * @param {Quaternion} quaternion - The rotation as a Quaternion.
7322		 * @param {Vector3} scale - The scale vector.
7323		 * @return {Matrix4} A reference to this matrix.
7324		 */ decompose(position, quaternion, scale) {
7325	        const te = this.elements;
7326	        let sx = _v1$5.set(te[0], te[1], te[2]).length();
7327	        const sy = _v1$5.set(te[4], te[5], te[6]).length();
7328	        const sz = _v1$5.set(te[8], te[9], te[10]).length();
7329	        // if determine is negative, we need to invert one scale
7330	        const det = this.determinant();
7331	        if (det < 0) sx = -sx;
7332	        position.x = te[12];
7333	        position.y = te[13];
7334	        position.z = te[14];
7335	        // scale the rotation part
7336	        _m1$2.copy(this);
7337	        const invSX = 1 / sx;
7338	        const invSY = 1 / sy;
7339	        const invSZ = 1 / sz;
7340	        _m1$2.elements[0] *= invSX;
7341	        _m1$2.elements[1] *= invSX;
7342	        _m1$2.elements[2] *= invSX;
7343	        _m1$2.elements[4] *= invSY;
7344	        _m1$2.elements[5] *= invSY;
7345	        _m1$2.elements[6] *= invSY;
7346	        _m1$2.elements[8] *= invSZ;
7347	        _m1$2.elements[9] *= invSZ;
7348	        _m1$2.elements[10] *= invSZ;
7349	        quaternion.setFromRotationMatrix(_m1$2);
7350	        scale.x = sx;
7351	        scale.y = sy;
7352	        scale.z = sz;
7353	        return this;
7354	    }
7355	    /**
7356		 * Creates a perspective projection matrix. This is used internally by
7357		 * {@link PerspectiveCamera#updateProjectionMatrix}.
7358
7359		 * @param {number} left - Left boundary of the viewing frustum at the near plane.
7360		 * @param {number} right - Right boundary of the viewing frustum at the near plane.
7361		 * @param {number} top - Top boundary of the viewing frustum at the near plane.
7362		 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
7363		 * @param {number} near - The distance from the camera to the near plane.
7364		 * @param {number} far - The distance from the camera to the far plane.
7365		 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
7366		 * @return {Matrix4} A reference to this matrix.
7367		 */ makePerspective(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem) {
7368	        const te = this.elements;
7369	        const x = 2 * near / (right - left);
7370	        const y = 2 * near / (top - bottom);
7371	        const a = (right + left) / (right - left);
7372	        const b = (top + bottom) / (top - bottom);
7373	        let c, d;
7374	        if (coordinateSystem === WebGLCoordinateSystem) {
7375	            c = -(far + near) / (far - near);
7376	            d = -2 * far * near / (far - near);
7377	        } else if (coordinateSystem === WebGPUCoordinateSystem) {
7378	            c = -far / (far - near);
7379	            d = -far * near / (far - near);
7380	        } else {
7381	            throw new Error('THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem);
7382	        }
7383	        te[0] = x;
7384	        te[4] = 0;
7385	        te[8] = a;
7386	        te[12] = 0;
7387	        te[1] = 0;
7388	        te[5] = y;
7389	        te[9] = b;
7390	        te[13] = 0;
7391	        te[2] = 0;
7392	        te[6] = 0;
7393	        te[10] = c;
7394	        te[14] = d;
7395	        te[3] = 0;
7396	        te[7] = 0;
7397	        te[11] = -1;
7398	        te[15] = 0;
7399	        return this;
7400	    }
7401	    /**
7402		 * Creates a orthographic projection matrix. This is used internally by
7403		 * {@link OrthographicCamera#updateProjectionMatrix}.
7404
7405		 * @param {number} left - Left boundary of the viewing frustum at the near plane.
7406		 * @param {number} right - Right boundary of the viewing frustum at the near plane.
7407		 * @param {number} top - Top boundary of the viewing frustum at the near plane.
7408		 * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane.
7409		 * @param {number} near - The distance from the camera to the near plane.
7410		 * @param {number} far - The distance from the camera to the far plane.
7411		 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system.
7412		 * @return {Matrix4} A reference to this matrix.
7413		 */ makeOrthographic(left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem) {
7414	        const te = this.elements;
7415	        const w = 1.0 / (right - left);
7416	        const h = 1.0 / (top - bottom);
7417	        const p = 1.0 / (far - near);
7418	        const x = (right + left) * w;
7419	        const y = (top + bottom) * h;
7420	        let z, zInv;
7421	        if (coordinateSystem === WebGLCoordinateSystem) {
7422	            z = (far + near) * p;
7423	            zInv = -2 * p;
7424	        } else if (coordinateSystem === WebGPUCoordinateSystem) {
7425	            z = near * p;
7426	            zInv = -1 * p;
7427	        } else {
7428	            throw new Error('THREE.Matrix4.makeOrthographic(): Invalid coordinate system: ' + coordinateSystem);
7429	        }
7430	        te[0] = 2 * w;
7431	        te[4] = 0;
7432	        te[8] = 0;
7433	        te[12] = -x;
7434	        te[1] = 0;
7435	        te[5] = 2 * h;
7436	        te[9] = 0;
7437	        te[13] = -y;
7438	        te[2] = 0;
7439	        te[6] = 0;
7440	        te[10] = zInv;
7441	        te[14] = -z;
7442	        te[3] = 0;
7443	        te[7] = 0;
7444	        te[11] = 0;
7445	        te[15] = 1;
7446	        return this;
7447	    }
7448	    /**
7449		 * Returns `true` if this matrix is equal with the given one.
7450		 *
7451		 * @param {Matrix4} matrix - The matrix to test for equality.
7452		 * @return {boolean} Whether this matrix is equal with the given one.
7453		 */ equals(matrix) {
7454	        const te = this.elements;
7455	        const me = matrix.elements;
7456	        for(let i = 0; i < 16; i++){
7457	            if (te[i] !== me[i]) return false;
7458	        }
7459	        return true;
7460	    }
7461	    /**
7462		 * Sets the elements of the matrix from the given array.
7463		 *
7464		 * @param {Array<number>} array - The matrix elements in column-major order.
7465		 * @param {number} [offset=0] - Index of the first element in the array.
7466		 * @return {Matrix4} A reference to this matrix.
7467		 */ fromArray(array, offset = 0) {
7468	        for(let i = 0; i < 16; i++){
7469	            this.elements[i] = array[i + offset];
7470	        }
7471	        return this;
7472	    }
7473	    /**
7474		 * Writes the elements of this matrix to the given array. If no array is provided,
7475		 * the method returns a new instance.
7476		 *
7477		 * @param {Array<number>} [array=[]] - The target array holding the matrix elements in column-major order.
7478		 * @param {number} [offset=0] - Index of the first element in the array.
7479		 * @return {Array<number>} The matrix elements in column-major order.
7480		 */ toArray(array = [], offset = 0) {
7481	        const te = this.elements;
7482	        array[offset] = te[0];
7483	        array[offset + 1] = te[1];
7484	        array[offset + 2] = te[2];
7485	        array[offset + 3] = te[3];
7486	        array[offset + 4] = te[4];
7487	        array[offset + 5] = te[5];
7488	        array[offset + 6] = te[6];
7489	        array[offset + 7] = te[7];
7490	        array[offset + 8] = te[8];
7491	        array[offset + 9] = te[9];
7492	        array[offset + 10] = te[10];
7493	        array[offset + 11] = te[11];
7494	        array[offset + 12] = te[12];
7495	        array[offset + 13] = te[13];
7496	        array[offset + 14] = te[14];
7497	        array[offset + 15] = te[15];
7498	        return array;
7499	    }
7500	    /**
7501		 * Constructs a new 4x4 matrix. The arguments are supposed to be
7502		 * in row-major order. If no arguments are provided, the constructor
7503		 * initializes the matrix as an identity matrix.
7504		 *
7505		 * @param {number} [n11] - 1-1 matrix element.
7506		 * @param {number} [n12] - 1-2 matrix element.
7507		 * @param {number} [n13] - 1-3 matrix element.
7508		 * @param {number} [n14] - 1-4 matrix element.
7509		 * @param {number} [n21] - 2-1 matrix element.
7510		 * @param {number} [n22] - 2-2 matrix element.
7511		 * @param {number} [n23] - 2-3 matrix element.
7512		 * @param {number} [n24] - 2-4 matrix element.
7513		 * @param {number} [n31] - 3-1 matrix element.
7514		 * @param {number} [n32] - 3-2 matrix element.
7515		 * @param {number} [n33] - 3-3 matrix element.
7516		 * @param {number} [n34] - 3-4 matrix element.
7517		 * @param {number} [n41] - 4-1 matrix element.
7518		 * @param {number}
7518 [n42] - 4-2 matrix element.
7519		 * @param {number} [n43] - 4-3 matrix element.
7520		 * @param {number} [n44] - 4-4 matrix element.
7521		 */ constructor(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44){
7522	        /**
7523			 * This flag can be used for type testing.
7524			 *
7525			 * @type {boolean}
7526			 * @readonly
7527			 * @default true
7528			 */ Matrix4.prototype.isMatrix4 = true;
7529	        /**
7530			 * A column-major list of matrix values.
7531			 *
7532			 * @type {Array<number>}
7533			 */ this.elements = [
7534	            1,
7535	            0,
7536	            0,
7537	            0,
7538	            0,
7539	            1,
7540	            0,
7541	            0,
7542	            0,
7543	            0,
7544	            1,
7545	            0,
7546	            0,
7547	            0,
7548	            0,
7549	            1
7550	        ];
7551	        if (n11 !== undefined) {
7552	            this.set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44);
7553	        }
7554	    }
7555	}
7556	const _v1$5 = /*@__PURE__*/ new Vector3();
7557	const _m1$2 = /*@__PURE__*/ new Matrix4();
7558	const _zero = /*@__PURE__*/ new Vector3(0, 0, 0);
7559	const _one = /*@__PURE__*/ new Vector3(1, 1, 1);
7560	const _x = /*@__PURE__*/ new Vector3();
7561	const _y = /*@__PURE__*/ new Vector3();
7562	const _z = /*@__PURE__*/ new Vector3();
7563	const _matrix$2 = /*@__PURE__*/ new Matrix4();
7564	const _quaternion$3 = /*@__PURE__*/ new Quaternion();
7565	/**
7566	 * A class representing Euler angles.
7567	 *
7568	 * Euler angles describe a rotational transformation by rotating an object on
7569	 * its various axes in specified amounts per axis, and a specified axis
7570	 * order.
7571	 *
7572	 * Iterating through an instance will yield its components (x, y, z,
7573	 * order) in the corresponding order.
7574	 *
7575	 * ```js
7576	 * const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' );
7577	 * const b = new THREE.Vector3( 1, 0, 1 );
7578	 * b.applyEuler(a);
7579	 * ```
7580	 */ class Euler {
7581	    /**
7582		 * The angle of the x axis in radians.
7583		 *
7584		 * @type {number}
7585		 * @default 0
7586		 */ get x() {
7587	        return this._x;
7588	    }
7589	    set x(value) {
7590	        this._x = value;
7591	        this._onChangeCallback();
7592	    }
7593	    /**
7594		 * The angle of the y axis in radians.
7595		 *
7596		 * @type {number}
7597		 * @default 0
7598		 */ get y() {
7599	        return this._y;
7600	    }
7601	    set y(value) {
7602	        this._y = value;
7603	        this._onChangeCallback();
7604	    }
7605	    /**
7606		 * The angle of the z axis in radians.
7607		 *
7608		 * @type {number}
7609		 * @default 0
7610		 */ get z() {
7611	        return this._z;
7612	    }
7613	    set z(value) {
7614	        this._z = value;
7615	        this._onChangeCallback();
7616	    }
7617	    /**
7618		 * A string representing the order that the rotations are applied.
7619		 *
7620		 * @type {string}
7621		 * @default 'XYZ'
7622		 */ get order() {
7623	        return this._order;
7624	    }
7625	    set order(value) {
7626	        this._order = value;
7627	        this._onChangeCallback();
7628	    }
7629	    /**
7630		 * Sets the Euler components.
7631		 *
7632		 * @param {number} x - The angle of the x axis in radians.
7633		 * @param {number} y - The angle of the y axis in radians.
7634		 * @param {number} z - The angle of the z axis in radians.
7635		 * @param {string} [order] - A string representing the order that the rotations are applied.
7636		 * @return {Euler} A reference to this Euler instance.
7637		 */ set(x, y, z, order = this._order) {
7638	        this._x = x;
7639	        this._y = y;
7640	        this._z = z;
7641	        this._order = order;
7642	        this._onChangeCallback();
7643	        return this;
7644	    }
7645	    /**
7646		 * Returns a new Euler instance with copied values from this instance.
7647		 *
7648		 * @return {Euler} A clone of this instance.
7649		 */ clone() {
7650	        return new this.constructor(this._x, this._y, this._z, this._order);
7651	    }
7652	    /**
7653		 * Copies the values of the given Euler instance to this instance.
7654		 *
7655		 * @param {Euler} euler - The Euler instance to copy.
7656		 * @return {Euler} A reference to this Euler instance.
7657		 */ copy(euler) {
7658	        this._x = euler._x;
7659	        this._y = euler._y;
7660	        this._z = euler._z;
7661	        this._order = euler._order;
7662	        this._onChangeCallback();
7663	        return this;
7664	    }
7665	    /**
7666		 * Sets the angles of this Euler instance from a pure rotation matrix.
7667		 *
7668		 * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled).
7669		 * @param {string} [order] - A string representing the order that the rotations are applied.
7670		 * @param {boolean}
vendor: 9,336 bytes, lines 7670-7932
7670 [update=true] - Whether the internal `onChange` callback should be executed or not.
7671		 * @return {Euler} A reference to this Euler instance.
7672		 */ setFromRotationMatrix(m, order = this._order, update = true) {
7673	        const te = m.elements;
7674	        const m11 = te[0], m12 = te[4], m13 = te[8];
7675	        const m21 = te[1], m22 = te[5], m23 = te[9];
7676	        const m31 = te[2], m32 = te[6], m33 = te[10];
7677	        switch(order){
7678	            case 'XYZ':
7679	                this._y = Math.asin(clamp$1(m13, -1, 1));
7680	                if (Math.abs(m13) < 0.9999999) {
7681	                    this._x = Math.atan2(-m23, m33);
7682	                    this._z = Math.atan2(-m12, m11);
7683	                } else {
7684	                    this._x = Math.atan2(m32, m22);
7685	                    this._z = 0;
7686	                }
7687	                break;
7688	            case 'YXZ':
7689	                this._x = Math.asin(-clamp$1(m23, -1, 1));
7690	                if (Math.abs(m23) < 0.9999999) {
7691	                    this._y = Math.atan2(m13, m33);
7692	                    this._z = Math.atan2(m21, m22);
7693	                } else {
7694	                    this._y = Math.atan2(-m31, m11);
7695	                    this._z = 0;
7696	                }
7697	                break;
7698	            case 'ZXY':
7699	                this._x = Math.asin(clamp$1(m32, -1, 1));
7700	                if (Math.abs(m32) < 0.9999999) {
7701	                    this._y = Math.atan2(-m31, m33);
7702	                    this._z = Math.atan2(-m12, m22);
7703	                } else {
7704	                    this._y = 0;
7705	                    this._z = Math.atan2(m21, m11);
7706	                }
7707	                break;
7708	            case 'ZYX':
7709	                this._y = Math.asin(-clamp$1(m31, -1, 1));
7710	                if (Math.abs(m31) < 0.9999999) {
7711	                    this._x = Math.atan2(m32, m33);
7712	                    this._z = Math.atan2(m21, m11);
7713	                } else {
7714	                    this._x = 0;
7715	                    this._z = Math.atan2(-m12, m22);
7716	                }
7717	                break;
7718	            case 'YZX':
7719	                this._z = Math.asin(clamp$1(m21, -1, 1));
7720	                if (Math.abs(m21) < 0.9999999) {
7721	                    this._x = Math.atan2(-m23, m22);
7722	                    this._y = Math.atan2(-m31, m11);
7723	                } else {
7724	                    this._x = 0;
7725	                    this._y = Math.atan2(m13, m33);
7726	                }
7727	                break;
7728	            case 'XZY':
7729	                this._z = Math.asin(-clamp$1(m12, -1, 1));
7730	                if (Math.abs(m12) < 0.9999999) {
7731	                    this._x = Math.atan2(m32, m22);
7732	                    this._y = Math.atan2(m13, m11);
7733	                } else {
7734	                    this._x = Math.atan2(-m23, m33);
7735	                    this._y = 0;
7736	                }
7737	                break;
7738	            default:
7739	                console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order);
7740	        }
7741	        this._order = order;
7742	        if (update === true) this._onChangeCallback();
7743	        return this;
7744	    }
7745	    /**
7746		 * Sets the angles of this Euler instance from a normalized quaternion.
7747		 *
7748		 * @param {Quaternion} q - A normalized Quaternion.
7749		 * @param {string} [order] - A string representing the order that the rotations are applied.
7750		 * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not.
7751		 * @return {Euler} A reference to this Euler instance.
7752		 */ setFromQuaternion(q, order, update) {
7753	        _matrix$2.makeRotationFromQuaternion(q);
7754	        return this.setFromRotationMatrix(_matrix$2, order, update);
7755	    }
7756	    /**
7757		 * Sets the angles of this Euler instance from the given vector.
7758		 *
7759		 * @param {Vector3} v - The vector.
7760		 * @param {string} [order] - A string representing the order that the rotations are applied.
7761		 * @return {Euler} A reference to this Euler instance.
7762		 */ setFromVector3(v, order = this._order) {
7763	        return this.set(v.x, v.y, v.z, order);
7764	    }
7765	    /**
7766		 * Resets the euler angle with a new order by creating a quaternion from this
7767		 * euler angle and then setting this euler angle with the quaternion and the
7768		 * new order.
7769		 *
7770		 * Warning: This discards revolution information.
7771		 *
7772		 * @param {string} [newOrder] - A string representing the new order that the rotations are applied.
7773		 * @return {Euler} A reference to this Euler instance.
7774		 */ reorder(newOrder) {
7775	        _quaternion$3.setFromEuler(this);
7776	        return this.setFromQuaternion(_quaternion$3, newOrder);
7777	    }
7778	    /**
7779		 * Returns `true` if this Euler instance is equal with the given one.
7780		 *
7781		 * @param {Euler} euler - The Euler instance to test for equality.
7782		 * @return {boolean} Whether this Euler instance is equal with the given one.
7783		 */ equals(euler) {
7784	        return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
7785	    }
7786	    /**
7787		 * Sets this Euler instance's components to values from the given array. The first three
7788		 * entries of the array are assign to the x,y and z components. An optional fourth entry
7789		 * defines the Euler order.
7790		 *
7791		 * @param {Array<number,number,number,?string>} array - An array holding the Euler component values.
7792		 * @return {Euler} A reference to this Euler instance.
7793		 */ fromArray(array) {
7794	        this._x = array[0];
7795	        this._y = array[1];
7796	        this._z = array[2];
7797	        if (array[3] !== undefined) this._order = array[3];
7798	        this._onChangeCallback();
7799	        return this;
7800	    }
7801	    /**
7802		 * Writes the components of this Euler instance to the given array. If no array is provided,
7803		 * the method returns a new instance.
7804		 *
7805		 * @param {Array<number,number,number,string>} [array=[]] - The target array holding the Euler components.
7806		 * @param {number} [offset=0] - Index of the first element in the array.
7807		 * @return {Array<number,number,number,string>} The Euler components.
7808		 */ toArray(array = [], offset = 0) {
7809	        array[offset] = this._x;
7810	        array[offset + 1] = this._y;
7811	        array[offset + 2] = this._z;
7812	        array[offset + 3] = this._order;
7813	        return array;
7814	    }
7815	    _onChange(callback) {
7816	        this._onChangeCallback = callback;
7817	        return this;
7818	    }
7819	    _onChangeCallback() {}
7820	    *[Symbol.iterator]() {
7821	        yield this._x;
7822	        yield this._y;
7823	        yield this._z;
7824	        yield this._order;
7825	    }
7826	    /**
7827		 * Constructs a new euler instance.
7828		 *
7829		 * @param {number} [x=0] - The angle of the x axis in radians.
7830		 * @param {number} [y=0] - The angle of the y axis in radians.
7831		 * @param {number} [z=0] - The angle of the z axis in radians.
7832		 * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied.
7833		 */ constructor(x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER){
7834	        /**
7835			 * This flag can be used for type testing.
7836			 *
7837			 * @type {boolean}
7838			 * @readonly
7839			 * @default true
7840			 */ this.isEuler = true;
7841	        this._x = x;
7842	        this._y = y;
7843	        this._z = z;
7844	        this._order = order;
7845	    }
7846	}
7847	/**
7848	 * The default Euler angle order.
7849	 *
7850	 * @static
7851	 * @type {string}
7852	 * @default 'XYZ'
7853	 */ Euler.DEFAULT_ORDER = 'XYZ';
7854	class Layers {
7855	    set(channel) {
7856	        this.mask = (1 << channel | 0) >>> 0;
7857	    }
7858	    enable(channel) {
7859	        this.mask |= 1 << channel | 0;
7860	    }
7861	    enableAll() {
7862	        this.mask = 0xffffffff | 0;
7863	    }
7864	    toggle(channel) {
7865	        this.mask ^= 1 << channel | 0;
7866	    }
7867	    disable(channel) {
7868	        this.mask &= ~(1 << channel | 0);
7869	    }
7870	    disableAll() {
7871	        this.mask = 0;
7872	    }
7873	    test(layers) {
7874	        return (this.mask & layers.mask) !== 0;
7875	    }
7876	    isEnabled(channel) {
7877	        return (this.mask & (1 << channel | 0)) !== 0;
7878	    }
7879	    constructor(){
7880	        this.mask = 1 | 0;
7881	    }
7882	}
7883	let _object3DId = 0;
7884	const _v1$4 = /*@__PURE__*/ new Vector3();
7885	const _q1 = /*@__PURE__*/ new Quaternion();
7886	const _m1$1$1 = /*@__PURE__*/ new Matrix4();
7887	const _target = /*@__PURE__*/ new Vector3();
7888	const _position$3 = /*@__PURE__*/ new Vector3();
7889	const _scale$2 = /*@__PURE__*/ new Vector3();
7890	const _quaternion$2 = /*@__PURE__*/ new Quaternion();
7891	const _xAxis = /*@__PURE__*/ new Vector3(1, 0, 0);
7892	const _yAxis = /*@__PURE__*/ new Vector3(0, 1, 0);
7893	const _zAxis = /*@__PURE__*/ new Vector3(0, 0, 1);
7894	/**
7895	 * Fires when the object has been added to its parent object.
7896	 *
7897	 * @event Object3D#added
7898	 * @type {Object}
7899	 */ const _addedEvent = {
7900	    type: 'added'
7901	};
7902	/**
7903	 * Fires when the object has been removed from its parent object.
7904	 *
7905	 * @event Object3D#removed
7906	 * @type {Object}
7907	 */ const _removedEvent = {
7908	    type: 'removed'
7909	};
7910	/**
7911	 * Fires when a new child object has been added.
7912	 *
7913	 * @event Object3D#childadded
7914	 * @type {Object}
7915	 */ const _childaddedEvent = {
7916	    type: 'childadded',
7917	    child: null
7918	};
7919	/**
7920	 * Fires when a new child object has been added.
7921	 *
7922	 * @event Object3D#childremoved
7923	 * @type {Object}
7924	 */ const _childremovedEvent = {
7925	    type: 'childremoved',
7926	    child: null
7927	};
7928	/**
7929	 * This is the base class for most objects in three.js and provides a set of
7930	 * properties and methods for manipulating objects in 3D space.
7931	 *
7932	 * @augments EventDispatcher
7933	 */ class Object3D extends EventDispatcher {
7934	    /**
7935		 * A callback that is executed immediately before a 3D object is rendered to a shadow map.
7936		 *
7937		 * @param {Renderer|WebGLRenderer} renderer - The renderer.
7938		 * @param {Object3D} object - The 3D object.
7939		 * @param {Camera} camera - The camera that is used to render the scene.
7940		 * @param {Camera} shadowCamera - The shadow camera.
7941		 * @param {BufferGeometry} geometry - The 3D object's geometry.
7942		 * @param {Material} depthMaterial - The depth material.
7943		 * @param {Object} group - The geometry group data.
7944		 */ onBeforeShadow() {}
7945	    /**
7946		 * A callback that is executed immediately after a 3D object is rendered to a shadow map.
7947		 *
7948		 * @param {Renderer|WebGLRenderer} renderer - The renderer.
7949		 * @param {Object3D} object - The 3D object.
7950		 * @param {Camera} camera - The camera that is used to render the scene.
7951		 * @param {Camera} shadowCamera - The shadow camera.
7952		 * @param {BufferGeometry} geometry - The 3D object's geometry.
7953		 * @param {Material} depthMaterial - The depth material.
7954		 * @param {Object} group - The geometry group data.
7955		 */ onAfterShadow() {}
7956	    /**
7957		 * A callback that is executed immediately before a 3D object is rendered.
7958		 *
7959		 * @param {Renderer|WebGLRenderer} renderer - The renderer.
7960		 * @param {Object3D} object - The 3D object.
7961		 * @param {Camera} camera - The camera that is used to render the scene.
7962		 * @param {BufferGeometry} geometry - The 3D object's geometry.
7963		 * @param {Material} material - The 3D object's material.
7964		 * @param {Object} group - The geometry group data.
7965		 */ onBeforeRender() {}
7966	    /**
7967		 * A callback that is executed immediately after a 3D object is rendered.
7968		 *
7969		 * @param {Renderer|WebGLRenderer} renderer - The renderer.
7970		 * @param {Object3D} object - The 3D object.
7971		 * @param {Camera} camera - The camera that is used to render the scene.
7972		 * @param {BufferGeometry} geometry - The 3D object's geometry.
7973		 * @param {Material} material - The 3D object's material.
7974		 * @param {Object} group - The geometry group data.
7975		 */ onAfterRender() {}
7976	    /**
7977		 * Applies the given transformation matrix to the object and updates the object's position,
7978		 * rotation and scale.
7979		 *
7980		 * @param {Matrix4} matrix - The transformation matrix.
7981		 */ applyMatrix4(matrix) {
7982	        if (this.matrixAutoUpdate) this.updateMatrix();
7983	        this.matrix.premultiply(matrix);
7984	        this.matrix.decompose(this.position, this.quaternion, this.scale);
7985	    }
7986	    /**
7987		 * Applies a rotation represented by given the quaternion to the 3D object.
7988		 *
7989		 * @param {Quaternion} q - The quaternion.
7990		 * @return {Object3D} A reference to this instance.
7991		 */ applyQuaternion(q) {
7992	        this.quaternion.premultiply(q);
7993	        return this;
7994	    }
7995	    /**
7996		 * Sets the given rotation represented as an axis/angle couple to the 3D object.
7997		 *
7998		 * @param {Vector3} axis - The (normalized) axis vector.
7999		 * @param {number} angle - The angle in radians.
8000		 */ setRotationFromAxisAngle(axis, angle) {
8001	        // assumes axis is normalized
8002	        this.quaternion.setFromAxisAngle(axis, angle);
8003	    }
8004	    /**
8005		 * Sets the given rotation represented as Euler angles to the 3D object.
8006		 *
8007		 * @param {Euler} euler - The Euler angles.
8008		 */ setRotationFromEuler(euler) {
8009	        this.quaternion.setFromEuler(euler, true);
8010	    }
8011	    /**
8012		 * Sets the given rotation represented as rotation matrix to the 3D object.
8013		 *
8014		 * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be
8015		 * a pure rotation matrix (i.e, unscaled).
8016		 */ setRotationFromMatrix(m) {
8017	        // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
8018	        this.quaternion.setFromRotationMatrix(m);
8019	    }
8020	    /**
8021		 * Sets the given rotation represented as a Quaternion to the 3D object.
8022		 *
8023		 * @param {Quaternion} q - The Quaternion
8024		 */ setRotationFromQuaternion(q) {
8025	        // assumes q is normalized
8026	        this.quaternion.copy(q);
8027	    }
8028	    /**
8029		 * Rotates the 3D object along an axis in local space.
8030		 *
8031		 * @param {Vector3} axis - The (normalized) axis vector.
8032		 * @param {number} angle - The angle in radians.
8033		 * @return {Object3D} A reference to this instance.
8034		 */ rotateOnAxis(axis, angle) {
8035	        // rotate object on axis in object space
8036	        // axis is assumed to be normalized
8037	        _q1.setFromAxisAngle(axis, angle);
vendor: 4,501 bytes, lines 8038-8156
8038	        this.quaternion.multiply(_q1);
8039	        return this;
8040	    }
8041	    /**
8042		 * Rotates the 3D object along an axis in world space.
8043		 *
8044		 * @param {Vector3} axis - The (normalized) axis vector.
8045		 * @param {number} angle - The angle in radians.
8046		 * @return {Object3D} A reference to this instance.
8047		 */ rotateOnWorldAxis(axis, angle) {
8048	        // rotate object on axis in world space
8049	        // axis is assumed to be normalized
8050	        // method assumes no rotated parent
8051	        _q1.setFromAxisAngle(axis, angle);
8052	        this.quaternion.premultiply(_q1);
8053	        return this;
8054	    }
8055	    /**
8056		 * Rotates the 3D object around its X axis in local space.
8057		 *
8058		 * @param {number} angle - The angle in radians.
8059		 * @return {Object3D} A reference to this instance.
8060		 */ rotateX(angle) {
8061	        return this.rotateOnAxis(_xAxis, angle);
8062	    }
8063	    /**
8064		 * Rotates the 3D object around its Y axis in local space.
8065		 *
8066		 * @param {number} angle - The angle in radians.
8067		 * @return {Object3D} A reference to this instance.
8068		 */ rotateY(angle) {
8069	        return this.rotateOnAxis(_yAxis, angle);
8070	    }
8071	    /**
8072		 * Rotates the 3D object around its Z axis in local space.
8073		 *
8074		 * @param {number} angle - The angle in radians.
8075		 * @return {Object3D} A reference to this instance.
8076		 */ rotateZ(angle) {
8077	        return this.rotateOnAxis(_zAxis, angle);
8078	    }
8079	    /**
8080		 * Translate the 3D object by a distance along the given axis in local space.
8081		 *
8082		 * @param {Vector3} axis - The (normalized) axis vector.
8083		 * @param {number} distance - The distance in world units.
8084		 * @return {Object3D} A reference to this instance.
8085		 */ translateOnAxis(axis, distance) {
8086	        // translate object by distance along axis in object space
8087	        // axis is assumed to be normalized
8088	        _v1$4.copy(axis).applyQuaternion(this.quaternion);
8089	        this.position.add(_v1$4.multiplyScalar(distance));
8090	        return this;
8091	    }
8092	    /**
8093		 * Translate the 3D object by a distance along its X-axis in local space.
8094		 *
8095		 * @param {number} distance - The distance in world units.
8096		 * @return {Object3D} A reference to this instance.
8097		 */ translateX(distance) {
8098	        return this.translateOnAxis(_xAxis, distance);
8099	    }
8100	    /**
8101		 * Translate the 3D object by a distance along its Y-axis in local space.
8102		 *
8103		 * @param {number} distance - The distance in world units.
8104		 * @return {Object3D} A reference to this instance.
8105		 */ translateY(distance) {
8106	        return this.translateOnAxis(_yAxis, distance);
8107	    }
8108	    /**
8109		 * Translate the 3D object by a distance along its Z-axis in local space.
8110		 *
8111		 * @param {number} distance - The distance in world units.
8112		 * @return {Object3D} A reference to this instance.
8113		 */ translateZ(distance) {
8114	        return this.translateOnAxis(_zAxis, distance);
8115	    }
8116	    /**
8117		 * Converts the given vector from this 3D object's local space to world space.
8118		 *
8119		 * @param {Vector3} vector - The vector to convert.
8120		 * @return {Vector3} The converted vector.
8121		 */ localToWorld(vector) {
8122	        this.updateWorldMatrix(true, false);
8123	        return vector.applyMatrix4(this.matrixWorld);
8124	    }
8125	    /**
8126		 * Converts the given vector from this 3D object's word space to local space.
8127		 *
8128		 * @param {Vector3} vector - The vector to convert.
8129		 * @return {Vector3} The converted vector.
8130		 */ worldToLocal(vector) {
8131	        this.updateWorldMatrix(true, false);
8132	        return vector.applyMatrix4(_m1$1$1.copy(this.matrixWorld).invert());
8133	    }
8134	    /**
8135		 * Rotates the object to face a point in world space.
8136		 *
8137		 * This method does not support objects having non-uniformly-scaled parent(s).
8138		 *
8139		 * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space
8140		 * @param {number} [y] - The y coordinate in world space.
8141		 * @param {number} [z] - The z coordinate in world space.
8142		 */ lookAt(x, y, z) {
8143	        // This method does not support objects having non-uniformly-scaled parent(s)
8144	        if (x.isVector3) {
8145	            _target.copy(x);
8146	        } else {
8147	            _target.set(x, y, z);
8148	        }
8149	        const parent = this.parent;
8150	        this.updateWorldMatrix(true, false);
8151	        _position$3.setFromMatrixPosition(this.matrixWorld);
8152	        if (this.isCamera || this.isLight) {
8153	            _m1$1$1.lookAt(_position$3, _target, this.up);
8154	        } else {
8155	            _m1$1$1.lookAt(_target, _position$3, this.up);
8156	        }
vendor: 6,168 bytes, lines 8157-8315
8157	        this.quaternion.setFromRotationMatrix(_m1$1$1);
8158	        if (parent) {
8159	            _m1$1$1.extractRotation(parent.matrixWorld);
8160	            _q1.setFromRotationMatrix(_m1$1$1);
8161	            this.quaternion.premultiply(_q1.invert());
8162	        }
8163	    }
8164	    /**
8165		 * Adds the given 3D object as a child to this 3D object. An arbitrary number of
8166		 * objects may be added. Any current parent on an object passed in here will be
8167		 * removed, since an object can have at most one parent.
8168		 *
8169		 * @fires Object3D#added
8170		 * @fires Object3D#childadded
8171		 * @param {Object3D} object - The 3D object to add.
8172		 * @return {Object3D} A reference to this instance.
8173		 */ add(object) {
8174	        if (arguments.length > 1) {
8175	            for(let i = 0; i < arguments.length; i++){
8176	                this.add(arguments[i]);
8177	            }
8178	            return this;
8179	        }
8180	        if (object === this) {
8181	            console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object);
8182	            return this;
8183	        }
8184	        if (object && object.isObject3D) {
8185	            object.removeFromParent();
8186	            object.parent = this;
8187	            this.children.push(object);
8188	            object.dispatchEvent(_addedEvent);
8189	            _childaddedEvent.child = object;
8190	            this.dispatchEvent(_childaddedEvent);
8191	            _childaddedEvent.child = null;
8192	        } else {
8193	            console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object);
8194	        }
8195	        return this;
8196	    }
8197	    /**
8198		 * Removes the given 3D object as child from this 3D object.
8199		 * An arbitrary number of objects may be removed.
8200		 *
8201		 * @fires Object3D#removed
8202		 * @fires Object3D#childremoved
8203		 * @param {Object3D} object - The 3D object to remove.
8204		 * @return {Object3D} A reference to this instance.
8205		 */ remove(object) {
8206	        if (arguments.length > 1) {
8207	            for(let i = 0; i < arguments.length; i++){
8208	                this.remove(arguments[i]);
8209	            }
8210	            return this;
8211	        }
8212	        const index = this.children.indexOf(object);
8213	        if (index !== -1) {
8214	            object.parent = null;
8215	            this.children.splice(index, 1);
8216	            object.dispatchEvent(_removedEvent);
8217	            _childremovedEvent.child = object;
8218	            this.dispatchEvent(_childremovedEvent);
8219	            _childremovedEvent.child = null;
8220	        }
8221	        return this;
8222	    }
8223	    /**
8224		 * Removes this 3D object from its current parent.
8225		 *
8226		 * @fires Object3D#removed
8227		 * @fires Object3D#childremoved
8228		 * @return {Object3D} A reference to this instance.
8229		 */ removeFromParent() {
8230	        const parent = this.parent;
8231	        if (parent !== null) {
8232	            parent.remove(this);
8233	        }
8234	        return this;
8235	    }
8236	    /**
8237		 * Removes all child objects.
8238		 *
8239		 * @fires Object3D#removed
8240		 * @fires Object3D#childremoved
8241		 * @return {Object3D} A reference to this instance.
8242		 */ clear() {
8243	        return this.remove(...this.children);
8244	    }
8245	    /**
8246		 * Adds the given 3D object as a child of this 3D object, while maintaining the object's world
8247		 * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s).
8248		 *
8249		 * @fires Object3D#added
8250		 * @fires Object3D#childadded
8251		 * @param {Object3D} object - The 3D object to attach.
8252		 * @return {Object3D} A reference to this instance.
8253		 */ attach(object) {
8254	        // adds object as a child of this, while maintaining the object's world transform
8255	        // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)
8256	        this.updateWorldMatrix(true, false);
8257	        _m1$1$1.copy(this.matrixWorld).invert();
8258	        if (object.parent !== null) {
8259	            object.parent.updateWorldMatrix(true, false);
8260	            _m1$1$1.multiply(object.parent.matrixWorld);
8261	        }
8262	        object.applyMatrix4(_m1$1$1);
8263	        object.removeFromParent();
8264	        object.parent = this;
8265	        this.children.push(object);
8266	        object.updateWorldMatrix(false, true);
8267	        object.dispatchEvent(_addedEvent);
8268	        _childaddedEvent.child = object;
8269	        this.dispatchEvent(_childaddedEvent);
8270	        _childaddedEvent.child = null;
8271	        return this;
8272	    }
8273	    /**
8274		 * Searches through the 3D object and its children, starting with the 3D object
8275		 * itself, and returns the first with a matching ID.
8276		 *
8277		 * @param {number} id - The id.
8278		 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
8279		 */ getObjectById(id) {
8280	        return this.getObjectByProperty('id', id);
8281	    }
8282	    /**
8283		 * Searches through the 3D object and its children, starting with the 3D object
8284		 * itself, and returns the first with a matching name.
8285		 *
8286		 * @param {string} name - The name.
8287		 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
8288		 */ getObjectByName(name) {
8289	        return this.getObjectByProperty('name', name);
8290	    }
8291	    /**
8292		 * Searches through the 3D object and its children, starting with the 3D object
8293		 * itself, and returns the first with a matching property value.
8294		 *
8295		 * @param {string} name - The name of the property.
8296		 * @param {any} value - The value.
8297		 * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found.
8298		 */ getObjectByProperty(name, value) {
8299	        if (this[name] === value) return this;
8300	        for(let i = 0, l = this.children.length; i < l; i++){
8301	            const child = this.children[i];
8302	            const object = child.getObjectByProperty(name, value);
8303	            if (object !== undefined) {
8304	                return object;
8305	            }
8306	        }
8307	        return undefined;
8308	    }
8309	    /**
8310		 * Searches through the 3D object and its children, starting with the 3D object
8311		 * itself, and returns all 3D objects with a matching property value.
8312		 *
8313		 * @param {string} name - The name of the property.
8314		 * @param {any} value - The value.
8315		 * @param {Array<Object3D>} result - The method stores the result in this array.
vendor: 4,394 bytes, lines 8316-8422
8316		 * @return {Array<Object3D>} The found 3D objects.
8317		 */ getObjectsByProperty(name, value, result = []) {
8318	        if (this[name] === value) result.push(this);
8319	        const children = this.children;
8320	        for(let i = 0, l = children.length; i < l; i++){
8321	            children[i].getObjectsByProperty(name, value, result);
8322	        }
8323	        return result;
8324	    }
8325	    /**
8326		 * Returns a vector representing the position of the 3D object in world space.
8327		 *
8328		 * @param {Vector3} target - The target vector the result is stored to.
8329		 * @return {Vector3} The 3D object's position in world space.
8330		 */ getWorldPosition(target) {
8331	        this.updateWorldMatrix(true, false);
8332	        return target.setFromMatrixPosition(this.matrixWorld);
8333	    }
8334	    /**
8335		 * Returns a Quaternion representing the position of the 3D object in world space.
8336		 *
8337		 * @param {Quaternion} target - The target Quaternion the result is stored to.
8338		 * @return {Quaternion} The 3D object's rotation in world space.
8339		 */ getWorldQuaternion(target) {
8340	        this.updateWorldMatrix(true, false);
8341	        this.matrixWorld.decompose(_position$3, target, _scale$2);
8342	        return target;
8343	    }
8344	    /**
8345		 * Returns a vector representing the scale of the 3D object in world space.
8346		 *
8347		 * @param {Vector3} target - The target vector the result is stored to.
8348		 * @return {Vector3} The 3D object's scale in world space.
8349		 */ getWorldScale(target) {
8350	        this.updateWorldMatrix(true, false);
8351	        this.matrixWorld.decompose(_position$3, _quaternion$2, target);
8352	        return target;
8353	    }
8354	    /**
8355		 * Returns a vector representing the ("look") direction of the 3D object in world space.
8356		 *
8357		 * @param {Vector3} target - The target vector the result is stored to.
8358		 * @return {Vector3} The 3D object's direction in world space.
8359		 */ getWorldDirection(target) {
8360	        this.updateWorldMatrix(true, false);
8361	        const e = this.matrixWorld.elements;
8362	        return target.set(e[8], e[9], e[10]).normalize();
8363	    }
8364	    /**
8365		 * Abstract method to get intersections between a casted ray and this
8366		 * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points}
8367		 * implement this method in order to use raycasting.
8368		 *
8369		 * @abstract
8370		 * @param {Raycaster} raycaster - The raycaster.
8371		 * @param {Array<Object>} intersects - An array holding the result of the method.
8372		 */ raycast() {}
8373	    /**
8374		 * Executes the callback on this 3D object and all descendants.
8375		 *
8376		 * Note: Modifying the scene graph inside the callback is discouraged.
8377		 *
8378		 * @param {Function} callback - A callback function that allows to process the current 3D object.
8379		 */ traverse(callback) {
8380	        callback(this);
8381	        const children = this.children;
8382	        for(let i = 0, l = children.length; i < l; i++){
8383	            children[i].traverse(callback);
8384	        }
8385	    }
8386	    /**
8387		 * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects.
8388		 * Descendants of invisible 3D objects are not traversed.
8389		 *
8390		 * Note: Modifying the scene graph inside the callback is discouraged.
8391		 *
8392		 * @param {Function} callback - A callback function that allows to process the current 3D object.
8393		 */ traverseVisible(callback) {
8394	        if (this.visible === false) return;
8395	        callback(this);
8396	        const children = this.children;
8397	        for(let i = 0, l = children.length; i < l; i++){
8398	            children[i].traverseVisible(callback);
8399	        }
8400	    }
8401	    /**
8402		 * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors.
8403		 *
8404		 * Note: Modifying the scene graph inside the callback is discouraged.
8405		 *
8406		 * @param {Function} callback - A callback function that allows to process the current 3D object.
8407		 */ traverseAncestors(callback) {
8408	        const parent = this.parent;
8409	        if (parent !== null) {
8410	            callback(parent);
8411	            parent.traverseAncestors(callback);
8412	        }
8413	    }
8414	    /**
8415		 * Updates the transformation matrix in local space by computing it from the current
8416		 * position, rotation and scale values.
8417		 */ updateMatrix() {
8418	        this.matrix.compose(this.position, this.quaternion, this.scale);
8419	        this.matrixWorldNeedsUpdate = true;
8420	    }
8421	    /**
8422		 * Updates the transformation matrix in world space of this 3D objects and its desce
8422ndants.
8423		 *
8424		 * To ensure correct results, this method also recomputes the 3D object's transformation matrix in
8425		 * local space. The computation of the local and world matrix can be controlled with the
8426		 * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both
8427		 * `true` by default.  Set these flags to `false` if you need more control over the update matrix process.
8428		 *
8429		 * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even
8430		 * when {@link Object3D#matrixWorldAutoUpdate} is set to `false`.
8431		 */ updateMatrixWorld(force) {
8432	        if (this.matrixAutoUpdate) this.updateMatrix();
8433	        if (this.matrixWorldNeedsUpdate || force) {
8434	            if (this.matrixWorldAutoUpdate === true) {
8435	                if (this.parent === null) {
8436	                    this.matrixWorld.copy(this.matrix);
8437	                } else {
8438	                    this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
8439	                }
8440	            }
8441	            this.matrixWorldNeedsUpdate = false;
8442	            force = true;
8443	        }
8444	        // make sure descendants are updated if required
8445	        const children = this.children;
8446	        for(let i = 0, l = children.length; i < l; i++){
8447	            const child = children[i];
8448	            child.updateMatrixWorld(force);
8449	        }
8450	    }
8451	    /**
8452		 * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the
8453		 * update of ancestor and descendant nodes.
8454		 *
8455		 * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not.
8456		 * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not.
8457		 */ updateWorldMatrix(updateParents, updateChildren) {
8458	        const parent = this.parent;
8459	        if (updateParents === true && parent !== null) {
8460	            parent.updateWorldMatrix(true, false);
8461	        }
8462	        if (this.matrixAutoUpdate) this.updateMatrix();
8463	        if (this.matrixWorldAutoUpdate === true) {
8464	            if (this.parent === null) {
8465	                this.matrixWorld.copy(this.matrix);
8466	            } else {
8467	                this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
8468	            }
8469	        }
8470	        // make sure descendants are updated
8471	        if (updateChildren === true) {
8472	            const children = this.children;
8473	            for(let i = 0, l = children.length; i < l; i++){
8474	                const child = children[i];
8475	                child.updateWorldMatrix(false, true);
8476	            }
8477	        }
8478	    }
8479	    /**
8480		 * Serializes the 3D object into JSON.
8481		 *
8482		 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
8483		 * @return {Object} A JSON object representing the serialized 3D object.
8484		 * @see {@link ObjectLoader#parse}
8485		 */ toJSON(meta) {
8486	        // meta is a string when called from JSON.stringify
8487	        const isRootObject = meta === undefined || typeof meta === 'string';
8488	        const output = {};
8489	        // meta is a hash used to collect geometries, materials.
8490	        // not providing it implies that this is the root object
8491	        // being serialized.
8492	        if (isRootObject) {
8493	            // initialize meta obj
8494	            meta = {
8495	                geometries: {},
8496	                materials: {},
8497	                textures: {},
8498	                images: {},
8499	                shapes: {},
8500	                skeletons: {},
8501	                animations: {},
8502	                nodes: {}
8503	            };
8504	            output.metadata = {
8505	                version: 4.6,
8506	                type: 'Object',
8507	                generator: 'Object3D.toJSON'
8508	            };
8509	        }
8510	        // standard Object3D serialization
8511	        const object = {};
8512	        object.uuid = this.uuid;
8513	        object.type = this.type;
8514	        if (this.name !== '') object.name = this.name;
8515	        if (this.castShadow === true) object.castShadow = true;
8516	        if (this.receiveShadow === true) object.receiveShadow = true;
8517	        if (this.visible === false) object.visible = false;
vendor: 4,179 bytes, lines 8518-8602
8518	        if (this.frustumCulled === false) object.frustumCulled = false;
8519	        if (this.renderOrder !== 0) object.renderOrder = this.renderOrder;
8520	        if (Object.keys(this.userData).length > 0) object.userData = this.userData;
8521	        object.layers = this.layers.mask;
8522	        object.matrix = this.matrix.toArray();
8523	        object.up = this.up.toArray();
8524	        if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false;
8525	        // object specific properties
8526	        if (this.isInstancedMesh) {
8527	            object.type = 'InstancedMesh';
8528	            object.count = this.count;
8529	            object.instanceMatrix = this.instanceMatrix.toJSON();
8530	            if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON();
8531	        }
8532	        if (this.isBatchedMesh) {
8533	            object.type = 'BatchedMesh';
8534	            object.perObjectFrustumCulled = this.perObjectFrustumCulled;
8535	            object.sortObjects = this.sortObjects;
8536	            object.drawRanges = this._drawRanges;
8537	            object.reservedRanges = this._reservedRanges;
8538	            object.visibility = this._visibility;
8539	            object.active = this._active;
8540	            object.bounds = this._bounds.map((bound)=>({
8541	                    boxInitialized: bound.boxInitialized,
8542	                    boxMin: bound.box.min.toArray(),
8543	                    boxMax: bound.box.max.toArray(),
8544	                    sphereInitialized: bound.sphereInitialized,
8545	                    sphereRadius: bound.sphere.radius,
8546	                    sphereCenter: bound.sphere.center.toArray()
8547	                }));
8548	            object.maxInstanceCount = this._maxInstanceCount;
8549	            object.maxVertexCount = this._maxVertexCount;
8550	            object.maxIndexCount = this._maxIndexCount;
8551	            object.geometryInitialized = this._geometryInitialized;
8552	            object.geometryCount = this._geometryCount;
8553	            object.matricesTexture = this._matricesTexture.toJSON(meta);
8554	            if (this._colorsTexture !== null) object.colorsTexture = this._colorsTexture.toJSON(meta);
8555	            if (this.boundingSphere !== null) {
8556	                object.boundingSphere = {
8557	                    center: object.boundingSphere.center.toArray(),
8558	                    radius: object.boundingSphere.radius
8559	                };
8560	            }
8561	            if (this.boundingBox !== null) {
8562	                object.boundingBox = {
8563	                    min: object.boundingBox.min.toArray(),
8564	                    max: object.boundingBox.max.toArray()
8565	                };
8566	            }
8567	        }
8568	        //
8569	        function serialize(library, element) {
8570	            if (library[element.uuid] === undefined) {
8571	                library[element.uuid] = element.toJSON(meta);
8572	            }
8573	            return element.uuid;
8574	        }
8575	        if (this.isScene) {
8576	            if (this.background) {
8577	                if (this.background.isColor) {
8578	                    object.background = this.background.toJSON();
8579	                } else if (this.background.isTexture) {
8580	                    object.background = this.background.toJSON(meta).uuid;
8581	                }
8582	            }
8583	            if (this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true) {
8584	                object.environment = this.environment.toJSON(meta).uuid;
8585	            }
8586	        } else if (this.isMesh || this.isLine || this.isPoints) {
8587	            object.geometry = serialize(meta.geometries, this.geometry);
8588	            const parameters = this.geometry.parameters;
8589	            if (parameters !== undefined && parameters.shapes !== undefined) {
8590	                const shapes = parameters.shapes;
8591	                if (Array.isArray(shapes)) {
8592	                    for(let i = 0, l = shapes.length; i < l; i++){
8593	                        const shape = shapes[i];
8594	                        serialize(meta.shapes, shape);
8595	                    }
8596	                } else {
8597	                    serialize(meta.shapes, shapes);
8598	                }
8599	            }
8600	        }
8601	        if (this.isSkinnedMesh) {
8602	            object.bindMode = this.bindMode;
vendor: 9,652 bytes, lines 8603-8875
8603	            object.bindMatrix = this.bindMatrix.toArray();
8604	            if (this.skeleton !== undefined) {
8605	                serialize(meta.skeletons, this.skeleton);
8606	                object.skeleton = this.skeleton.uuid;
8607	            }
8608	        }
8609	        if (this.material !== undefined) {
8610	            if (Array.isArray(this.material)) {
8611	                const uuids = [];
8612	                for(let i = 0, l = this.material.length; i < l; i++){
8613	                    uuids.push(serialize(meta.materials, this.material[i]));
8614	                }
8615	                object.material = uuids;
8616	            } else {
8617	                object.material = serialize(meta.materials, this.material);
8618	            }
8619	        }
8620	        //
8621	        if (this.children.length > 0) {
8622	            object.children = [];
8623	            for(let i = 0; i < this.children.length; i++){
8624	                object.children.push(this.children[i].toJSON(meta).object);
8625	            }
8626	        }
8627	        //
8628	        if (this.animations.length > 0) {
8629	            object.animations = [];
8630	            for(let i = 0; i < this.animations.length; i++){
8631	                const animation = this.animations[i];
8632	                object.animations.push(serialize(meta.animations, animation));
8633	            }
8634	        }
8635	        if (isRootObject) {
8636	            const geometries = extractFromCache(meta.geometries);
8637	            const materials = extractFromCache(meta.materials);
8638	            const textures = extractFromCache(meta.textures);
8639	            const images = extractFromCache(meta.images);
8640	            const shapes = extractFromCache(meta.shapes);
8641	            const skeletons = extractFromCache(meta.skeletons);
8642	            const animations = extractFromCache(meta.animations);
8643	            const nodes = extractFromCache(meta.nodes);
8644	            if (geometries.length > 0) output.geometries = geometries;
8645	            if (materials.length > 0) output.materials = materials;
8646	            if (textures.length > 0) output.textures = textures;
8647	            if (images.length > 0) output.images = images;
8648	            if (shapes.length > 0) output.shapes = shapes;
8649	            if (skeletons.length > 0) output.skeletons = skeletons;
8650	            if (animations.length > 0) output.animations = animations;
8651	            if (nodes.length > 0) output.nodes = nodes;
8652	        }
8653	        output.object = object;
8654	        return output;
8655	        // extract data from the cache hash
8656	        // remove metadata on each item
8657	        // and return as array
8658	        function extractFromCache(cache) {
8659	            const values = [];
8660	            for(const key in cache){
8661	                const data = cache[key];
8662	                delete data.metadata;
8663	                values.push(data);
8664	            }
8665	            return values;
8666	        }
8667	    }
8668	    /**
8669		 * Returns a new 3D object with copied values from this instance.
8670		 *
8671		 * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned.
8672		 * @return {Object3D} A clone of this instance.
8673		 */ clone(recursive) {
8674	        return new this.constructor().copy(this, recursive);
8675	    }
8676	    /**
8677		 * Copies the values of the given 3D object to this instance.
8678		 *
8679		 * @param {Object3D} source - The 3D object to copy.
8680		 * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned.
8681		 * @return {Object3D} A reference to this instance.
8682		 */ copy(source, recursive = true) {
8683	        this.name = source.name;
8684	        this.up.copy(source.up);
8685	        this.position.copy(source.position);
8686	        this.rotation.order = source.rotation.order;
8687	        this.quaternion.copy(source.quaternion);
8688	        this.scale.copy(source.scale);
8689	        this.matrix.copy(source.matrix);
8690	        this.matrixWorld.copy(source.matrixWorld);
8691	        this.matrixAutoUpdate = source.matrixAutoUpdate;
8692	        this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate;
8693	        this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
8694	        this.layers.mask = source.layers.mask;
8695	        this.visible = source.visible;
8696	        this.castShadow = source.castShadow;
8697	        this.receiveShadow = source.receiveShadow;
8698	        this.frustumCulled = source.frustumCulled;
8699	        this.renderOrder = source.renderOrder;
8700	        this.animations = source.animations.slice();
8701	        this.userData = JSON.parse(JSON.stringify(source.userData));
8702	        if (recursive === true) {
8703	            for(let i = 0; i < source.children.length; i++){
8704	                const child = source.children[i];
8705	                this.add(child.clone());
8706	            }
8707	        }
8708	        return this;
8709	    }
8710	    /**
8711		 * Constructs a new 3D object.
8712		 */ constructor(){
8713	        super();
8714	        /**
8715			 * This flag can be used for type testing.
8716			 *
8717			 * @type {boolean}
8718			 * @readonly
8719			 * @default true
8720			 */ this.isObject3D = true;
8721	        /**
8722			 * The ID of the 3D object.
8723			 *
8724			 * @name Object3D#id
8725			 * @type {number}
8726			 * @readonly
8727			 */ Object.defineProperty(this, 'id', {
8728	            value: _object3DId++
8729	        });
8730	        /**
8731			 * The UUID of the 3D object.
8732			 *
8733			 * @type {string}
8734			 * @readonly
8735			 */ this.uuid = generateUUID();
8736	        /**
8737			 * The name of the 3D object.
8738			 *
8739			 * @type {string}
8740			 */ this.name = '';
8741	        /**
8742			 * The type property is used for detecting the object type
8743			 * in context of serialization/deserialization.
8744			 *
8745			 * @type {string}
8746			 * @readonly
8747			 */ this.type = 'Object3D';
8748	        /**
8749			 * A reference to the parent object.
8750			 *
8751			 * @type {?Object3D}
8752			 * @default null
8753			 */ this.parent = null;
8754	        /**
8755			 * An array holding the child 3D objects of this instance.
8756			 *
8757			 * @type {Array<Object3D>}
8758			 */ this.children = [];
8759	        /**
8760			 * Defines the `up` direction of the 3D object which influences
8761			 * the orientation via methods like {@link Object3D#lookAt}.
8762			 *
8763			 * The default values for all 3D objects is defined by `Object3D.DEFAULT_UP`.
8764			 *
8765			 * @type {Vector3}
8766			 */ this.up = Object3D.DEFAULT_UP.clone();
8767	        const position = new Vector3();
8768	        const rotation = new Euler();
8769	        const quaternion = new Quaternion();
8770	        const scale = new Vector3(1, 1, 1);
8771	        function onRotationChange() {
8772	            quaternion.setFromEuler(rotation, false);
8773	        }
8774	        function onQuaternionChange() {
8775	            rotation.setFromQuaternion(quaternion, undefined, false);
8776	        }
8777	        rotation._onChange(onRotationChange);
8778	        quaternion._onChange(onQuaternionChange);
8779	        Object.defineProperties(this, {
8780	            /**
8781				 * Represents the object's local position.
8782				 *
8783				 * @name Object3D#position
8784				 * @type {Vector3}
8785				 * @default (0,0,0)
8786				 */ position: {
8787	                configurable: true,
8788	                enumerable: true,
8789	                value: position
8790	            },
8791	            /**
8792				 * Represents the object's local rotation as Euler angles, in radians.
8793				 *
8794				 * @name Object3D#rotation
8795				 * @type {Euler}
8796				 * @default (0,0,0)
8797				 */ rotation: {
8798	                configurable: true,
8799	                enumerable: true,
8800	                value: rotation
8801	            },
8802	            /**
8803				 * Represents the object's local rotation as Quaternions.
8804				 *
8805				 * @name Object3D#quaternion
8806				 * @type {Quaternion}
8807				 */ quaternion: {
8808	                configurable: true,
8809	                enumerable: true,
8810	                value: quaternion
8811	            },
8812	            /**
8813				 * Represents the object's local scale.
8814				 *
8815				 * @name Object3D#scale
8816				 * @type {Vector3}
8817				 * @default (1,1,1)
8818				 */ scale: {
8819	                configurable: true,
8820	                enumerable: true,
8821	                value: scale
8822	            },
8823	            /**
8824				 * Represents the object's model-view matrix.
8825				 *
8826				 * @name Object3D#modelViewMatrix
8827				 * @type {Matrix4}
8828				 */ modelViewMatrix: {
8829	                value: new Matrix4()
8830	            },
8831	            /**
8832				 * Represents the object's normal matrix.
8833				 *
8834				 * @name Object3D#normalMatrix
8835				 * @type {Matrix3}
8836				 */ normalMatrix: {
8837	                value: new Matrix3()
8838	            }
8839	        });
8840	        /**
8841			 * Represents the object's transformation matrix in local space.
8842			 *
8843			 * @type {Matrix4}
8844			 */ this.matrix = new Matrix4();
8845	        /**
8846			 * Represents the object's transformation matrix in world space.
8847			 * If the 3D object has no parent, then it's identical to the local transformation matrix
8848			 *
8849			 * @type {Matrix4}
8850			 */ this.matrixWorld = new Matrix4();
8851	        /**
8852			 * When set to `true`, the engine automatically computes the local matrix from position,
8853			 * rotation and scale every frame.
8854			 *
8855			 * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_AUTO_UPDATE`.
8856			 *
8857			 * @type {boolean}
8858			 * @default true
8859			 */ this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE;
8860	        /**
8861			 * When set to `true`, the engine automatically computes the world matrix from the current local
8862			 * matrix and the object's transformation hierarchy.
8863			 *
8864			 * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE`.
8865			 *
8866			 * @type {boolean}
8867			 * @default true
8868			 */ this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer
8869	        /**
8870			 * When set to `true`, it calculates the world matrix in that frame and resets this property
8871			 * to `false`.
8872			 *
8873			 * @type {boolean}
8874			 * @default false
8875			 */ this.matrixWorldNeedsUpdate = false;
8876	        /**
8877			 * The layer membership of the 3D object. The 3D object is only visible if it has
8878			 * at least one layer in common with the camera in use. This property can also be
8879			 * used to filter out unwanted objects in ray-intersection tests when using {@link Raycaster}.
8880			 *
8881			 * @type {Layers}
8882			 */ this.layers = new Layers();
8883	        /**
8884			 * When set to `true`, the 3D object gets rendered.
8885			 *
8886			 * @type {boolean}
8887			 * @default true
8888			 */ this.visible = true;
8889	        /**
8890			 * When set to `true`, the 3D object gets rendered into shadow maps.
8891			 *
8892			 * @type {boolean}
8893			 * @default false
8894			 */ this.castShadow = false;
8895	        /**
8896			 * When set to `true`, the 3D object is affected by shadows in the scene.
8897			 *
8898			 * @type {boolean}
8899			 * @default false
8900			 */ this.receiveShadow = false;
8901	        /**
8902			 * When set to `true`, the 3D object is honored by view frustum culling.
8903			 *
8904			 * @type {boolean}
8905			 * @default true
8906			 */ this.frustumCulled = true;
8907	        /**
8908			 * This value allows the default rendering order of scene graph objects to be
8909			 * overridden although opaque and transparent objects remain sorted independently.
8910			 * When this property is set for an instance of {@link Group},all descendants
8911			 * objects will be sorted and rendered together. Sorting is from lowest to highest
8912			 * render order.
8913			 *
8914			 * @type {number}
8915			 * @default 0
8916			 */ this.renderOrder = 0;
8917	        /**
8918			 * An array holding the animation clips of the 3D object.
8919			 *
8920			 * @type {Array<AnimationClip>}
8921			 */ this.animations = [];
8922	        /**
8923			 * An object that can be used to store custom data about the 3D object. It
8924			 * should not hold references to functions as these will not be cloned.
8925			 *
8926			 * @type {Object}
8927			 */ this.userData = {};
8928	    }
8929	}
8930	/**
8931	 * The default up direction for objects, also used as the default
8932	 * position for {@link DirectionalLight} and {@link HemisphereLight}.
8933	 *
8934	 * @static
8935	 * @type {Vector3}
8936	 * @default (0,1,0)
8937	 */ Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3(0, 1, 0);
8938	/**
8939	 * The default setting for {@link Object3D#matrixAutoUpdate} for
8940	 * newly created 3D objects.
8941	 *
8942	 * @static
8943	 * @type {boolean}
8944	 * @default true
8945	 */ Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true;
8946	/**
8947	 * The default setting for {@link Object3D#matrixWorldAutoUpdate} for
8948	 * newly created 3D objects.
8949	 *
8950	 * @static
8951	 * @type {boolean}
8952	 * @default true
8953	 */ Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true;
8954	const _v0$1 = /*@__PURE__*/ new Vector3();
8955	const _v1$3 = /*@__PURE__*/ new Vector3();
8956	const _v2$2 = /*@__PURE__*/ new Vector3();
8957	const _v3$2 = /*@__PURE__*/ new Vector3();
8958	const _vab = /*@__PURE__*/ new Vector3();
8959	const _vac = /*@__PURE__*/ new Vector3();
8960	const _vbc = /*@__PURE__*/ new Vector3();
8961	const _vap = /*@__PURE__*/ new Vector3();
8962	const _vbp = /*@__PURE__*/ new Vector3();
8963	const _vcp = /*@__PURE__*/ new Vector3();
8964	const _v40 = /*@__PURE__*/ new Vector4();
8965	const _v41 = /*@__PURE__*/ new Vector4();
8966	const _v42 = /*@__PURE__*/ new Vector4();
8967	/**
8968	 * A geometric triangle as defined by three vectors representing its three corners.
8969	 */ class Triangle {
8970	    /**
8971		 * Computes the normal vector of a triangle.
8972		 *
8973		 * @param {Vector3} a - The first corner of the triangle.
8974		 * @param {Vector3} b - The second corner of the triangle.
8975		 * @param {Vector3} c - The third corner of the triangle.
8976		 * @param {Vector3} target - The target vector that is used to store the method's result.
8977		 * @return {Vector3} The triangle's normal.
8978		 */ static getNormal(a, b, c, target) {
8979	        target.subVectors(c, b);
8980	        _v0$1.subVectors(a, b);
8981	        target.cross(_v0$1);
8982	        const targetLengthSq = target.lengthSq();
8983	        if (targetLengthSq > 0) {
8984	            return target.multiplyScalar(1 / Math.sqrt(targetLengthSq));
8985	        }
8986	        return target.set(0, 0, 0);
8987	    }
8988	    /**
8989		 * Computes a barycentric coordinates from the given vector.
8990		 * Returns `null` if the triangle is degenerate.
8991		 *
8992		 * @param {Vector3} point - A point in 3D space.
8993		 * @param {Vector3} a - The first corner of the triangle.
8994		 * @param {Vector3} b - The second corner of the triangle.
8995		 * @param {Vector3} c - The third corner of the triangle.
8996		 * @param {Vector3} target - The target vector that is used to store the method's result.
8997		 * @return {?Vector3} The barycentric coordinates for the given point
8998		 */ static getBarycoord(point, a, b, c, target) {
8999	        // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
9000	        _v0$1.subVectors(c, a);
9001	        _v1$3.subVectors(b, a);
9002	        _v2$2.subVectors(point, a);
vendor: 4,454 bytes, lines 9003-9099
9003	        const dot00 = _v0$1.dot(_v0$1);
9004	        const dot01 = _v0$1.dot(_v1$3);
9005	        const dot02 = _v0$1.dot(_v2$2);
9006	        const dot11 = _v1$3.dot(_v1$3);
9007	        const dot12 = _v1$3.dot(_v2$2);
9008	        const denom = dot00 * dot11 - dot01 * dot01;
9009	        // collinear or singular triangle
9010	        if (denom === 0) {
9011	            target.set(0, 0, 0);
9012	            return null;
9013	        }
9014	        const invDenom = 1 / denom;
9015	        const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
9016	        const v = (dot00 * dot12 - dot01 * dot02) * invDenom;
9017	        // barycentric coordinates must always sum to 1
9018	        return target.set(1 - u - v, v, u);
9019	    }
9020	    /**
9021		 * Returns `true` if the given point, when projected onto the plane of the
9022		 * triangle, lies within the triangle.
9023		 *
9024		 * @param {Vector3} point - The point in 3D space to test.
9025		 * @param {Vector3} a - The first corner of the triangle.
9026		 * @param {Vector3} b - The second corner of the triangle.
9027		 * @param {Vector3} c - The third corner of the triangle.
9028		 * @return {boolean} Whether the given point, when projected onto the plane of the
9029		 * triangle, lies within the triangle or not.
9030		 */ static containsPoint(point, a, b, c) {
9031	        // if the triangle is degenerate then we can't contain a point
9032	        if (this.getBarycoord(point, a, b, c, _v3$2) === null) {
9033	            return false;
9034	        }
9035	        return _v3$2.x >= 0 && _v3$2.y >= 0 && _v3$2.x + _v3$2.y <= 1;
9036	    }
9037	    /**
9038		 * Computes the value barycentrically interpolated for the given point on the
9039		 * triangle. Returns `null` if the triangle is degenerate.
9040		 *
9041		 * @param {Vector3} point - Position of interpolated point.
9042		 * @param {Vector3} p1 - The first corner of the triangle.
9043		 * @param {Vector3} p2 - The second corner of the triangle.
9044		 * @param {Vector3} p3 - The third corner of the triangle.
9045		 * @param {Vector3} v1 - Value to interpolate of first vertex.
9046		 * @param {Vector3} v2 - Value to interpolate of second vertex.
9047		 * @param {Vector3} v3 - Value to interpolate of third vertex.
9048		 * @param {Vector3} target - The target vector that is used to store the method's result.
9049		 * @return {?Vector3} The interpolated value.
9050		 */ static getInterpolation(point, p1, p2, p3, v1, v2, v3, target) {
9051	        if (this.getBarycoord(point, p1, p2, p3, _v3$2) === null) {
9052	            target.x = 0;
9053	            target.y = 0;
9054	            if ('z' in target) target.z = 0;
9055	            if ('w' in target) target.w = 0;
9056	            return null;
9057	        }
9058	        target.setScalar(0);
9059	        target.addScaledVector(v1, _v3$2.x);
9060	        target.addScaledVector(v2, _v3$2.y);
9061	        target.addScaledVector(v3, _v3$2.z);
9062	        return target;
9063	    }
9064	    /**
9065		 * Computes the value barycentrically interpolated for the given attribute and indices.
9066		 *
9067		 * @param {BufferAttribute} attr - The attribute to interpolate.
9068		 * @param {number} i1 - Index of first vertex.
9069		 * @param {number} i2 - Index of second vertex.
9070		 * @param {number} i3 - Index of third vertex.
9071		 * @param {Vector3} barycoord - The barycoordinate value to use to interpolate.
9072		 * @param {Vector3} target - The target vector that is used to store the method's result.
9073		 * @return {Vector3} The interpolated attribute value.
9074		 */ static getInterpolatedAttribute(attr, i1, i2, i3, barycoord, target) {
9075	        _v40.setScalar(0);
9076	        _v41.setScalar(0);
9077	        _v42.setScalar(0);
9078	        _v40.fromBufferAttribute(attr, i1);
9079	        _v41.fromBufferAttribute(attr, i2);
9080	        _v42.fromBufferAttribute(attr, i3);
9081	        target.setScalar(0);
9082	        target.addScaledVector(_v40, barycoord.x);
9083	        target.addScaledVector(_v41, barycoord.y);
9084	        target.addScaledVector(_v42, barycoord.z);
9085	        return target;
9086	    }
9087	    /**
9088		 * Returns `true` if the triangle is oriented towards the given direction.
9089		 *
9090		 * @param {Vector3} a - The first corner of the triangle.
9091		 * @param {Vector3} b - The second corner of the triangle.
9092		 * @param {Vector3} c - The third corner of the triangle.
9093		 * @param {Vector3} direction - The (normalized) direction vector.
9094		 * @return {boolean} Whether the triangle is oriented towards the given direction or not.
9095		 */ static isFrontFacing(a, b, c, direction) {
9096	        _v0$1.subVectors(c, b);
9097	        _v1$3.subVectors(a, b);
9098	        // strictly front facing
9099	        return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false;
vendor: 6,559 bytes, lines 9100-9254
9100	    }
9101	    /**
9102		 * Sets the triangle's vertices by copying the given values.
9103		 *
9104		 * @param {Vector3} a - The first corner of the triangle.
9105		 * @param {Vector3} b - The second corner of the triangle.
9106		 * @param {Vector3} c - The third corner of the triangle.
9107		 * @return {Triangle} A reference to this triangle.
9108		 */ set(a, b, c) {
9109	        this.a.copy(a);
9110	        this.b.copy(b);
9111	        this.c.copy(c);
9112	        return this;
9113	    }
9114	    /**
9115		 * Sets the triangle's vertices by copying the given array values.
9116		 *
9117		 * @param {Array<Vector3>} points - An array with 3D points.
9118		 * @param {number} i0 - The array index representing the first corner of the triangle.
9119		 * @param {number} i1 - The array index representing the second corner of the triangle.
9120		 * @param {number} i2 - The array index representing the third corner of the triangle.
9121		 * @return {Triangle} A reference to this triangle.
9122		 */ setFromPointsAndIndices(points, i0, i1, i2) {
9123	        this.a.copy(points[i0]);
9124	        this.b.copy(points[i1]);
9125	        this.c.copy(points[i2]);
9126	        return this;
9127	    }
9128	    /**
9129		 * Sets the triangle's vertices by copying the given attribute values.
9130		 *
9131		 * @param {BufferAttribute} attribute - A buffer attribute with 3D points data.
9132		 * @param {number} i0 - The attribute index representing the first corner of the triangle.
9133		 * @param {number} i1 - The attribute index representing the second corner of the triangle.
9134		 * @param {number} i2 - The attribute index representing the third corner of the triangle.
9135		 * @return {Triangle} A reference to this triangle.
9136		 */ setFromAttributeAndIndices(attribute, i0, i1, i2) {
9137	        this.a.fromBufferAttribute(attribute, i0);
9138	        this.b.fromBufferAttribute(attribute, i1);
9139	        this.c.fromBufferAttribute(attribute, i2);
9140	        return this;
9141	    }
9142	    /**
9143		 * Returns a new triangle with copied values from this instance.
9144		 *
9145		 * @return {Triangle} A clone of this instance.
9146		 */ clone() {
9147	        return new this.constructor().copy(this);
9148	    }
9149	    /**
9150		 * Copies the values of the given triangle to this instance.
9151		 *
9152		 * @param {Triangle} triangle - The triangle to copy.
9153		 * @return {Triangle} A reference to this triangle.
9154		 */ copy(triangle) {
9155	        this.a.copy(triangle.a);
9156	        this.b.copy(triangle.b);
9157	        this.c.copy(triangle.c);
9158	        return this;
9159	    }
9160	    /**
9161		 * Computes the area of the triangle.
9162		 *
9163		 * @return {number} The triangle's area.
9164		 */ getArea() {
9165	        _v0$1.subVectors(this.c, this.b);
9166	        _v1$3.subVectors(this.a, this.b);
9167	        return _v0$1.cross(_v1$3).length() * 0.5;
9168	    }
9169	    /**
9170		 * Computes the midpoint of the triangle.
9171		 *
9172		 * @param {Vector3} target - The target vector that is used to store the method's result.
9173		 * @return {Vector3} The triangle's midpoint.
9174		 */ getMidpoint(target) {
9175	        return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3);
9176	    }
9177	    /**
9178		 * Computes the normal of the triangle.
9179		 *
9180		 * @param {Vector3} target - The target vector that is used to store the method's result.
9181		 * @return {Vector3} The triangle's normal.
9182		 */ getNormal(target) {
9183	        return Triangle.getNormal(this.a, this.b, this.c, target);
9184	    }
9185	    /**
9186		 * Computes a plane the triangle lies within.
9187		 *
9188		 * @param {Plane} target - The target vector that is used to store the method's result.
9189		 * @return {Plane} The plane the triangle lies within.
9190		 */ getPlane(target) {
9191	        return target.setFromCoplanarPoints(this.a, this.b, this.c);
9192	    }
9193	    /**
9194		 * Computes a barycentric coordinates from the given vector.
9195		 * Returns `null` if the triangle is degenerate.
9196		 *
9197		 * @param {Vector3} point - A point in 3D space.
9198		 * @param {Vector3} target - The target vector that is used to store the method's result.
9199		 * @return {?Vector3} The barycentric coordinates for the given point
9200		 */ getBarycoord(point, target) {
9201	        return Triangle.getBarycoord(point, this.a, this.b, this.c, target);
9202	    }
9203	    /**
9204		 * Computes the value barycentrically interpolated for the given point on the
9205		 * triangle. Returns `null` if the triangle is degenerate.
9206		 *
9207		 * @param {Vector3} point - Position of interpolated point.
9208		 * @param {Vector3} v1 - Value to interpolate of first vertex.
9209		 * @param {Vector3} v2 - Value to interpolate of second vertex.
9210		 * @param {Vector3} v3 - Value to interpolate of third vertex.
9211		 * @param {Vector3} target - The target vector that is used to store the method's result.
9212		 * @return {?Vector3} The interpolated value.
9213		 */ getInterpolation(point, v1, v2, v3, target) {
9214	        return Triangle.getInterpolation(point, this.a, this.b, this.c, v1, v2, v3, target);
9215	    }
9216	    /**
9217		 * Returns `true` if the given point, when projected onto the plane of the
9218		 * triangle, lies within the triangle.
9219		 *
9220		 * @param {Vector3} point - The point in 3D space to test.
9221		 * @return {boolean} Whether the given point, when projected onto the plane of the
9222		 * triangle, lies within the triangle or not.
9223		 */ containsPoint(point) {
9224	        return Triangle.containsPoint(point, this.a, this.b, this.c);
9225	    }
9226	    /**
9227		 * Returns `true` if the triangle is oriented towards the given direction.
9228		 *
9229		 * @param {Vector3} direction - The (normalized) direction vector.
9230		 * @return {boolean} Whether the triangle is oriented towards the given direction or not.
9231		 */ isFrontFacing(direction) {
9232	        return Triangle.isFrontFacing(this.a, this.b, this.c, direction);
9233	    }
9234	    /**
9235		 * Returns `true` if this triangle intersects with the given box.
9236		 *
9237		 * @param {Box3} box - The box to intersect.
9238		 * @return {boolean} Whether this triangle intersects with the given box or not.
9239		 */ intersectsBox(box) {
9240	        return box.intersectsTriangle(this);
9241	    }
9242	    /**
9243		 * Returns the closest point on the triangle to the given point.
9244		 *
9245		 * @param {Vector3} p - The point to compute the closest point for.
9246		 * @param {Vector3} target - The target vector that is used to store the method's result.
9247		 * @return {Vector3} The closest point on the triangle.
9248		 */ closestPointToPoint(p, target) {
9249	        const a = this.a, b = this.b, c = this.c;
9250	        let v, w;
9251	        // algorithm thanks to Real-Time Collision Detection by Christer Ericson,
9252	        // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
9253	        // under the accompanying license; see chapter 5.1.5 for detailed explanation.
9254	        // basically, we're distinguishing which of the voronoi regi
vendor: 6,478 bytes, lines 9254-9459
9254ons of the triangle
9255	        // the point lies in with the minimum amount of redundant computation.
9256	        _vab.subVectors(b, a);
9257	        _vac.subVectors(c, a);
9258	        _vap.subVectors(p, a);
9259	        const d1 = _vab.dot(_vap);
9260	        const d2 = _vac.dot(_vap);
9261	        if (d1 <= 0 && d2 <= 0) {
9262	            // vertex region of A; barycentric coords (1, 0, 0)
9263	            return target.copy(a);
9264	        }
9265	        _vbp.subVectors(p, b);
9266	        const d3 = _vab.dot(_vbp);
9267	        const d4 = _vac.dot(_vbp);
9268	        if (d3 >= 0 && d4 <= d3) {
9269	            // vertex region of B; barycentric coords (0, 1, 0)
9270	            return target.copy(b);
9271	        }
9272	        const vc = d1 * d4 - d3 * d2;
9273	        if (vc <= 0 && d1 >= 0 && d3 <= 0) {
9274	            v = d1 / (d1 - d3);
9275	            // edge region of AB; barycentric coords (1-v, v, 0)
9276	            return target.copy(a).addScaledVector(_vab, v);
9277	        }
9278	        _vcp.subVectors(p, c);
9279	        const d5 = _vab.dot(_vcp);
9280	        const d6 = _vac.dot(_vcp);
9281	        if (d6 >= 0 && d5 <= d6) {
9282	            // vertex region of C; barycentric coords (0, 0, 1)
9283	            return target.copy(c);
9284	        }
9285	        const vb = d5 * d2 - d1 * d6;
9286	        if (vb <= 0 && d2 >= 0 && d6 <= 0) {
9287	            w = d2 / (d2 - d6);
9288	            // edge region of AC; barycentric coords (1-w, 0, w)
9289	            return target.copy(a).addScaledVector(_vac, w);
9290	        }
9291	        const va = d3 * d6 - d5 * d4;
9292	        if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) {
9293	            _vbc.subVectors(c, b);
9294	            w = (d4 - d3) / (d4 - d3 + (d5 - d6));
9295	            // edge region of BC; barycentric coords (0, 1-w, w)
9296	            return target.copy(b).addScaledVector(_vbc, w); // edge region of BC
9297	        }
9298	        // face region
9299	        const denom = 1 / (va + vb + vc);
9300	        // u = va * denom
9301	        v = vb * denom;
9302	        w = vc * denom;
9303	        return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w);
9304	    }
9305	    /**
9306		 * Returns `true` if this triangle is equal with the given one.
9307		 *
9308		 * @param {Triangle} triangle - The triangle to test for equality.
9309		 * @return {boolean} Whether this triangle is equal with the given one.
9310		 */ equals(triangle) {
9311	        return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c);
9312	    }
9313	    /**
9314		 * Constructs a new triangle.
9315		 *
9316		 * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle.
9317		 * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle.
9318		 * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle.
9319		 */ constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()){
9320	        /**
9321			 * The first corner of the triangle.
9322			 *
9323			 * @type {Vector3}
9324			 */ this.a = a;
9325	        /**
9326			 * The second corner of the triangle.
9327			 *
9328			 * @type {Vector3}
9329			 */ this.b = b;
9330	        /**
9331			 * The third corner of the triangle.
9332			 *
9333			 * @type {Vector3}
9334			 */ this.c = c;
9335	    }
9336	}
9337	const _colorKeywords = {
9338	    'aliceblue': 0xF0F8FF,
9339	    'antiquewhite': 0xFAEBD7,
9340	    'aqua': 0x00FFFF,
9341	    'aquamarine': 0x7FFFD4,
9342	    'azure': 0xF0FFFF,
9343	    'beige': 0xF5F5DC,
9344	    'bisque': 0xFFE4C4,
9345	    'black': 0x000000,
9346	    'blanchedalmond': 0xFFEBCD,
9347	    'blue': 0x0000FF,
9348	    'blueviolet': 0x8A2BE2,
9349	    'brown': 0xA52A2A,
9350	    'burlywood': 0xDEB887,
9351	    'cadetblue': 0x5F9EA0,
9352	    'chartreuse': 0x7FFF00,
9353	    'chocolate': 0xD2691E,
9354	    'coral': 0xFF7F50,
9355	    'cornflowerblue': 0x6495ED,
9356	    'cornsilk': 0xFFF8DC,
9357	    'crimson': 0xDC143C,
9358	    'cyan': 0x00FFFF,
9359	    'darkblue': 0x00008B,
9360	    'darkcyan': 0x008B8B,
9361	    'darkgoldenrod': 0xB8860B,
9362	    'darkgray': 0xA9A9A9,
9363	    'darkgreen': 0x006400,
9364	    'darkgrey': 0xA9A9A9,
9365	    'darkkhaki': 0xBDB76B,
9366	    'darkmagenta': 0x8B008B,
9367	    'darkolivegreen': 0x556B2F,
9368	    'darkorange': 0xFF8C00,
9369	    'darkorchid': 0x9932CC,
9370	    'darkred': 0x8B0000,
9371	    'darksalmon': 0xE9967A,
9372	    'darkseagreen': 0x8FBC8F,
9373	    'darkslateblue': 0x483D8B,
9374	    'darkslategray': 0x2F4F4F,
9375	    'darkslategrey': 0x2F4F4F,
9376	    'darkturquoise': 0x00CED1,
9377	    'darkviolet': 0x9400D3,
9378	    'deeppink': 0xFF1493,
9379	    'deepskyblue': 0x00BFFF,
9380	    'dimgray': 0x696969,
9381	    'dimgrey': 0x696969,
9382	    'dodgerblue': 0x1E90FF,
9383	    'firebrick': 0xB22222,
9384	    'floralwhite': 0xFFFAF0,
9385	    'forestgreen': 0x228B22,
9386	    'fuchsia': 0xFF00FF,
9387	    'gainsboro': 0xDCDCDC,
9388	    'ghostwhite': 0xF8F8FF,
9389	    'gold': 0xFFD700,
9390	    'goldenrod': 0xDAA520,
9391	    'gray': 0x808080,
9392	    'green': 0x008000,
9393	    'greenyellow': 0xADFF2F,
9394	    'grey': 0x808080,
9395	    'honeydew': 0xF0FFF0,
9396	    'hotpink': 0xFF69B4,
9397	    'indianred': 0xCD5C5C,
9398	    'indigo': 0x4B0082,
9399	    'ivory': 0xFFFFF0,
9400	    'khaki': 0xF0E68C,
9401	    'lavender': 0xE6E6FA,
9402	    'lavenderblush': 0xFFF0F5,
9403	    'lawngreen': 0x7CFC00,
9404	    'lemonchiffon': 0xFFFACD,
9405	    'lightblue': 0xADD8E6,
9406	    'lightcoral': 0xF08080,
9407	    'lightcyan': 0xE0FFFF,
9408	    'lightgoldenrodyellow': 0xFAFAD2,
9409	    'lightgray': 0xD3D3D3,
9410	    'lightgreen': 0x90EE90,
9411	    'lightgrey': 0xD3D3D3,
9412	    'lightpink': 0xFFB6C1,
9413	    'lightsalmon': 0xFFA07A,
9414	    'lightseagreen': 0x20B2AA,
9415	    'lightskyblue': 0x87CEFA,
9416	    'lightslategray': 0x778899,
9417	    'lightslategrey': 0x778899,
9418	    'lightsteelblue': 0xB0C4DE,
9419	    'lightyellow': 0xFFFFE0,
9420	    'lime': 0x00FF00,
9421	    'limegreen': 0x32CD32,
9422	    'linen': 0xFAF0E6,
9423	    'magenta': 0xFF00FF,
9424	    'maroon': 0x800000,
9425	    'mediumaquamarine': 0x66CDAA,
9426	    'mediumblue': 0x0000CD,
9427	    'mediumorchid': 0xBA55D3,
9428	    'mediumpurple': 0x9370DB,
9429	    'mediumseagreen': 0x3CB371,
9430	    'mediumslateblue': 0x7B68EE,
9431	    'mediumspringgreen': 0x00FA9A,
9432	    'mediumturquoise': 0x48D1CC,
9433	    'mediumvioletred': 0xC71585,
9434	    'midnightblue': 0x191970,
9435	    'mintcream': 0xF5FFFA,
9436	    'mistyrose': 0xFFE4E1,
9437	    'moccasin': 0xFFE4B5,
9438	    'navajowhite': 0xFFDEAD,
9439	    'navy': 0x000080,
9440	    'oldlace': 0xFDF5E6,
9441	    'olive': 0x808000,
9442	    'olivedrab': 0x6B8E23,
9443	    'orange': 0xFFA500,
9444	    'orangered': 0xFF4500,
9445	    'orchid': 0xDA70D6,
9446	    'palegoldenrod': 0xEEE8AA,
9447	    'palegreen': 0x98FB98,
9448	    'paleturquoise': 0xAFEEEE,
9449	    'palevioletred': 0xDB7093,
9450	    'papayawhip': 0xFFEFD5,
9451	    'peachpuff': 0xFFDAB9,
9452	    'peru': 0xCD853F,
9453	    'pink': 0xFFC0CB,
9454	    'plum': 0xDDA0DD,
9455	    'powderblue': 0xB0E0E6,
9456	    'purple': 0x800080,
9457	    'rebeccapurple': 0x663399,
9458	    'red': 0xFF0000,
9459	    'rosybrown': 0xBC8F8F,
vendor: 4,148 bytes, lines 9460-9587
9460	    'royalblue': 0x4169E1,
9461	    'saddlebrown': 0x8B4513,
9462	    'salmon': 0xFA8072,
9463	    'sandybrown': 0xF4A460,
9464	    'seagreen': 0x2E8B57,
9465	    'seashell': 0xFFF5EE,
9466	    'sienna': 0xA0522D,
9467	    'silver': 0xC0C0C0,
9468	    'skyblue': 0x87CEEB,
9469	    'slateblue': 0x6A5ACD,
9470	    'slategray': 0x708090,
9471	    'slategrey': 0x708090,
9472	    'snow': 0xFFFAFA,
9473	    'springgreen': 0x00FF7F,
9474	    'steelblue': 0x4682B4,
9475	    'tan': 0xD2B48C,
9476	    'teal': 0x008080,
9477	    'thistle': 0xD8BFD8,
9478	    'tomato': 0xFF6347,
9479	    'turquoise': 0x40E0D0,
9480	    'violet': 0xEE82EE,
9481	    'wheat': 0xF5DEB3,
9482	    'white': 0xFFFFFF,
9483	    'whitesmoke': 0xF5F5F5,
9484	    'yellow': 0xFFFF00,
9485	    'yellowgreen': 0x9ACD32
9486	};
9487	const _hslA = {
9488	    h: 0,
9489	    s: 0,
9490	    l: 0
9491	};
9492	const _hslB = {
9493	    h: 0,
9494	    s: 0,
9495	    l: 0
9496	};
9497	function hue2rgb(p, q, t) {
9498	    if (t < 0) t += 1;
9499	    if (t > 1) t -= 1;
9500	    if (t < 1 / 6) return p + (q - p) * 6 * t;
9501	    if (t < 1 / 2) return q;
9502	    if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);
9503	    return p;
9504	}
9505	/**
9506	 * A Color instance is represented by RGB components in the linear <i>working
9507	 * color space</i>, which defaults to `LinearSRGBColorSpace`. Inputs
9508	 * conventionally using `SRGBColorSpace` (such as hexadecimals and CSS
9509	 * strings) are converted to the working color space automatically.
9510	 *
9511	 * ```js
9512	 * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace
9513	 * const color = new THREE.Color().setHex( 0x112233 );
9514	 * ```
9515	 * Source color spaces may be specified explicitly, to ensure correct conversions.
9516	 * ```js
9517	 * // assumed already LinearSRGBColorSpace; no conversion
9518	 * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 );
9519	 *
9520	 * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace
9521	 * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace );
9522	 * ```
9523	 * If THREE.ColorManagement is disabled, no conversions occur. For details,
9524	 * see <i>Color management</i>. Iterating through a Color instance will yield
9525	 * its components (r, g, b) in the corresponding order. A Color can be initialised
9526	 * in any of the following ways:
9527	 * ```js
9528	 * //empty constructor - will default white
9529	 * const color1 = new THREE.Color();
9530	 *
9531	 * //Hexadecimal color (recommended)
9532	 * const color2 = new THREE.Color( 0xff0000 );
9533	 *
9534	 * //RGB string
9535	 * const color3 = new THREE.Color("rgb(255, 0, 0)");
9536	 * const color4 = new THREE.Color("rgb(100%, 0%, 0%)");
9537	 *
9538	 * //X11 color name - all 140 color names are supported.
9539	 * //Note the lack of CamelCase in the name
9540	 * const color5 = new THREE.Color( 'skyblue' );
9541	 * //HSL string
9542	 * const color6 = new THREE.Color("hsl(0, 100%, 50%)");
9543	 *
9544	 * //Separate RGB values between 0 and 1
9545	 * const color7 = new THREE.Color( 1, 0, 0 );
9546	 * ```
9547	 */ class Color {
9548	    /**
9549		 * Sets the colors's components from the given values.
9550		 *
9551		 * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are
9552		 * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.
9553		 * @param {number} [g] - The green component.
9554		 * @param {number} [b] - The blue component.
9555		 * @return {Color} A reference to this color.
9556		 */ set(r, g, b) {
9557	        if (g === undefined && b === undefined) {
9558	            // r is THREE.Color, hex or string
9559	            const value = r;
9560	            if (value && value.isColor) {
9561	                this.copy(value);
9562	            } else if (typeof value === 'number') {
9563	                this.setHex(value);
9564	            } else if (typeof value === 'string') {
9565	                this.setStyle(value);
9566	            }
9567	        } else {
9568	            this.setRGB(r, g, b);
9569	        }
9570	        return this;
9571	    }
9572	    /**
9573		 * Sets the colors's components to the given scalar value.
9574		 *
9575		 * @param {number} scalar - The scalar value.
9576		 * @return {Color} A reference to this color.
9577		 */ setScalar(scalar) {
9578	        this.r = scalar;
9579	        this.g = scalar;
9580	        this.b = scalar;
9581	        return this;
9582	    }
9583	    /**
9584		 * Sets this color from a hexadecimal value.
9585		 *
9586		 * @param {number} hex - The hexadecimal value.
9587		 * @param {string}
vendor: 10,233 bytes, lines 9587-9830
9587 [colorSpace=SRGBColorSpace] - The color space.
9588		 * @return {Color} A reference to this color.
9589		 */ setHex(hex, colorSpace = SRGBColorSpace) {
9590	        hex = Math.floor(hex);
9591	        this.r = (hex >> 16 & 255) / 255;
9592	        this.g = (hex >> 8 & 255) / 255;
9593	        this.b = (hex & 255) / 255;
9594	        ColorManagement.toWorkingColorSpace(this, colorSpace);
9595	        return this;
9596	    }
9597	    /**
9598		 * Sets this color from RGB values.
9599		 *
9600		 * @param {number} r - Red channel value between `0.0` and `1.0`.
9601		 * @param {number} g - Green channel value between `0.0` and `1.0`.
9602		 * @param {number} b - Blue channel value between `0.0` and `1.0`.
9603		 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
9604		 * @return {Color} A reference to this color.
9605		 */ setRGB(r, g, b, colorSpace = ColorManagement.workingColorSpace) {
9606	        this.r = r;
9607	        this.g = g;
9608	        this.b = b;
9609	        ColorManagement.toWorkingColorSpace(this, colorSpace);
9610	        return this;
9611	    }
9612	    /**
9613		 * Sets this color from RGB values.
9614		 *
9615		 * @param {number} h - Hue value between `0.0` and `1.0`.
9616		 * @param {number} s - Saturation value between `0.0` and `1.0`.
9617		 * @param {number} l - Lightness value between `0.0` and `1.0`.
9618		 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
9619		 * @return {Color} A reference to this color.
9620		 */ setHSL(h, s, l, colorSpace = ColorManagement.workingColorSpace) {
9621	        // h,s,l ranges are in 0.0 - 1.0
9622	        h = euclideanModulo(h, 1);
9623	        s = clamp$1(s, 0, 1);
9624	        l = clamp$1(l, 0, 1);
9625	        if (s === 0) {
9626	            this.r = this.g = this.b = l;
9627	        } else {
9628	            const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;
9629	            const q = 2 * l - p;
9630	            this.r = hue2rgb(q, p, h + 1 / 3);
9631	            this.g = hue2rgb(q, p, h);
9632	            this.b = hue2rgb(q, p, h - 1 / 3);
9633	        }
9634	        ColorManagement.toWorkingColorSpace(this, colorSpace);
9635	        return this;
9636	    }
9637	    /**
9638		 * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`,
9639		 * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or
9640		 * any [X11 color name]{@link https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart} -
9641		 * all 140 color names are supported).
9642		 *
9643		 * @param {string} style - Color as a CSS-style string.
9644		 * @param {string} [colorSpace=SRGBColorSpace] - The color space.
9645		 * @return {Color} A reference to this color.
9646		 */ setStyle(style, colorSpace = SRGBColorSpace) {
9647	        function handleAlpha(string) {
9648	            if (string === undefined) return;
9649	            if (parseFloat(string) < 1) {
9650	                console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.');
9651	            }
9652	        }
9653	        let m;
9654	        if (m = /^(\w+)\(([^\)]*)\)/.exec(style)) {
9655	            // rgb / hsl
9656	            let color;
9657	            const name = m[1];
9658	            const components = m[2];
9659	            switch(name){
9660	                case 'rgb':
9661	                case 'rgba':
9662	                    if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
9663	                        // rgb(255,0,0) rgba(255,0,0,0.5)
9664	                        handleAlpha(color[4]);
9665	                        return this.setRGB(Math.min(255, parseInt(color[1], 10)) / 255, Math.min(255, parseInt(color[2], 10)) / 255, Math.min(255, parseInt(color[3], 10)) / 255, colorSpace);
9666	                    }
9667	                    if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
9668	                        // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
9669	                        handleAlpha(color[4]);
9670	                        return this.setRGB(Math.min(100, parseInt(color[1], 10)) / 100, Math.min(100, parseInt(color[2], 10)) / 100, Math.min(100, parseInt(color[3], 10)) / 100, colorSpace);
9671	                    }
9672	                    break;
9673	                case 'hsl':
9674	                case 'hsla':
9675	                    if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
9676	                        // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
9677	                        handleAlpha(color[4]);
9678	                        return this.setHSL(parseFloat(color[1]) / 360, parseFloat(color[2]) / 100, parseFloat(color[3]) / 100, colorSpace);
9679	                    }
9680	                    break;
9681	                default:
9682	                    console.warn('THREE.Color: Unknown color model ' + style);
9683	            }
9684	        } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) {
9685	            // hex color
9686	            const hex = m[1];
9687	            const size = hex.length;
9688	            if (size === 3) {
9689	                // #ff0
9690	                return this.setRGB(parseInt(hex.charAt(0), 16) / 15, parseInt(hex.charAt(1), 16) / 15, parseInt(hex.charAt(2), 16) / 15, colorSpace);
9691	            } else if (size === 6) {
9692	                // #ff0000
9693	                return this.setHex(parseInt(hex, 16), colorSpace);
9694	            } else {
9695	                console.warn('THREE.Color: Invalid hex color ' + style);
9696	            }
9697	        } else if (style && style.length > 0) {
9698	            return this.setColorName(style, colorSpace);
9699	        }
9700	        return this;
9701	    }
9702	    /**
9703		 * Sets this color from a color name. Faster than {@link Color#setStyle} if
9704		 * you don't need the other CSS-style formats.
9705		 *
9706		 * For convenience, the list of names is exposed in `Color.NAMES` as a hash.
9707		 * ```js
9708		 * Color.NAMES.aliceblue // returns 0xF0F8FF
9709		 * ```
9710		 *
9711		 * @param {string} style - The color name.
9712		 * @param {string} [colorSpace=SRGBColorSpace] - The color space.
9713		 * @return {Color} A reference to this color.
9714		 */ setColorName(style, colorSpace = SRGBColorSpace) {
9715	        // color keywords
9716	        const hex = _colorKeywords[style.toLowerCase()];
9717	        if (hex !== undefined) {
9718	            // red
9719	            this.setHex(hex, colorSpace);
9720	        } else {
9721	            // unknown color
9722	            console.warn('THREE.Color: Unknown color ' + style);
9723	        }
9724	        return this;
9725	    }
9726	    /**
9727		 * Returns a new color with copied values from this instance.
9728		 *
9729		 * @return {Color} A clone of this instance.
9730		 */ clone() {
9731	        return new this.constructor(this.r, this.g, this.b);
9732	    }
9733	    /**
9734		 * Copies the values of the given color to this instance.
9735		 *
9736		 * @param {Color} color - The color to copy.
9737		 * @return {Color} A reference to this color.
9738		 */ copy(color) {
9739	        this.r = color.r;
9740	        this.g = color.g;
9741	        this.b = color.b;
9742	        return this;
9743	    }
9744	    /**
9745		 * Copies the given color into this color, and then converts this color from
9746		 * `SRGBColorSpace` to `LinearSRGBColorSpace`.
9747		 *
9748		 * @param {Color} color - The color to copy/convert.
9749		 * @return {Color} A reference to this color.
9750		 */ copySRGBToLinear(color) {
9751	        this.r = SRGBToLinear(color.r);
9752	        this.g = SRGBToLinear(color.g);
9753	        this.b = SRGBToLinear(color.b);
9754	        return this;
9755	    }
9756	    /**
9757		 * Copies the given color into this color, and then converts this color from
9758		 * `LinearSRGBColorSpace` to `SRGBColorSpace`.
9759		 *
9760		 * @param {Color} color - The color to copy/convert.
9761		 * @return {Color} A reference to this color.
9762		 */ copyLinearToSRGB(color) {
9763	        this.r = LinearToSRGB(color.r);
9764	        this.g = LinearToSRGB(color.g);
9765	        this.b = LinearToSRGB(color.b);
9766	        return this;
9767	    }
9768	    /**
9769		 * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`.
9770		 *
9771		 * @return {Color} A reference to this color.
9772		 */ convertSRGBToLinear() {
9773	        this.copySRGBToLinear(this);
9774	        return this;
9775	    }
9776	    /**
9777		 * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`.
9778		 *
9779		 * @return {Color} A reference to this color.
9780		 */ convertLinearToSRGB() {
9781	        this.copyLinearToSRGB(this);
9782	        return this;
9783	    }
9784	    /**
9785		 * Returns the hexadecimal value of this color.
9786		 *
9787		 * @param {string} [colorSpace=SRGBColorSpace] - The color space.
9788		 * @return {number} The hexadecimal value.
9789		 */ getHex(colorSpace = SRGBColorSpace) {
9790	        ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace);
9791	        return Math.round(clamp$1(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp$1(_color.g * 255, 0, 255)) * 256 + Math.round(clamp$1(_color.b * 255, 0, 255));
9792	    }
9793	    /**
9794		 * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').
9795		 *
9796		 * @param {string} [colorSpace=SRGBColorSpace] - The color space.
9797		 * @return {string} The hexadecimal value as a string.
9798		 */ getHexString(colorSpace = SRGBColorSpace) {
9799	        return ('000000' + this.getHex(colorSpace).toString(16)).slice(-6);
9800	    }
9801	    /**
9802		 * Converts the colors RGB values into the HSL format and stores them into the
9803		 * given target object.
9804		 *
9805		 * @param {{h:0,s:0,l:0}} target - The target object that is used to store the method's result.
9806		 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
9807		 * @return {{h:number,s:number,l:number}} The HSL representation of this color.
9808		 */ getHSL(target, colorSpace = ColorManagement.workingColorSpace) {
9809	        // h,s,l ranges are in 0.0 - 1.0
9810	        ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace);
9811	        const r = _color.r, g = _color.g, b = _color.b;
9812	        const max = Math.max(r, g, b);
9813	        const min = Math.min(r, g, b);
9814	        let hue, saturation;
9815	        const lightness = (min + max) / 2.0;
9816	        if (min === max) {
9817	            hue = 0;
9818	            saturation = 0;
9819	        } else {
9820	            const delta = max - min;
9821	            saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
9822	            switch(max){
9823	                case r:
9824	                    hue = (g - b) / delta + (g < b ? 6 : 0);
9825	                    break;
9826	                case g:
9827	                    hue = (b - r) / delta + 2;
9828	                    break;
9829	                case b:
9830	                    hue = (r - g) / delta + 4;
vendor: 6,884 bytes, lines 9831-10010
9831	                    break;
9832	            }
9833	            hue /= 6;
9834	        }
9835	        target.h = hue;
9836	        target.s = saturation;
9837	        target.l = lightness;
9838	        return target;
9839	    }
9840	    /**
9841		 * Returns the RGB values of this color and stores them into the given target object.
9842		 *
9843		 * @param {Color} target - The target color that is used to store the method's result.
9844		 * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space.
9845		 * @return {Color} The RGB representation of this color.
9846		 */ getRGB(target, colorSpace = ColorManagement.workingColorSpace) {
9847	        ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace);
9848	        target.r = _color.r;
9849	        target.g = _color.g;
9850	        target.b = _color.b;
9851	        return target;
9852	    }
9853	    /**
9854		 * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`.
9855		 *
9856		 * @param {string} [colorSpace=SRGBColorSpace] - The color space.
9857		 * @return {string} The CSS representation of this color.
9858		 */ getStyle(colorSpace = SRGBColorSpace) {
9859	        ColorManagement.fromWorkingColorSpace(_color.copy(this), colorSpace);
9860	        const r = _color.r, g = _color.g, b = _color.b;
9861	        if (colorSpace !== SRGBColorSpace) {
9862	            // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
9863	            return `color(${colorSpace} ${r.toFixed(3)} ${g.toFixed(3)} ${b.toFixed(3)})`;
9864	        }
9865	        return `rgb(${Math.round(r * 255)},${Math.round(g * 255)},${Math.round(b * 255)})`;
9866	    }
9867	    /**
9868		 * Adds the given HSL values to this color's values.
9869		 * Internally, this converts the color's RGB values to HSL, adds HSL
9870		 * and then converts the color back to RGB.
9871		 *
9872		 * @param {number} h - Hue value between `0.0` and `1.0`.
9873		 * @param {number} s - Saturation value between `0.0` and `1.0`.
9874		 * @param {number} l - Lightness value between `0.0` and `1.0`.
9875		 * @return {Color} A reference to this color.
9876		 */ offsetHSL(h, s, l) {
9877	        this.getHSL(_hslA);
9878	        return this.setHSL(_hslA.h + h, _hslA.s + s, _hslA.l + l);
9879	    }
9880	    /**
9881		 * Adds the RGB values of the given color to the RGB values of this color.
9882		 *
9883		 * @param {Color} color - The color to add.
9884		 * @return {Color} A reference to this color.
9885		 */ add(color) {
9886	        this.r += color.r;
9887	        this.g += color.g;
9888	        this.b += color.b;
9889	        return this;
9890	    }
9891	    /**
9892		 * Adds the RGB values of the given colors and stores the result in this instance.
9893		 *
9894		 * @param {Color} color1 - The first color.
9895		 * @param {Color} color2 - The second color.
9896		 * @return {Color} A reference to this color.
9897		 */ addColors(color1, color2) {
9898	        this.r = color1.r + color2.r;
9899	        this.g = color1.g + color2.g;
9900	        this.b = color1.b + color2.b;
9901	        return this;
9902	    }
9903	    /**
9904		 * Adds the given scalar value to the RGB values of this color.
9905		 *
9906		 * @param {number} s - The scalar to add.
9907		 * @return {Color} A reference to this color.
9908		 */ addScalar(s) {
9909	        this.r += s;
9910	        this.g += s;
9911	        this.b += s;
9912	        return this;
9913	    }
9914	    /**
9915		 * Subtracts the RGB values of the given color from the RGB values of this color.
9916		 *
9917		 * @param {Color} color - The color to subtract.
9918		 * @return {Color} A reference to this color.
9919		 */ sub(color) {
9920	        this.r = Math.max(0, this.r - color.r);
9921	        this.g = Math.max(0, this.g - color.g);
9922	        this.b = Math.max(0, this.b - color.b);
9923	        return this;
9924	    }
9925	    /**
9926		 * Multiplies the RGB values of the given color with the RGB values of this color.
9927		 *
9928		 * @param {Color} color - The color to multiply.
9929		 * @return {Color} A reference to this color.
9930		 */ multiply(color) {
9931	        this.r *= color.r;
9932	        this.g *= color.g;
9933	        this.b *= color.b;
9934	        return this;
9935	    }
9936	    /**
9937		 * Multiplies the given scalar value with the RGB values of this color.
9938		 *
9939		 * @param {number} s - The scalar to multiply.
9940		 * @return {Color} A reference to this color.
9941		 */ multiplyScalar(s) {
9942	        this.r *= s;
9943	        this.g *= s;
9944	        this.b *= s;
9945	        return this;
9946	    }
9947	    /**
9948		 * Linearly interpolates this color's RGB values toward the RGB values of the
9949		 * given color. The alpha argument can be thought of as the ratio between
9950		 * the two colors, where `0.0` is this color and `1.0` is the first argument.
9951		 *
9952		 * @param {Color} color - The color to converge on.
9953		 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
9954		 * @return {Color} A reference to this color.
9955		 */ lerp(color, alpha) {
9956	        this.r += (color.r - this.r) * alpha;
9957	        this.g += (color.g - this.g) * alpha;
9958	        this.b += (color.b - this.b) * alpha;
9959	        return this;
9960	    }
9961	    /**
9962		 * Linearly interpolates between the given colors and stores the result in this instance.
9963		 * The alpha argument can be thought of as the ratio between the two colors, where `0.0`
9964		 * is the first and `1.0` is the second color.
9965		 *
9966		 * @param {Color} color1 - The first color.
9967		 * @param {Color} color2 - The second color.
9968		 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
9969		 * @return {Color} A reference to this color.
9970		 */ lerpColors(color1, color2, alpha) {
9971	        this.r = color1.r + (color2.r - color1.r) * alpha;
9972	        this.g = color1.g + (color2.g - color1.g) * alpha;
9973	        this.b = color1.b + (color2.b - color1.b) * alpha;
9974	        return this;
9975	    }
9976	    /**
9977		 * Linearly interpolates this color's HSL values toward the HSL values of the
9978		 * given color. It differs from {@link Color#lerp} by not interpolating straight
9979		 * from one color to the other, but instead going through all the hues in between
9980		 * those two colors. The alpha argument can be thought of as the ratio between
9981		 * the two colors, where 0.0 is this color and 1.0 is the first argument.
9982		 *
9983		 * @param {Color} color - The color to converge on.
9984		 * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`.
9985		 * @return {Color} A reference to this color.
9986		 */ lerpHSL(color, alpha) {
9987	        this.getHSL(_hslA);
9988	        color.getHSL(_hslB);
9989	        const h = lerp$1(_hslA.h, _hslB.h, alpha);
9990	        const s = lerp$1(_hslA.s, _hslB.s, alpha);
9991	        const l = lerp$1(_hslA.l, _hslB.l, alpha);
9992	        this.setHSL(h, s, l);
9993	        return this;
9994	    }
9995	    /**
9996		 * Sets the color's RGB components from the given 3D vector.
9997		 *
9998		 * @param {Vector3} v - The vector to set.
9999		 * @return {Color} A reference to this color.
10000		 */ setFromVector3(v) {
10001	        this.r = v.x;
10002	        this.g = v.y;
10003	        this.b = v.z;
10004	        return this;
10005	    }
10006	    /**
10007		 * Transforms this color with the given 3x3 matrix.
10008		 *
10009		 * @param {Matrix3} m - The matrix.
10010		 * @return {Color} A reference to this color.
vendor: 20,959 bytes, lines 10011-10437
10011		 */ applyMatrix3(m) {
10012	        const r = this.r, g = this.g, b = this.b;
10013	        const e = m.elements;
10014	        this.r = e[0] * r + e[3] * g + e[6] * b;
10015	        this.g = e[1] * r + e[4] * g + e[7] * b;
10016	        this.b = e[2] * r + e[5] * g + e[8] * b;
10017	        return this;
10018	    }
10019	    /**
10020		 * Returns `true` if this color is equal with the given one.
10021		 *
10022		 * @param {Color} c - The color to test for equality.
10023		 * @return {boolean} Whether this bounding color is equal with the given one.
10024		 */ equals(c) {
10025	        return c.r === this.r && c.g === this.g && c.b === this.b;
10026	    }
10027	    /**
10028		 * Sets this color's RGB components from the given array.
10029		 *
10030		 * @param {Array<number>} array - An array holding the RGB values.
10031		 * @param {number} [offset=0] - The offset into the array.
10032		 * @return {Color} A reference to this color.
10033		 */ fromArray(array, offset = 0) {
10034	        this.r = array[offset];
10035	        this.g = array[offset + 1];
10036	        this.b = array[offset + 2];
10037	        return this;
10038	    }
10039	    /**
10040		 * Writes the RGB components of this color to the given array. If no array is provided,
10041		 * the method returns a new instance.
10042		 *
10043		 * @param {Array<number>} [array=[]] - The target array holding the color components.
10044		 * @param {number} [offset=0] - Index of the first element in the array.
10045		 * @return {Array<number>} The color components.
10046		 */ toArray(array = [], offset = 0) {
10047	        array[offset] = this.r;
10048	        array[offset + 1] = this.g;
10049	        array[offset + 2] = this.b;
10050	        return array;
10051	    }
10052	    /**
10053		 * Sets the components of this color from the given buffer attribute.
10054		 *
10055		 * @param {BufferAttribute} attribute - The buffer attribute holding color data.
10056		 * @param {number} index - The index into the attribute.
10057		 * @return {Color} A reference to this color.
10058		 */ fromBufferAttribute(attribute, index) {
10059	        this.r = attribute.getX(index);
10060	        this.g = attribute.getY(index);
10061	        this.b = attribute.getZ(index);
10062	        return this;
10063	    }
10064	    /**
10065		 * This methods defines the serialization result of this class. Returns the color
10066		 * as a hexadecimal value.
10067		 *
10068		 * @return {number} The hexadecimal value.
10069		 */ toJSON() {
10070	        return this.getHex();
10071	    }
10072	    *[Symbol.iterator]() {
10073	        yield this.r;
10074	        yield this.g;
10075	        yield this.b;
10076	    }
10077	    /**
10078		 * Constructs a new color.
10079		 *
10080		 * Note that standard method of specifying color in three.js is with a hexadecimal triplet,
10081		 * and that method is used throughout the rest of the documentation.
10082		 *
10083		 * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are
10084		 * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance.
10085		 * @param {number} [g] - The green component.
10086		 * @param {number} [b] - The blue component.
10087		 */ constructor(r, g, b){
10088	        /**
10089			 * This flag can be used for type testing.
10090			 *
10091			 * @type {boolean}
10092			 * @readonly
10093			 * @default true
10094			 */ this.isColor = true;
10095	        /**
10096			 * The red component.
10097			 *
10098			 * @type {number}
10099			 * @default 1
10100			 */ this.r = 1;
10101	        /**
10102			 * The green component.
10103			 *
10104			 * @type {number}
10105			 * @default 1
10106			 */ this.g = 1;
10107	        /**
10108			 * The blue component.
10109			 *
10110			 * @type {number}
10111			 * @default 1
10112			 */ this.b = 1;
10113	        return this.set(r, g, b);
10114	    }
10115	}
10116	const _color = /*@__PURE__*/ new Color();
10117	/**
10118	 * A dictionary with X11 color names.
10119	 *
10120	 * Note that multiple words such as Dark Orange become the string 'darkorange'.
10121	 *
10122	 * @static
10123	 * @type {Object}
10124	 */ Color.NAMES = _colorKeywords;
10125	let _materialId = 0;
10126	/**
10127	 * Abstract base class for materials.
10128	 *
10129	 * Materials define the appearance of renderable 3D objects.
10130	 *
10131	 * @abstract
10132	 * @augments EventDispatcher
10133	 */ let Material$1 = class Material extends EventDispatcher {
10134	    /**
10135		 * Sets the alpha value to be used when running an alpha test. The material
10136		 * will not be rendered if the opacity is lower than this value.
10137		 *
10138		 * @type {number}
10139		 * @readonly
10140		 * @default 0
10141		 */ get alphaTest() {
10142	        return this._alphaTest;
10143	    }
10144	    set alphaTest(value) {
10145	        if (this._alphaTest > 0 !== value > 0) {
10146	            this.version++;
10147	        }
10148	        this._alphaTest = value;
10149	    }
10150	    /**
10151		 * An optional callback that is executed immediately before the material is used to render a 3D object.
10152		 *
10153		 * This method can only be used when rendering with {@link WebGLRenderer}.
10154		 *
10155		 * @param {WebGLRenderer} renderer - The renderer.
10156		 * @param {Scene} scene - The scene.
10157		 * @param {Camera} camera - The camera that is used to render the scene.
10158		 * @param {BufferGeometry} geometry - The 3D object's geometry.
10159		 * @param {Object3D} object - The 3D object.
10160		 * @param {Object} group - The geometry group data.
10161		 */ onBeforeRender() {}
10162	    /**
10163		 * An optional callback that is executed immediately before the shader
10164		 * program is compiled. This function is called with the shader source code
10165		 * as a parameter. Useful for the modification of built-in materials.
10166		 *
10167		 * This method can only be used when rendering with {@link WebGLRenderer}. The
10168		 * recommended approach when customizing materials is to use `WebGPURenderer` with the new
10169		 * Node Material system and [TSL]{@link https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language}.
10170		 *
10171		 * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source.
10172		 * @param {WebGLRenderer} renderer - A reference to the renderer.
10173		 */ onBeforeCompile() {}
10174	    /**
10175		 * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify
10176		 * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached
10177		 * shader or recompile the shader for this material as needed.
10178		 *
10179		 * This method can only be used when rendering with {@link WebGLRenderer}.
10180		 *
10181		 * @return {string} The custom program cache key.
10182		 */ customProgramCacheKey() {
10183	        return this.onBeforeCompile.toString();
10184	    }
10185	    setValues(values) {
10186	        if (values === undefined) return;
10187	        for(const key in values){
10188	            const newValue = values[key];
10189	            if (newValue === undefined) {
10190	                console.warn(`THREE.Material: parameter '${key}' has value of undefined.`);
10191	                continue;
10192	            }
10193	            const currentValue = this[key];
10194	            if (currentValue === undefined) {
10195	                console.warn(`THREE.Material: '${key}' is not a property of THREE.${this.type}.`);
10196	                continue;
10197	            }
10198	            if (currentValue && currentValue.isColor) {
10199	                currentValue.set(newValue);
10200	            } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) {
10201	                currentValue.copy(newValue);
10202	            } else {
10203	                this[key] = newValue;
10204	            }
10205	        }
10206	    }
10207	    /**
10208		 * Serializes the material into JSON.
10209		 *
10210		 * @param {?(Object|string)} meta - An optional value holding meta information about the serialization.
10211		 * @return {Object} A JSON object representing the serialized material.
10212		 * @see {@link ObjectLoader#parse}
10213		 */ toJSON(meta) {
10214	        const isRootObject = meta === undefined || typeof meta === 'string';
10215	        if (isRootObject) {
10216	            meta = {
10217	                textures: {},
10218	                images: {}
10219	            };
10220	        }
10221	        const data = {
10222	            metadata: {
10223	                version: 4.6,
10224	                type: 'Material',
10225	                generator: 'Material.toJSON'
10226	            }
10227	        };
10228	        // standard Material serialization
10229	        data.uuid = this.uuid;
10230	        data.type = this.type;
10231	        if (this.name !== '') data.name = this.name;
10232	        if (this.color && this.color.isColor) data.color = this.color.getHex();
10233	        if (this.roughness !== undefined) data.roughness = this.roughness;
10234	        if (this.metalness !== undefined) data.metalness = this.metalness;
10235	        if (this.sheen !== undefined) data.sheen = this.sheen;
10236	        if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex();
10237	        if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness;
10238	        if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
10239	        if (this.emissiveIntensity !== undefined && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
10240	        if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
10241	        if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity;
10242	        if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex();
10243	        if (this.shininess !== undefined) data.shininess = this.shininess;
10244	        if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat;
10245	        if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness;
10246	        if (this.clearcoatMap && this.clearcoatMap.isTexture) {
10247	            data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid;
10248	        }
10249	        if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) {
10250	            data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid;
10251	        }
10252	        if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) {
10253	            data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid;
10254	            data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
10255	        }
10256	        if (this.dispersion !== undefined) data.dispersion = this.dispersion;
10257	        if (this.iridescence !== undefined) data.iridescence = this.iridescence;
10258	        if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR;
10259	        if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
10260	        if (this.iridescenceMap && this.iridescenceMap.isTexture) {
10261	            data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid;
10262	        }
10263	        if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) {
10264	            data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid;
10265	        }
10266	        if (this.anisotropy !== undefined) data.anisotropy = this.anisotropy;
10267	        if (this.anisotropyRotation !== undefined) data.anisotropyRotation = this.anisotropyRotation;
10268	        if (this.anisotropyMap && this.anisotropyMap.isTexture) {
10269	            data.anisotropyMap = this.anisotropyMap.toJSON(meta).uuid;
10270	        }
10271	        if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid;
10272	        if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid;
10273	        if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid;
10274	        if (this.lightMap && this.lightMap.isTexture) {
10275	            data.lightMap = this.lightMap.toJSON(meta).uuid;
10276	            data.lightMapIntensity = this.lightMapIntensity;
10277	        }
10278	        if (this.aoMap && this.aoMap.isTexture) {
10279	            data.aoMap = this.aoMap.toJSON(meta).uuid;
10280	            data.aoMapIntensity = this.aoMapIntensity;
10281	        }
10282	        if (this.bumpMap && this.bumpMap.isTexture) {
10283	            data.bumpMap = this.bumpMap.toJSON(meta).uuid;
10284	            data.bumpScale = this.bumpScale;
10285	        }
10286	        if (this.normalMap && this.normalMap.isTexture) {
10287	            data.normalMap = this.normalMap.toJSON(meta).uuid;
10288	            data.normalMapType = this.normalMapType;
10289	            data.normalScale = this.normalScale.toArray();
10290	        }
10291	        if (this.displacementMap && this.displacementMap.isTexture) {
10292	            data.displacementMap = this.displacementMap.toJSON(meta).uuid;
10293	            data.displacementScale = this.displacementScale;
10294	            data.displacementBias = this.displacementBias;
10295	        }
10296	        if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid;
10297	        if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid;
10298	        if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid;
10299	        if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid;
10300	        if (this.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid;
10301	        if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid;
10302	        if (this.envMap && this.envMap.isTexture) {
10303	            data.envMap = this.envMap.toJSON(meta).uuid;
10304	            if (this.combine !== undefined) data.combine = this.combine;
10305	        }
10306	        if (this.envMapRotation !== undefined) data.envMapRotation = this.envMapRotation.toArray();
10307	        if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity;
10308	        if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity;
10309	        if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio;
10310	        if (this.gradientMap && this.gradientMap.isTexture) {
10311	            data.gradientMap = this.gradientMap.toJSON(meta).uuid;
10312	        }
10313	        if (this.transmission !== undefined) data.transmission = this.transmission;
10314	        if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid;
10315	        if (this.thickness !== undefined) data.thickness = this.thickness;
10316	        if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid;
10317	        if (this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity) data.attenuationDistance = this.attenuationDistance;
10318	        if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex();
10319	        if (this.size !== undefined) data.size = this.size;
10320	        if (this.shadowSide !== null) data.shadowSide = this.shadowSide;
10321	        if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation;
10322	        if (this.blending !== NormalBlending) data.blending = this.blending;
10323	        if (this.side !== FrontSide) data.side = this.side;
10324	        if (this.vertexColors === true) data.vertexColors = true;
10325	        if (this.opacity < 1) data.opacity = this.opacity;
10326	        if (this.transparent === true) data.transparent = true;
10327	        if (this.blendSrc !== SrcAlphaFactor) data.blendSrc = this.blendSrc;
10328	        if (this.blendDst !== OneMinusSrcAlphaFactor) data.blendDst = this.blendDst;
10329	        if (this.blendEquation !== AddEquation) data.blendEquation = this.blendEquation;
10330	        if (this.blendSrcAlpha !== null) data.blendSrcAlpha = this.blendSrcAlpha;
10331	        if (this.blendDstAlpha !== null) data.blendDstAlpha = this.blendDstAlpha;
10332	        if (this.blendEquationAlpha !== null) data.blendEquationAlpha = this.blendEquationAlpha;
10333	        if (this.blendColor && this.blendColor.isColor) data.blendColor = this.blendColor.getHex();
10334	        if (this.blendAlpha !== 0) data.blendAlpha = this.blendAlpha;
10335	        if (this.depthFunc !== LessEqualDepth) data.depthFunc = this.depthFunc;
10336	        if (this.depthTest === false) data.depthTest = this.depthTest;
10337	        if (this.depthWrite === false) data.depthWrite = this.depthWrite;
10338	        if (this.colorWrite === false) data.colorWrite = this.colorWrite;
10339	        if (this.stencilWriteMask !== 0xff) data.stencilWriteMask = this.stencilWriteMask;
10340	        if (this.stencilFunc !== AlwaysStencilFunc) data.stencilFunc = this.stencilFunc;
10341	        if (this.stencilRef !== 0) data.stencilRef = this.stencilRef;
10342	        if (this.stencilFuncMask !== 0xff) data.stencilFuncMask = this.stencilFuncMask;
10343	        if (this.stencilFail !== KeepStencilOp) data.stencilFail = this.stencilFail;
10344	        if (this.stencilZFail !== KeepStencilOp) data.stencilZFail = this.stencilZFail;
10345	        if (this.stencilZPass !== KeepStencilOp) data.stencilZPass = this.stencilZPass;
10346	        if (this.stencilWrite === true) data.stencilWrite = this.stencilWrite;
10347	        // rotation (SpriteMaterial)
10348	        if (this.rotation !== undefined && this.rotation !== 0) data.rotation = this.rotation;
10349	        if (this.polygonOffset === true) data.polygonOffset = true;
10350	        if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor;
10351	        if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits;
10352	        if (this.linewidth !== undefined && this.linewidth !== 1) data.linewidth = this.linewidth;
10353	        if (this.dashSize !== undefined) data.dashSize = this.dashSize;
10354	        if (this.gapSize !== undefined) data.gapSize = this.gapSize;
10355	        if (this.scale !== undefined) data.scale = this.scale;
10356	        if (this.dithering === true) data.dithering = true;
10357	        if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
10358	        if (this.alphaHash === true) data.alphaHash = true;
10359	        if (this.alphaToCoverage === true) data.alphaToCoverage = true;
10360	        if (this.premultipliedAlpha === true) data.premultipliedAlpha = true;
10361	        if (this.forceSinglePass === true) data.forceSinglePass = true;
10362	        if (this.wireframe === true) data.wireframe = true;
10363	        if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
10364	        if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap;
10365	        if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin;
10366	        if (this.flatShading === true) data.flatShading = true;
10367	        if (this.visible === false) data.visible = false;
10368	        if (this.toneMapped === false) data.toneMapped = false;
10369	        if (this.fog === false) data.fog = false;
10370	        if (Object.keys(this.userData).length > 0) data.userData = this.userData;
10371	        // TODO: Copied from Object3D.toJSON
10372	        function extractFromCache(cache) {
10373	            const values = [];
10374	            for(const key in cache){
10375	                const data = cache[key];
10376	                delete data.metadata;
10377	                values.push(data);
10378	            }
10379	            return values;
10380	        }
10381	        if (isRootObject) {
10382	            const textures = extractFromCache(meta.textures);
10383	            const images = extractFromCache(meta.images);
10384	            if (textures.length > 0) data.textures = textures;
10385	            if (images.length > 0) data.images = images;
10386	        }
10387	        return data;
10388	    }
10389	    /**
10390		 * Returns a new material with copied values from this instance.
10391		 *
10392		 * @return {Material} A clone of this instance.
10393		 */ clone() {
10394	        return new this.constructor().copy(this);
10395	    }
10396	    /**
10397		 * Copies the values of the given material to this instance.
10398		 *
10399		 * @param {Material} source - The material to copy.
10400		 * @return {Material} A reference to this instance.
10401		 */ copy(source) {
10402	        this.name = source.name;
10403	        this.blending = source.blending;
10404	        this.side = source.side;
10405	        this.vertexColors = source.vertexColors;
10406	        this.opacity = source.opacity;
10407	        this.transparent = source.transparent;
10408	        this.blendSrc = source.blendSrc;
10409	        this.blendDst = source.blendDst;
10410	        this.blendEquation = source.blendEquation;
10411	        this.blendSrcAlpha = source.blendSrcAlpha;
10412	        this.blendDstAlpha = source.blendDstAlpha;
10413	        this.blendEquationAlpha = source.blendEquationAlpha;
10414	        this.blendColor.copy(source.blendColor);
10415	        this.blendAlpha = source.blendAlpha;
10416	        this.depthFunc = source.depthFunc;
10417	        this.depthTest = source.depthTest;
10418	        this.depthWrite = source.depthWrite;
10419	        this.stencilWriteMask = source.stencilWriteMask;
10420	        this.stencilFunc = source.stencilFunc;
10421	        this.stencilRef = source.stencilRef;
10422	        this.stencilFuncMask = source.stencilFuncMask;
10423	        this.stencilFail = source.stencilFail;
10424	        this.stencilZFail = source.stencilZFail;
10425	        this.stencilZPass = source.stencilZPass;
10426	        this.stencilWrite = source.stencilWrite;
10427	        const srcPlanes = source.clippingPlanes;
10428	        let dstPlanes = null;
10429	        if (srcPlanes !== null) {
10430	            const n = srcPlanes.length;
10431	            dstPlanes = new Array(n);
10432	            for(let i = 0; i !== n; ++i){
10433	                dstPlanes[i] = srcPlanes[i].clone();
10434	            }
10435	        }
10436	        this.clippingPlanes = dstPlanes;
10437	        this.clipIntersection = source.clipIntersection;
10438	        this.clipShadows = source.clipShadows;
10439	        this.shadowSide = source.shadowSide;
10440	        this.colorWrite = source.colorWrite;
10441	        this.precision = source.precision;
10442	        this.polygonOffset = source.polygonOffset;
10443	        this.polygonOffsetFactor = source.polygonOffsetFactor;
10444	        this.polygonOffsetUnits = source.polygonOffsetUnits;
10445	        this.dithering = source.dithering;
10446	        this.alphaTest = source.alphaTest;
10447	        this.alphaHash = source.alphaHash;
10448	        this.alphaToCoverage = source.alphaToCoverage;
10449	        this.premultipliedAlpha = source.premultipliedAlpha;
10450	        this.forceSinglePass = source.forceSinglePass;
10451	        this.visible = source.visible;
10452	        this.toneMapped = source.toneMapped;
10453	        this.userData = JSON.parse(JSON.stringify(source.userData));
10454	        return this;
10455	    }
10456	    /**
10457		 * Frees the GPU-related resources allocated by this instance. Call this
10458		 * method whenever this instance is no longer used in your app.
10459		 *
10460		 * @fires Material#dispose
10461		 */ dispose() {
10462	        /**
10463			 * Fires when the material has been disposed of.
10464			 *
10465			 * @event Material#dispose
10466			 * @type {Object}
10467			 */ this.dispatchEvent({
10468	            type: 'dispose'
10469	        });
10470	    }
10471	    /**
10472		 * Setting this property to `true` indicates the engine the material
10473		 * needs to be recompiled.
10474		 *
10475		 * @type {boolean}
10476		 * @default false
10477		 * @param {boolean} value
10478		 */ set needsUpdate(value) {
10479	        if (value === true) this.version++;
10480	    }
10481	    onBuild() {
10482	        console.warn('Material: onBuild() has been removed.'); // @deprecated, r166
10483	    }
10484	    /**
10485		 * Constructs a new material.
10486		 */ constructor(){
10487	        super();
10488	        /**
10489			 * This flag can be used for type testing.
10490			 *
10491			 * @type {boolean}
10492			 * @readonly
10493			 * @default true
10494			 */ this.isMaterial = true;
10495	        /**
10496			 * The ID of the material.
10497			 *
10498			 * @name Material#id
10499			 * @type {number}
10500			 * @readonly
10501			 */ Object.defineProperty(this, 'id', {
10502	            value: _materialId++
10503	        });
10504	        /**
10505			 * The UUID of the material.
10506			 *
10507			 * @type {string}
10508			 * @readonly
10509			 */ this.uuid = generateUUID();
10510	        /**
10511			 * The name of the material.
10512			 *
10513			 * @type {string}
10514			 */ this.name = '';
10515	        /**
10516			 * The type property is used for detecting the object type
10517			 * in context of serialization/deserialization.
10518			 *
10519			 * @type {string}
10520			 * @readonly
10521			 */ this.type = 'Material';
10522	        /**
10523			 * Defines the blending type of the material.
10524			 *
10525			 * It must be set to `CustomBlending` if custom blending properties like
10526			 * {@link Material#blendSrc}, {@link Material#blendDst} or {@link Material#blendEquation}
10527			 * should have any effect.
10528			 *
10529			 * @type {(NoBlending|NormalBlending|AdditiveBlending|SubtractiveBlending|MultiplyBlending|CustomBlending)}
10530			 * @default NormalBlending
10531			 */ this.blending = NormalBlending;
10532	        /**
10533			 * Defines which side of faces will be rendered - front, back or both.
10534			 *
10535			 * @type {(FrontSide|BackSide|DoubleSide)}
10536			 * @default FrontSide
10537			 */ this.side = FrontSide;
10538	        /**
10539			 * If set to `true`, vertex colors should be used.
10540			 *
10541			 * The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or
10542			 * four (RGBA) component color buffer attribute is used.
10543			 *
10544			 * @type {boolean}
10545			 * @default false
10546			 */ this.vertexColors = false;
10547	        /**
10548			 * Defines how transparent the material is.
10549			 * A value of `0.0` indicates fully transparent, `1.0` is fully opaque.
10550			 *
10551			 * If the {@link Material#transparent} is not set to `true`,
10552			 * the material will remain fully opaque and this value will only affect its color.
10553			 *
10554			 * @type {number}
10555			 * @default 1
10556			 */ this.opacity = 1;
10557	        /**
10558			 * Defines whether this material is transparent. This has an effect on
10559			 * rendering as transparent objects need special treatment and are rendered
10560			 * after non-transparent objects.
10561			 *
10562			 * When set to true, the extent to which the material is transparent is
10563			 * controlled by {@link Material#opacity}.
10564			 *
10565			 * @type {boolean}
10566			 * @default false
10567			 */ this.transparent = false;
10568	        /**
10569			 * Enables alpha hashed transparency, an alternative to {@link Material#transparent} or
10570			 * {@link Material#alphaTest}. The material will not be rendered if opacity is lower than
10571			 * a random threshold. Randomization introduces some grain or noise, but approximates alpha
10572			 * blending without the associated problems of sorting. Using TAA can reduce the resulting noise.
10573			 *
10574			 * @type {boolean}
10575			 * @default false
10576			 */ this.alphaHash = false;
10577	        /**
10578			 * Defines the blending source factor.
10579			 *
10580			 * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)}
10581			 * @default SrcAlphaFactor
10582			 */ this.blendSrc = SrcAlphaFactor;
10583	        /**
10584			 * Defines the blending destination factor.
10585			 *
10586			 * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)}
10587			 * @default OneMinusSrcAlphaFactor
10588			 */ this.blendDst = OneMinusSrcAlphaFactor;
10589	        /**
10590			 * Defines the blending equation.
10591			 *
10592			 * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)}
10593			 * @default OneMinusSrcAlphaFactor
10594			 */ this.blendEquation = AddEquation;
10595	        /**
10596			 * Defines the blending source alpha factor.
10597			 *
10598			 * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)}
10599			 * @default null
10600			 */ this.blendSrcAlpha = null;
10601	        /**
10602			 * Defines the blending destination alpha factor.
10603			 *
10604			 * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)}
10605			 * @default null
10606			 */ this.blendDstAlpha = null;
10607	        /**
10608			 * Defines the blending equation of the alpha channel.
10609			 *
10610			 * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)}
10611			 * @default OneMinusSrcAlphaFactor
10612			 */ this.blendEquationAlpha = null;
10613	        /**
10614			 * Represents the RGB values of the constant blend color.
10615			 *
10616			 * This property has only an effect when using custom blending with `ConstantColor` or `OneMinusConstantColor`.
10617			 *
10618			 * @type {Color}
10619			 * @default (0,0,0)
10620			 */ this.blendColor = new Color(0, 0, 0);
10621	        /**
10622			 * Represents the alpha value of the constant blend color.
10623			 *
10624			 * This property has only an effect when using custom blending with `ConstantAlpha` or `OneMinusConstantAlpha`.
10625			 *
10626			 * @type {number}
10627			 * @default 0
10628			 */ this.blendAlpha = 0;
10629	        /**
10630			 * Defines the depth function.
10631			 *
10632			 * @type {(NeverDepth|AlwaysDepth|LessDepth|LessEqualDepth|EqualDepth|GreaterEqualDepth|GreaterDepth|NotEqualDepth)}
10633			 * @default LessEqualDepth
10634			 */ this.depthFunc = LessEqualDepth;
10635	        /**
10636			 * Whether to have depth test enabled when rendering this material.
10637			 * When the depth test is disabled, the depth write will also be implicitly disabled.
10638			 *
10639			 * @type {boolean}
10640			 * @default true
10641			 */ this.depthTest = true;
10642	        /**
10643			 * Whether rendering this material has any effect on the depth buffer.
10644			 *
10645			 * When drawing 2D overlays it can be useful to disable the depth writing in
10646			 * order to layer several things together without creating z-index artifacts.
10647			 *
10648			 * @type {boolean}
10649			 * @default true
10650			 */ this.depthWrite = true;
10651	        /**
10652			 * The bit mask to use when writing to the stencil buffer.
10653			 *
10654			 * @type {number}
10655			 * @default 0xff
10656			 */ this.stencilWriteMask = 0xff;
10657	        /**
10658			 * The stencil comparison function to use.
10659			 *
10660			 * @type {NeverStencilFunc|LessStencilFunc|EqualStencilFunc|LessEqualStencilFunc|GreaterStencilFunc|NotEqualStencilFunc|GreaterEqualStencilFunc|AlwaysStencilFunc}
10661			 * @default AlwaysStencilFunc
10662			 */ this.stencilFunc = AlwaysStencilFunc;
10663	        /**
10664			 * The value to use when performing stencil comparisons or stencil operations.
10665			 *
10666			 * @type {number}
10667			 * @default 0
10668			 */ this.stencilRef = 0;
10669	        /**
10670			 * The bit mask to use when comparing against the stencil buffer.
10671			 *
10672			 * @type {number}
10673			 * @default 0xff
10674			 */ this.stencilFuncMask = 0xff;
10675	        /**
10676			 * Which stencil operation to perform when the comparison function returns `false`.
10677			 *
10678			 * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp}
10679			 * @default KeepStencilOp
10680			 */ this.stencilFail = KeepStencilOp;
10681	        /**
10682			 * Which stencil operation to perform when the comparison function returns
10683			 * `true` but the depth test fails.
10684			 *
10685			 * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp}
10686			 * @default KeepStencilOp
10687			 */ this.stencilZFail = KeepStencilOp;
10688	        /**
10689			 * Which stencil operation to perform when the comparison function returns
10690			 * `true` and the depth test passes.
10691			 *
10692			 * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp}
10693			 * @default KeepStencilOp
10694			 */ this.stencilZPass = KeepStencilOp;
10695	        /**
10696			 * Whether stencil operations are performed against the stencil buffer. In
10697			 * order to perform writes or comparisons against the stencil buffer this
10698			 * value must be `true`.
10699			 *
10700			 * @type {boolean}
10701			 * @default false
10702			 */ this.stencilWrite = false;
10703	        /**
10704			 * User-defined clipping planes specified as THREE.Plane objects in world
10705			 * space. These planes apply to the objects this material is attached to.
10706			 * Points in space whose signed distance to the plane is negative are clipped
10707			 * (not rendered). This requires {@link WebGLRenderer#localClippingEnabled} to
10708			 * be `true`.
10709			 *
10710			 * @type {?Array<Plane>}
10711			 * @default null
10712			 */ this.clippingPlanes = null;
10713	        /**
10714			 * Changes the behavior of clipping planes so that only their intersection is
10715			 * clipped, rather than their union.
10716			 *
10717			 * @type {boolean}
10718			 * @default false
10719			 */ this.clipIntersection = false;
10720	        /**
10721			 * Defines whether to clip shadows according to the clipping planes specified
10722			 * on this material.
10723			 *
10724			 * @type {boolean}
10725			 * @default false
10726			 */ this.clipShadows = false;
10727	        /**
10728			 * Defines which side of faces cast shadows. If `null`, the side casting shadows
10729			 * is determined as follows:
10730			 *
10731			 * - When {@link Material#side} is set to `FrontSide`, the back side cast shadows.
10732			 * - When {@link Material#side} is set to `BackSide`, the front side cast shadows.
10733			 * - When {@link Material#side} is set to `DoubleSide`, both sides cast shadows.
10734			 *
10735			 * @type {?(FrontSide|BackSide|DoubleSide)}
10736			 * @default null
10737			 */ this.shadowSide = null;
10738	        /**
10739			 * Whether to render the material's color.
10740			 *
10741			 * This can be used in conjunction with {@link Object3D#renderOder} to create invisible
10742			 * objects that occlude other objects.
10743			 *
10744			 * @type {boolean}
10745			 * @default true
10746			 */ this.colorWrite = true;
10747	        /**
10748			 * Override the renderer's default precision for this material.
10749			 *
10750			 * @type {?('highp'|'mediump'|'lowp')}
10751			 * @default null
10752			 */ this.precision = null;
10753	        /**
10754			 * Whether to use polygon offset or not. When enabled, each fragment's depth value will
10755			 * be offset after it is interpolated from the depth values of the appropriate vertices.
10756			 * The offset is added before the depth test is performed and before the value is written
10757			 * into the depth buffer.
10758			 *
10759			 * Can be useful for rendering hidden-line images, for applying decals to surfaces, and for
10760			 * rendering solids with highlighted edges.
10761			 *
10762			 * @type {boolean}
10763			 * @default false
10764			 */ this.polygonOffset = false;
10765	        /**
10766			 * Specifies a scale factor that is used to create a variable depth offset for each polygon.
10767			 *
10768			 * @type {number}
10769			 * @default 0
10770			 */ this.polygonOffsetFactor = 0;
10771	        /**
10772			 * Is multiplied by an implementation-specific value to create a constant depth offset.
10773			 *
10774			 * @type {number}
10775			 * @default 0
10776			 */ this.polygonOffsetUnits = 0;
10777	        /**
10778			 * Whether to apply dithering to the color to remove the appearance of banding.
10779			 *
10780			 * @type {boolean}
10781			 * @default false
10782			 */ this.dithering = false;
10783	        /**
10784			 * Whether alpha to coverage should be enabled or not. Can only be used with MSAA-enabled contexts
10785			 * (meaning when the renderer was created with *antialias* parameter set to `true`). Enabling this
10786			 * will smooth aliasing on clip plane edges and alphaTest-clipped edges.
10787			 *
10788			 * @type {boolean}
10789			 * @default false
10790			 */ this.alphaToCoverage = false;
10791	        /**
10792			 * Whether to premultiply the alpha (transparency) value.
10793			 *
10794			 * @type {boolean}
10795			 * @default false
10796			 */ this.premultipliedAlpha = false;
10797	        /**
10798			 * Whether double-sided, transparent objects should be rendered with a single pass or not.
10799			 *
10800			 * The engine renders double-sided, transparent objects with two draw calls (back faces first,
10801			 * then front faces) to mitigate transparency artifacts. There are scenarios however where this
10802			 * approach produces no quality gains but still doubles draw calls e.g. when rendering flat
10803			 * vegetation like grass sprites. In these cases, set the `forceSinglePass` flag to `true` to
10804			 * disable the two pass rendering to avoid performance issues.
10805			 *
10806			 * @type {boolean}
10807			 * @default false
10808			 */ this.forceSinglePass = false;
vendor: 19,351 bytes, lines 10809-11385
10809	        /**
10810			 * Defines whether 3D objects using this material are visible.
10811			 *
10812			 * @type {boolean}
10813			 * @default true
10814			 */ this.visible = true;
10815	        /**
10816			 * Defines whether this material is tone mapped according to the renderer's tone mapping setting.
10817			 *
10818			 * It is ignored when rendering to a render target or using post processing or when using
10819			 * `WebGPURenderer`. In all these cases, all materials are honored by tone mapping.
10820			 *
10821			 * @type {boolean}
10822			 * @default true
10823			 */ this.toneMapped = true;
10824	        /**
10825			 * An object that can be used to store custom data about the Material. It
10826			 * should not hold references to functions as these will not be cloned.
10827			 *
10828			 * @type {Object}
10829			 */ this.userData = {};
10830	        /**
10831			 * This starts at `0` and counts how many times {@link Material#needsUpdate} is set to `true`.
10832			 *
10833			 * @type {number}
10834			 * @readonly
10835			 * @default 0
10836			 */ this.version = 0;
10837	        this._alphaTest = 0;
10838	    }
10839	};
10840	class MeshBasicMaterial extends Material$1 {
10841	    copy(source) {
10842	        super.copy(source);
10843	        this.color.copy(source.color);
10844	        this.map = source.map;
10845	        this.lightMap = source.lightMap;
10846	        this.lightMapIntensity = source.lightMapIntensity;
10847	        this.aoMap = source.aoMap;
10848	        this.aoMapIntensity = source.aoMapIntensity;
10849	        this.specularMap = source.specularMap;
10850	        this.alphaMap = source.alphaMap;
10851	        this.envMap = source.envMap;
10852	        this.envMapRotation.copy(source.envMapRotation);
10853	        this.combine = source.combine;
10854	        this.reflectivity = source.reflectivity;
10855	        this.refractionRatio = source.refractionRatio;
10856	        this.wireframe = source.wireframe;
10857	        this.wireframeLinewidth = source.wireframeLinewidth;
10858	        this.wireframeLinecap = source.wireframeLinecap;
10859	        this.wireframeLinejoin = source.wireframeLinejoin;
10860	        this.fog = source.fog;
10861	        return this;
10862	    }
10863	    constructor(parameters){
10864	        super();
10865	        this.isMeshBasicMaterial = true;
10866	        this.type = 'MeshBasicMaterial';
10867	        this.color = new Color(0xffffff); // emissive
10868	        this.map = null;
10869	        this.lightMap = null;
10870	        this.lightMapIntensity = 1.0;
10871	        this.aoMap = null;
10872	        this.aoMapIntensity = 1.0;
10873	        this.specularMap = null;
10874	        this.alphaMap = null;
10875	        this.envMap = null;
10876	        this.envMapRotation = new Euler();
10877	        this.combine = MultiplyOperation;
10878	        this.reflectivity = 1;
10879	        this.refractionRatio = 0.98;
10880	        this.wireframe = false;
10881	        this.wireframeLinewidth = 1;
10882	        this.wireframeLinecap = 'round';
10883	        this.wireframeLinejoin = 'round';
10884	        this.fog = true;
10885	        this.setValues(parameters);
10886	    }
10887	}
10888	// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
10889	const _tables = /*@__PURE__*/ _generateTables();
10890	function _generateTables() {
10891	    // float32 to float16 helpers
10892	    const buffer = new ArrayBuffer(4);
10893	    const floatView = new Float32Array(buffer);
10894	    const uint32View = new Uint32Array(buffer);
10895	    const baseTable = new Uint32Array(512);
10896	    const shiftTable = new Uint32Array(512);
10897	    for(let i = 0; i < 256; ++i){
10898	        const e = i - 127;
10899	        // very small number (0, -0)
10900	        if (e < -27) {
10901	            baseTable[i] = 0x0000;
10902	            baseTable[i | 0x100] = 0x8000;
10903	            shiftTable[i] = 24;
10904	            shiftTable[i | 0x100] = 24;
10905	        // small number (denorm)
10906	        } else if (e < -14) {
10907	            baseTable[i] = 0x0400 >> -e - 14;
10908	            baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
10909	            shiftTable[i] = -e - 1;
10910	            shiftTable[i | 0x100] = -e - 1;
10911	        // normal number
10912	        } else if (e <= 15) {
10913	            baseTable[i] = e + 15 << 10;
10914	            baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
10915	            shiftTable[i] = 13;
10916	            shiftTable[i | 0x100] = 13;
10917	        // large number (Infinity, -Infinity)
10918	        } else if (e < 128) {
10919	            baseTable[i] = 0x7c00;
10920	            baseTable[i | 0x100] = 0xfc00;
10921	            shiftTable[i] = 24;
10922	            shiftTable[i | 0x100] = 24;
10923	        // stay (NaN, Infinity, -Infinity)
10924	        } else {
10925	            baseTable[i] = 0x7c00;
10926	            baseTable[i | 0x100] = 0xfc00;
10927	            shiftTable[i] = 13;
10928	            shiftTable[i | 0x100] = 13;
10929	        }
10930	    }
10931	    // float16 to float32 helpers
10932	    const mantissaTable = new Uint32Array(2048);
10933	    const exponentTable = new Uint32Array(64);
10934	    const offsetTable = new Uint32Array(64);
10935	    for(let i = 1; i < 1024; ++i){
10936	        let m = i << 13; // zero pad mantissa bits
10937	        let e = 0; // zero exponent
10938	        // normalized
10939	        while((m & 0x00800000) === 0){
10940	            m <<= 1;
10941	            e -= 0x00800000; // decrement exponent
10942	        }
10943	        m &= -8388609; // clear leading 1 bit
10944	        e += 0x38800000; // adjust bias
10945	        mantissaTable[i] = m | e;
10946	    }
10947	    for(let i = 1024; i < 2048; ++i){
10948	        mantissaTable[i] = 0x38000000 + (i - 1024 << 13);
10949	    }
10950	    for(let i = 1; i < 31; ++i){
10951	        exponentTable[i] = i << 23;
10952	    }
10953	    exponentTable[31] = 0x47800000;
10954	    exponentTable[32] = 0x80000000;
10955	    for(let i = 33; i < 63; ++i){
10956	        exponentTable[i] = 0x80000000 + (i - 32 << 23);
10957	    }
10958	    exponentTable[63] = 0xc7800000;
10959	    for(let i = 1; i < 64; ++i){
10960	        if (i !== 32) {
10961	            offsetTable[i] = 1024;
10962	        }
10963	    }
10964	    return {
10965	        floatView: floatView,
10966	        uint32View: uint32View,
10967	        baseTable: baseTable,
10968	        shiftTable: shiftTable,
10969	        mantissaTable: mantissaTable,
10970	        exponentTable: exponentTable,
10971	        offsetTable: offsetTable
10972	    };
10973	}
10974	/**
10975	 * Returns a half precision floating point value (FP16) from the given single
10976	 * precision floating point value (FP32).
10977	 *
10978	 * @param {number} val - A single precision floating point value.
10979	 * @return {number} The FP16 value.
10980	 */ function toHalfFloat(val) {
10981	    if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.');
10982	    val = clamp$1(val, -65504, 65504);
10983	    _tables.floatView[0] = val;
10984	    const f = _tables.uint32View[0];
10985	    const e = f >> 23 & 0x1ff;
10986	    return _tables.baseTable[e] + ((f & 0x007fffff) >> _tables.shiftTable[e]);
10987	}
10988	/**
10989	 * Returns a single precision floating point value (FP32) from the given half
10990	 * precision floating point value (FP16).
10991	 *
10992	 * @param {number} val - A half precision floating point value.
10993	 * @return {number} The FP32 value.
10994	 */ function fromHalfFloat(val) {
10995	    const m = val >> 10;
10996	    _tables.uint32View[0] = _tables.mantissaTable[_tables.offsetTable[m] + (val & 0x3ff)] + _tables.exponentTable[m];
10997	    return _tables.floatView[0];
10998	}
10999	/**
11000	 * A class containing utility functions for data.
11001	 *
11002	 * @hideconstructor
11003	 */ class DataUtils {
11004	    /**
11005		 * Returns a half precision floating point value (FP16) from the given single
11006		 * precision floating point value (FP32).
11007		 *
11008		 * @param {number} val - A single precision floating point value.
11009		 * @return {number} The FP16 value.
11010		 */ static toHalfFloat(val) {
11011	        return toHalfFloat(val);
11012	    }
11013	    /**
11014		 * Returns a single precision floating point value (FP32) from the given half
11015		 * precision floating point value (FP16).
11016		 *
11017		 * @param {number} val - A half precision floating point value.
11018		 * @return {number} The FP32 value.
11019		 */ static fromHalfFloat(val) {
11020	        return fromHalfFloat(val);
11021	    }
11022	}
11023	const _vector$9 = /*@__PURE__*/ new Vector3();
11024	const _vector2$1 = /*@__PURE__*/ new Vector2();
11025	let _id$2 = 0;
11026	class BufferAttribute {
11027	    onUploadCallback() {}
11028	    set needsUpdate(value) {
11029	        if (value === true) this.version++;
11030	    }
11031	    setUsage(value) {
11032	        this.usage = value;
11033	        return this;
11034	    }
11035	    addUpdateRange(start, count) {
11036	        this.updateRanges.push({
11037	            start,
11038	            count
11039	        });
11040	    }
11041	    clearUpdateRanges() {
11042	        this.updateRanges.length = 0;
11043	    }
11044	    copy(source) {
11045	        this.name = source.name;
11046	        this.array = new source.array.constructor(source.array);
11047	        this.itemSize = source.itemSize;
11048	        this.count = source.count;
11049	        this.normalized = source.normalized;
11050	        this.usage = source.usage;
11051	        this.gpuType = source.gpuType;
11052	        return this;
11053	    }
11054	    copyAt(index1, attribute, index2) {
11055	        index1 *= this.itemSize;
11056	        index2 *= attribute.itemSize;
11057	        for(let i = 0, l = this.itemSize; i < l; i++){
11058	            this.array[index1 + i] = attribute.array[index2 + i];
11059	        }
11060	        return this;
11061	    }
11062	    copyArray(array) {
11063	        this.array.set(array);
11064	        return this;
11065	    }
11066	    applyMatrix3(m) {
11067	        if (this.itemSize === 2) {
11068	            for(let i = 0, l = this.count; i < l; i++){
11069	                _vector2$1.fromBufferAttribute(this, i);
11070	                _vector2$1.applyMatrix3(m);
11071	                this.setXY(i, _vector2$1.x, _vector2$1.y);
11072	            }
11073	        } else if (this.itemSize === 3) {
11074	            for(let i = 0, l = this.count; i < l; i++){
11075	                _vector$9.fromBufferAttribute(this, i);
11076	                _vector$9.applyMatrix3(m);
11077	                this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
11078	            }
11079	        }
11080	        return this;
11081	    }
11082	    applyMatrix4(m) {
11083	        for(let i = 0, l = this.count; i < l; i++){
11084	            _vector$9.fromBufferAttribute(this, i);
11085	            _vector$9.applyMatrix4(m);
11086	            this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
11087	        }
11088	        return this;
11089	    }
11090	    applyNormalMatrix(m) {
11091	        for(let i = 0, l = this.count; i < l; i++){
11092	            _vector$9.fromBufferAttribute(this, i);
11093	            _vector$9.applyNormalMatrix(m);
11094	            this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
11095	        }
11096	        return this;
11097	    }
11098	    transformDirection(m) {
11099	        for(let i = 0, l = this.count; i < l; i++){
11100	            _vector$9.fromBufferAttribute(this, i);
11101	            _vector$9.transformDirection(m);
11102	            this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
11103	        }
11104	        return this;
11105	    }
11106	    set(value, offset = 0) {
11107	        // Matching BufferAttribute constructor, do not normalize the array.
11108	        this.array.set(value, offset);
11109	        return this;
11110	    }
11111	    getComponent(index, component) {
11112	        let value = this.array[index * this.itemSize + component];
11113	        if (this.normalized) value = denormalize(value, this.array);
11114	        return value;
11115	    }
11116	    setComponent(index, component, value) {
11117	        if (this.normalized) value = normalize(value, this.array);
11118	        this.array[index * this.itemSize + component] = value;
11119	        return this;
11120	    }
11121	    getX(index) {
11122	        let x = this.array[index * this.itemSize];
11123	        if (this.normalized) x = denormalize(x, this.array);
11124	        return x;
11125	    }
11126	    setX(index, x) {
11127	        if (this.normalized) x = normalize(x, this.array);
11128	        this.array[index * this.itemSize] = x;
11129	        return this;
11130	    }
11131	    getY(index) {
11132	        let y = this.array[index * this.itemSize + 1];
11133	        if (this.normalized) y = denormalize(y, this.array);
11134	        return y;
11135	    }
11136	    setY(index, y) {
11137	        if (this.normalized) y = normalize(y, this.array);
11138	        this.array[index * this.itemSize + 1] = y;
11139	        return this;
11140	    }
11141	    getZ(index) {
11142	        let z = this.array[index * this.itemSize + 2];
11143	        if (this.normalized) z = denormalize(z, this.array);
11144	        return z;
11145	    }
11146	    setZ(index, z) {
11147	        if (this.normalized) z = normalize(z, this.array);
11148	        this.array[index * this.itemSize + 2] = z;
11149	        return this;
11150	    }
11151	    getW(index) {
11152	        let w = this.array[index * this.itemSize + 3];
11153	        if (this.normalized) w = denormalize(w, this.array);
11154	        return w;
11155	    }
11156	    setW(index, w) {
11157	        if (this.normalized) w = normalize(w, this.array);
11158	        this.array[index * this.itemSize + 3] = w;
11159	        return this;
11160	    }
11161	    setXY(index, x, y) {
11162	        index *= this.itemSize;
11163	        if (this.normalized) {
11164	            x = normalize(x, this.array);
11165	            y = normalize(y, this.array);
11166	        }
11167	        this.array[index + 0] = x;
11168	        this.array[index + 1] = y;
11169	        return this;
11170	    }
11171	    setXYZ(index, x, y, z) {
11172	        index *= this.itemSize;
11173	        if (this.normalized) {
11174	            x = normalize(x, this.array);
11175	            y = normalize(y, this.array);
11176	            z = normalize(z, this.array);
11177	        }
11178	        this.array[index + 0] = x;
11179	        this.array[index + 1] = y;
11180	        this.array[index + 2] = z;
11181	        return this;
11182	    }
11183	    setXYZW(index, x, y, z, w) {
11184	        index *= this.itemSize;
11185	        if (this.normalized) {
11186	            x = normalize(x, this.array);
11187	            y = normalize(y, this.array);
11188	            z = normalize(z, this.array);
11189	            w = normalize(w, this.array);
11190	        }
11191	        this.array[index + 0] = x;
11192	        this.array[index + 1] = y;
11193	        this.array[index + 2] = z;
11194	        this.array[index + 3] = w;
11195	        return this;
11196	    }
11197	    onUpload(callback) {
11198	        this.onUploadCallback = callback;
11199	        return this;
11200	    }
11201	    clone() {
11202	        return new this.constructor(this.array, this.itemSize).copy(this);
11203	    }
11204	    toJSON() {
11205	        const data = {
11206	            itemSize: this.itemSize,
11207	            type: this.array.constructor.name,
11208	            array: Array.from(this.array),
11209	            normalized: this.normalized
11210	        };
11211	        if (this.name !== '') data.name = this.name;
11212	        if (this.usage !== StaticDrawUsage) data.usage = this.usage;
11213	        return data;
11214	    }
11215	    constructor(array, itemSize, normalized = false){
11216	        if (Array.isArray(array)) {
11217	            throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.');
11218	        }
11219	        this.isBufferAttribute = true;
11220	        Object.defineProperty(this, 'id', {
11221	            value: _id$2++
11222	        });
11223	        this.name = '';
11224	        this.array = array;
11225	        this.itemSize = itemSize;
11226	        this.count = array !== undefined ? array.length / itemSize : 0;
11227	        this.normalized = normalized;
11228	        this.usage = StaticDrawUsage;
11229	        this.updateRanges = [];
11230	        this.gpuType = FloatType;
11231	        this.version = 0;
11232	    }
11233	}
11234	class Uint16BufferAttribute extends BufferAttribute {
11235	    constructor(array, itemSize, normalized){
11236	        super(new Uint16Array(array), itemSize, normalized);
11237	    }
11238	}
11239	class Uint32BufferAttribute extends BufferAttribute {
11240	    constructor(array, itemSize, normalized){
11241	        super(new Uint32Array(array), itemSize, normalized);
11242	    }
11243	}
11244	class Float32BufferAttribute extends BufferAttribute {
11245	    constructor(array, itemSize, normalized){
11246	        super(new Float32Array(array), itemSize, normalized);
11247	    }
11248	}
11249	let _id$1 = 0;
11250	const _m1$3 = /*@__PURE__*/ new Matrix4();
11251	const _obj = /*@__PURE__*/ new Object3D();
11252	const _offset = /*@__PURE__*/ new Vector3();
11253	const _box$2 = /*@__PURE__*/ new Box3();
11254	const _boxMorphTargets = /*@__PURE__*/ new Box3();
11255	const _vector$8 = /*@__PURE__*/ new Vector3();
11256	class BufferGeometry extends EventDispatcher {
11257	    getIndex() {
11258	        return this.index;
11259	    }
11260	    setIndex(index) {
11261	        if (Array.isArray(index)) {
11262	            this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1);
11263	        } else {
11264	            this.index = index;
11265	        }
11266	        return this;
11267	    }
11268	    setIndirect(indirect) {
11269	        this.indirect = indirect;
11270	        return this;
11271	    }
11272	    getIndirect() {
11273	        return this.indirect;
11274	    }
11275	    getAttribute(name) {
11276	        return this.attributes[name];
11277	    }
11278	    setAttribute(name, attribute) {
11279	        this.attributes[name] = attribute;
11280	        return this;
11281	    }
11282	    deleteAttribute(name) {
11283	        delete this.attributes[name];
11284	        return this;
11285	    }
11286	    hasAttribute(name) {
11287	        return this.attributes[name] !== undefined;
11288	    }
11289	    addGroup(start, count, materialIndex = 0) {
11290	        this.groups.push({
11291	            start: start,
11292	            count: count,
11293	            materialIndex: materialIndex
11294	        });
11295	    }
11296	    clearGroups() {
11297	        this.groups = [];
11298	    }
11299	    setDrawRange(start, count) {
11300	        this.drawRange.start = start;
11301	        this.drawRange.count = count;
11302	    }
11303	    applyMatrix4(matrix) {
11304	        const position = this.attributes.position;
11305	        if (position !== undefined) {
11306	            position.applyMatrix4(matrix);
11307	            position.needsUpdate = true;
11308	        }
11309	        const normal = this.attributes.normal;
11310	        if (normal !== undefined) {
11311	            const normalMatrix = new Matrix3().getNormalMatrix(matrix);
11312	            normal.applyNormalMatrix(normalMatrix);
11313	            normal.needsUpdate = true;
11314	        }
11315	        const tangent = this.attributes.tangent;
11316	        if (tangent !== undefined) {
11317	            tangent.transformDirection(matrix);
11318	            tangent.needsUpdate = true;
11319	        }
11320	        if (this.boundingBox !== null) {
11321	            this.computeBoundingBox();
11322	        }
11323	        if (this.boundingSphere !== null) {
11324	            this.computeBoundingSphere();
11325	        }
11326	        return this;
11327	    }
11328	    applyQuaternion(q) {
11329	        _m1$3.makeRotationFromQuaternion(q);
11330	        this.applyMatrix4(_m1$3);
11331	        return this;
11332	    }
11333	    rotateX(angle) {
11334	        // rotate geometry around world x-axis
11335	        _m1$3.makeRotationX(angle);
11336	        this.applyMatrix4(_m1$3);
11337	        return this;
11338	    }
11339	    rotateY(angle) {
11340	        // rotate geometry around world y-axis
11341	        _m1$3.makeRotationY(angle);
11342	        this.applyMatrix4(_m1$3);
11343	        return this;
11344	    }
11345	    rotateZ(angle) {
11346	        // rotate geometry around world z-axis
11347	        _m1$3.makeRotationZ(angle);
11348	        this.applyMatrix4(_m1$3);
11349	        return this;
11350	    }
11351	    translate(x, y, z) {
11352	        // translate geometry
11353	        _m1$3.makeTranslation(x, y, z);
11354	        this.applyMatrix4(_m1$3);
11355	        return this;
11356	    }
11357	    scale(x, y, z) {
11358	        // scale geometry
11359	        _m1$3.makeScale(x, y, z);
11360	        this.applyMatrix4(_m1$3);
11361	        return this;
11362	    }
11363	    lookAt(vector) {
11364	        _obj.lookAt(vector);
11365	        _obj.updateMatrix();
11366	        this.applyMatrix4(_obj.matrix);
11367	        return this;
11368	    }
11369	    center() {
11370	        this.computeBoundingBox();
11371	        this.boundingBox.getCenter(_offset).negate();
11372	        this.translate(_offset.x, _offset.y, _offset.z);
11373	        return this;
11374	    }
11375	    setFromPoints(points) {
11376	        const positionAttribute = this.getAttribute('position');
11377	        if (positionAttribute === undefined) {
11378	            const position = [];
11379	            for(let i = 0, l = points.length; i < l; i++){
11380	                const point = points[i];
11381	                position.push(point.x, point.y, point.z || 0);
11382	            }
11383	            this.setAttribute('position', new Float32BufferAttribute(position, 3));
11384	        } else {
11385	            const l = Math.min(points.length, positionAttribute.count);
vendor: 4,159 bytes, lines 11385-11464
11385 // make sure data do not exceed buffer size
11386	            for(let i = 0; i < l; i++){
11387	                const point = points[i];
11388	                positionAttribute.setXYZ(i, point.x, point.y, point.z || 0);
11389	            }
11390	            if (points.length > positionAttribute.count) {
11391	                console.warn('THREE.BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry.');
11392	            }
11393	            positionAttribute.needsUpdate = true;
11394	        }
11395	        return this;
11396	    }
11397	    computeBoundingBox() {
11398	        if (this.boundingBox === null) {
11399	            this.boundingBox = new Box3();
11400	        }
11401	        const position = this.attributes.position;
11402	        const morphAttributesPosition = this.morphAttributes.position;
11403	        if (position && position.isGLBufferAttribute) {
11404	            console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.', this);
11405	            this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity));
11406	            return;
11407	        }
11408	        if (position !== undefined) {
11409	            this.boundingBox.setFromBufferAttribute(position);
11410	            // process morph attributes if present
11411	            if (morphAttributesPosition) {
11412	                for(let i = 0, il = morphAttributesPosition.length; i < il; i++){
11413	                    const morphAttribute = morphAttributesPosition[i];
11414	                    _box$2.setFromBufferAttribute(morphAttribute);
11415	                    if (this.morphTargetsRelative) {
11416	                        _vector$8.addVectors(this.boundingBox.min, _box$2.min);
11417	                        this.boundingBox.expandByPoint(_vector$8);
11418	                        _vector$8.addVectors(this.boundingBox.max, _box$2.max);
11419	                        this.boundingBox.expandByPoint(_vector$8);
11420	                    } else {
11421	                        this.boundingBox.expandByPoint(_box$2.min);
11422	                        this.boundingBox.expandByPoint(_box$2.max);
11423	                    }
11424	                }
11425	            }
11426	        } else {
11427	            this.boundingBox.makeEmpty();
11428	        }
11429	        if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) {
11430	            console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this);
11431	        }
11432	    }
11433	    computeBoundingSphere() {
11434	        if (this.boundingSphere === null) {
11435	            this.boundingSphere = new Sphere();
11436	        }
11437	        const position = this.attributes.position;
11438	        const morphAttributesPosition = this.morphAttributes.position;
11439	        if (position && position.isGLBufferAttribute) {
11440	            console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.', this);
11441	            this.boundingSphere.set(new Vector3(), Infinity);
11442	            return;
11443	        }
11444	        if (position) {
11445	            // first, find the center of the bounding sphere
11446	            const center = this.boundingSphere.center;
11447	            _box$2.setFromBufferAttribute(position);
11448	            // process morph attributes if present
11449	            if (morphAttributesPosition) {
11450	                for(let i = 0, il = morphAttributesPosition.length; i < il; i++){
11451	                    const morphAttribute = morphAttributesPosition[i];
11452	                    _boxMorphTargets.setFromBufferAttribute(morphAttribute);
11453	                    if (this.morphTargetsRelative) {
11454	                        _vector$8.addVectors(_box$2.min, _boxMorphTargets.min);
11455	                        _box$2.expandByPoint(_vector$8);
11456	                        _vector$8.addVectors(_box$2.max, _boxMorphTargets.max);
11457	                        _box$2.expandByPoint(_vector$8);
11458	                    } else {
11459	                        _box$2.expandByPoint(_boxMorphTargets.min);
11460	                        _box$2.expandByPoint(_boxMorphTargets.max);
11461	                    }
11462	                }
11463	            }
11464	            _box$2.getCenter(center);
vendor: 12,663 bytes, lines 11465-11737
11465	            // second, try to find a boundingSphere with a radius smaller than the
11466	            // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
11467	            let maxRadiusSq = 0;
11468	            for(let i = 0, il = position.count; i < il; i++){
11469	                _vector$8.fromBufferAttribute(position, i);
11470	                maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
11471	            }
11472	            // process morph attributes if present
11473	            if (morphAttributesPosition) {
11474	                for(let i = 0, il = morphAttributesPosition.length; i < il; i++){
11475	                    const morphAttribute = morphAttributesPosition[i];
11476	                    const morphTargetsRelative = this.morphTargetsRelative;
11477	                    for(let j = 0, jl = morphAttribute.count; j < jl; j++){
11478	                        _vector$8.fromBufferAttribute(morphAttribute, j);
11479	                        if (morphTargetsRelative) {
11480	                            _offset.fromBufferAttribute(position, j);
11481	                            _vector$8.add(_offset);
11482	                        }
11483	                        maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
11484	                    }
11485	                }
11486	            }
11487	            this.boundingSphere.radius = Math.sqrt(maxRadiusSq);
11488	            if (isNaN(this.boundingSphere.radius)) {
11489	                console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this);
11490	            }
11491	        }
11492	    }
11493	    computeTangents() {
11494	        const index = this.index;
11495	        const attributes = this.attributes;
11496	        // based on http://www.terathon.com/code/tangent.html
11497	        // (per vertex tangents)
11498	        if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) {
11499	            console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)');
11500	            return;
11501	        }
11502	        const positionAttribute = attributes.position;
11503	        const normalAttribute = attributes.normal;
11504	        const uvAttribute = attributes.uv;
11505	        if (this.hasAttribute('tangent') === false) {
11506	            this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * positionAttribute.count), 4));
11507	        }
11508	        const tangentAttribute = this.getAttribute('tangent');
11509	        const tan1 = [], tan2 = [];
11510	        for(let i = 0; i < positionAttribute.count; i++){
11511	            tan1[i] = new Vector3();
11512	            tan2[i] = new Vector3();
11513	        }
11514	        const vA = new Vector3(), vB = new Vector3(), vC = new Vector3(), uvA = new Vector2(), uvB = new Vector2(), uvC = new Vector2(), sdir = new Vector3(), tdir = new Vector3();
11515	        function handleTriangle(a, b, c) {
11516	            vA.fromBufferAttribute(positionAttribute, a);
11517	            vB.fromBufferAttribute(positionAttribute, b);
11518	            vC.fromBufferAttribute(positionAttribute, c);
11519	            uvA.fromBufferAttribute(uvAttribute, a);
11520	            uvB.fromBufferAttribute(uvAttribute, b);
11521	            uvC.fromBufferAttribute(uvAttribute, c);
11522	            vB.sub(vA);
11523	            vC.sub(vA);
11524	            uvB.sub(uvA);
11525	            uvC.sub(uvA);
11526	            const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y);
11527	            // silently ignore degenerate uv triangles having coincident or colinear vertices
11528	            if (!isFinite(r)) return;
11529	            sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r);
11530	            tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r);
11531	            tan1[a].add(sdir);
11532	            tan1[b].add(sdir);
11533	            tan1[c].add(sdir);
11534	            tan2[a].add(tdir);
11535	            tan2[b].add(tdir);
11536	            tan2[c].add(tdir);
11537	        }
11538	        let groups = this.groups;
11539	        if (groups.length === 0) {
11540	            groups = [
11541	                {
11542	                    start: 0,
11543	                    count: index.count
11544	                }
11545	            ];
11546	        }
11547	        for(let i = 0, il = groups.length; i < il; ++i){
11548	            const group = groups[i];
11549	            const start = group.start;
11550	            const count = group.count;
11551	            for(let j = start, jl = start + count; j < jl; j += 3){
11552	                handleTriangle(index.getX(j + 0), index.getX(j + 1), index.getX(j + 2));
11553	            }
11554	        }
11555	        const tmp = new Vector3(), tmp2 = new Vector3();
11556	        const n = new Vector3(), n2 = new Vector3();
11557	        function handleVertex(v) {
11558	            n.fromBufferAttribute(normalAttribute, v);
11559	            n2.copy(n);
11560	            const t = tan1[v];
11561	            // Gram-Schmidt orthogonalize
11562	            tmp.copy(t);
11563	            tmp.sub(n.multiplyScalar(n.dot(t))).normalize();
11564	            // Calculate handedness
11565	            tmp2.crossVectors(n2, t);
11566	            const test = tmp2.dot(tan2[v]);
11567	            const w = test < 0.0 ? -1 : 1.0;
11568	            tangentAttribute.setXYZW(v, tmp.x, tmp.y, tmp.z, w);
11569	        }
11570	        for(let i = 0, il = groups.length; i < il; ++i){
11571	            const group = groups[i];
11572	            const start = group.start;
11573	            const count = group.count;
11574	            for(let j = start, jl = start + count; j < jl; j += 3){
11575	                handleVertex(index.getX(j + 0));
11576	                handleVertex(index.getX(j + 1));
11577	                handleVertex(index.getX(j + 2));
11578	            }
11579	        }
11580	    }
11581	    computeVertexNormals() {
11582	        const index = this.index;
11583	        const positionAttribute = this.getAttribute('position');
11584	        if (positionAttribute !== undefined) {
11585	            let normalAttribute = this.getAttribute('normal');
11586	            if (normalAttribute === undefined) {
11587	                normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3);
11588	                this.setAttribute('normal', normalAttribute);
11589	            } else {
11590	                // reset existing normals to zero
11591	                for(let i = 0, il = normalAttribute.count; i < il; i++){
11592	                    normalAttribute.setXYZ(i, 0, 0, 0);
11593	                }
11594	            }
11595	            const pA = new Vector3(), pB = new Vector3(), pC = new Vector3();
11596	            const nA = new Vector3(), nB = new Vector3(), nC = new Vector3();
11597	            const cb = new Vector3(), ab = new Vector3();
11598	            // indexed elements
11599	            if (index) {
11600	                for(let i = 0, il = index.count; i < il; i += 3){
11601	                    const vA = index.getX(i + 0);
11602	                    const vB = index.getX(i + 1);
11603	                    const vC = index.getX(i + 2);
11604	                    pA.fromBufferAttribute(positionAttribute, vA);
11605	                    pB.fromBufferAttribute(positionAttribute, vB);
11606	                    pC.fromBufferAttribute(positionAttribute, vC);
11607	                    cb.subVectors(pC, pB);
11608	                    ab.subVectors(pA, pB);
11609	                    cb.cross(ab);
11610	                    nA.fromBufferAttribute(normalAttribute, vA);
11611	                    nB.fromBufferAttribute(normalAttribute, vB);
11612	                    nC.fromBufferAttribute(normalAttribute, vC);
11613	                    nA.add(cb);
11614	                    nB.add(cb);
11615	                    nC.add(cb);
11616	                    normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z);
11617	                    normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z);
11618	                    normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z);
11619	                }
11620	            } else {
11621	                // non-indexed elements (unconnected triangle soup)
11622	                for(let i = 0, il = positionAttribute.count; i < il; i += 3){
11623	                    pA.fromBufferAttribute(positionAttribute, i + 0);
11624	                    pB.fromBufferAttribute(positionAttribute, i + 1);
11625	                    pC.fromBufferAttribute(positionAttribute, i + 2);
11626	                    cb.subVectors(pC, pB);
11627	                    ab.subVectors(pA, pB);
11628	                    cb.cross(ab);
11629	                    normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z);
11630	                    normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z);
11631	                    normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z);
11632	                }
11633	            }
11634	            this.normalizeNormals();
11635	            normalAttribute.needsUpdate = true;
11636	        }
11637	    }
11638	    normalizeNormals() {
11639	        const normals = this.attributes.normal;
11640	        for(let i = 0, il = normals.count; i < il; i++){
11641	            _vector$8.fromBufferAttribute(normals, i);
11642	            _vector$8.normalize();
11643	            normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z);
11644	        }
11645	    }
11646	    toNonIndexed() {
11647	        function convertBufferAttribute(attribute, indices) {
11648	            const array = attribute.array;
11649	            const itemSize = attribute.itemSize;
11650	            const normalized = attribute.normalized;
11651	            const array2 = new array.constructor(indices.length * itemSize);
11652	            let index = 0, index2 = 0;
11653	            for(let i = 0, l = indices.length; i < l; i++){
11654	                if (attribute.isInterleavedBufferAttribute) {
11655	                    index = indices[i] * attribute.data.stride + attribute.offset;
11656	                } else {
11657	                    index = indices[i] * itemSize;
11658	                }
11659	                for(let j = 0; j < itemSize; j++){
11660	                    array2[index2++] = array[index++];
11661	                }
11662	            }
11663	            return new BufferAttribute(array2, itemSize, normalized);
11664	        }
11665	        //
11666	        if (this.index === null) {
11667	            console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.');
11668	            return this;
11669	        }
11670	        const geometry2 = new BufferGeometry();
11671	        const indices = this.index.array;
11672	        const attributes = this.attributes;
11673	        // attributes
11674	        for(const name in attributes){
11675	            const attribute = attributes[name];
11676	            const newAttribute = convertBufferAttribute(attribute, indices);
11677	            geometry2.setAttribute(name, newAttribute);
11678	        }
11679	        // morph attributes
11680	        const morphAttributes = this.morphAttributes;
11681	        for(const name in morphAttributes){
11682	            const morphArray = [];
11683	            const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
11684	            for(let i = 0, il = morphAttribute.length; i < il; i++){
11685	                const attribute = morphAttribute[i];
11686	                const newAttribute = convertBufferAttribute(attribute, indices);
11687	                morphArray.push(newAttribute);
11688	            }
11689	            geometry2.morphAttributes[name] = morphArray;
11690	        }
11691	        geometry2.morphTargetsRelative = this.morphTargetsRelative;
11692	        // groups
11693	        const groups = this.groups;
11694	        for(let i = 0, l = groups.length; i < l; i++){
11695	            const group = groups[i];
11696	            geometry2.addGroup(group.start, group.count, group.materialIndex);
11697	        }
11698	        return geometry2;
11699	    }
11700	    toJSON() {
11701	        const data = {
11702	            metadata: {
11703	                version: 4.6,
11704	                type: 'BufferGeometry',
11705	                generator: 'BufferGeometry.toJSON'
11706	            }
11707	        };
11708	        // standard BufferGeometry serialization
11709	        data.uuid = this.uuid;
11710	        data.type = this.type;
11711	        if (this.name !== '') data.name = this.name;
11712	        if (Object.keys(this.userData).length > 0) data.userData = this.userData;
11713	        if (this.parameters !== undefined) {
11714	            const parameters = this.parameters;
11715	            for(const key in parameters){
11716	                if (parameters[key] !== undefined) data[key] = parameters[key];
11717	            }
11718	            return data;
11719	        }
11720	        // for simplicity the code assumes attributes are not shared across geometries, see #15811
11721	        data.data = {
11722	            attributes: {}
11723	        };
11724	        const index = this.index;
11725	        if (index !== null) {
11726	            data.data.index = {
11727	                type: index.array.constructor.name,
11728	                array: Array.prototype.slice.call(index.array)
11729	            };
11730	        }
11731	        const attributes = this.attributes;
11732	        for(const key in attributes){
11733	            const attribute = attributes[key];
11734	            data.data.attributes[key] = attribute.toJSON(data.data);
11735	        }
11736	        const morphAttributes = {};
11737	        let hasMorphAttributes = false;
vendor: 5,811 bytes, lines 11738-11896
11738	        for(const key in this.morphAttributes){
11739	            const attributeArray = this.morphAttributes[key];
11740	            const array = [];
11741	            for(let i = 0, il = attributeArray.length; i < il; i++){
11742	                const attribute = attributeArray[i];
11743	                array.push(attribute.toJSON(data.data));
11744	            }
11745	            if (array.length > 0) {
11746	                morphAttributes[key] = array;
11747	                hasMorphAttributes = true;
11748	            }
11749	        }
11750	        if (hasMorphAttributes) {
11751	            data.data.morphAttributes = morphAttributes;
11752	            data.data.morphTargetsRelative = this.morphTargetsRelative;
11753	        }
11754	        const groups = this.groups;
11755	        if (groups.length > 0) {
11756	            data.data.groups = JSON.parse(JSON.stringify(groups));
11757	        }
11758	        const boundingSphere = this.boundingSphere;
11759	        if (boundingSphere !== null) {
11760	            data.data.boundingSphere = {
11761	                center: boundingSphere.center.toArray(),
11762	                radius: boundingSphere.radius
11763	            };
11764	        }
11765	        return data;
11766	    }
11767	    clone() {
11768	        return new this.constructor().copy(this);
11769	    }
11770	    copy(source) {
11771	        // reset
11772	        this.index = null;
11773	        this.attributes = {};
11774	        this.morphAttributes = {};
11775	        this.groups = [];
11776	        this.boundingBox = null;
11777	        this.boundingSphere = null;
11778	        // used for storing cloned, shared data
11779	        const data = {};
11780	        // name
11781	        this.name = source.name;
11782	        // index
11783	        const index = source.index;
11784	        if (index !== null) {
11785	            this.setIndex(index.clone(data));
11786	        }
11787	        // attributes
11788	        const attributes = source.attributes;
11789	        for(const name in attributes){
11790	            const attribute = attributes[name];
11791	            this.setAttribute(name, attribute.clone(data));
11792	        }
11793	        // morph attributes
11794	        const morphAttributes = source.morphAttributes;
11795	        for(const name in morphAttributes){
11796	            const array = [];
11797	            const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
11798	            for(let i = 0, l = morphAttribute.length; i < l; i++){
11799	                array.push(morphAttribute[i].clone(data));
11800	            }
11801	            this.morphAttributes[name] = array;
11802	        }
11803	        this.morphTargetsRelative = source.morphTargetsRelative;
11804	        // groups
11805	        const groups = source.groups;
11806	        for(let i = 0, l = groups.length; i < l; i++){
11807	            const group = groups[i];
11808	            this.addGroup(group.start, group.count, group.materialIndex);
11809	        }
11810	        // bounding box
11811	        const boundingBox = source.boundingBox;
11812	        if (boundingBox !== null) {
11813	            this.boundingBox = boundingBox.clone();
11814	        }
11815	        // bounding sphere
11816	        const boundingSphere = source.boundingSphere;
11817	        if (boundingSphere !== null) {
11818	            this.boundingSphere = boundingSphere.clone();
11819	        }
11820	        // draw range
11821	        this.drawRange.start = source.drawRange.start;
11822	        this.drawRange.count = source.drawRange.count;
11823	        // user data
11824	        this.userData = source.userData;
11825	        return this;
11826	    }
11827	    dispose() {
11828	        this.dispatchEvent({
11829	            type: 'dispose'
11830	        });
11831	    }
11832	    constructor(){
11833	        super();
11834	        this.isBufferGeometry = true;
11835	        Object.defineProperty(this, 'id', {
11836	            value: _id$1++
11837	        });
11838	        this.uuid = generateUUID();
11839	        this.name = '';
11840	        this.type = 'BufferGeometry';
11841	        this.index = null;
11842	        this.indirect = null;
11843	        this.attributes = {};
11844	        this.morphAttributes = {};
11845	        this.morphTargetsRelative = false;
11846	        this.groups = [];
11847	        this.boundingBox = null;
11848	        this.boundingSphere = null;
11849	        this.drawRange = {
11850	            start: 0,
11851	            count: Infinity
11852	        };
11853	        this.userData = {};
11854	    }
11855	}
11856	const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4();
11857	const _ray$3 = /*@__PURE__*/ new Ray();
11858	const _sphere$6 = /*@__PURE__*/ new Sphere();
11859	const _sphereHitAt = /*@__PURE__*/ new Vector3();
11860	const _vA$1 = /*@__PURE__*/ new Vector3();
11861	const _vB$1 = /*@__PURE__*/ new Vector3();
11862	const _vC$1 = /*@__PURE__*/ new Vector3();
11863	const _tempA = /*@__PURE__*/ new Vector3();
11864	const _morphA = /*@__PURE__*/ new Vector3();
11865	const _intersectionPoint = /*@__PURE__*/ new Vector3();
11866	const _intersectionPointWorld = /*@__PURE__*/ new Vector3();
11867	/**
11868	 * Class representing triangular polygon mesh based objects.
11869	 *
11870	 * ```js
11871	 * const geometry = new THREE.BoxGeometry( 1, 1, 1 );
11872	 * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
11873	 * const mesh = new THREE.Mesh( geometry, material );
11874	 * scene.add( mesh );
11875	 * ```
11876	 *
11877	 * @augments Object3D
11878	 */ class Mesh extends Object3D {
11879	    copy(source, recursive) {
11880	        super.copy(source, recursive);
11881	        if (source.morphTargetInfluences !== undefined) {
11882	            this.morphTargetInfluences = source.morphTargetInfluences.slice();
11883	        }
11884	        if (source.morphTargetDictionary !== undefined) {
11885	            this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary);
11886	        }
11887	        this.material = Array.isArray(source.material) ? source.material.slice() : source.material;
11888	        this.geometry = source.geometry;
11889	        return this;
11890	    }
11891	    /**
11892		 * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences}
11893		 * to make sure existing morph targets can influence this 3D object.
11894		 */ updateMorphTargets() {
11895	        const geometry = this.geometry;
11896	        const morphAttributes = geometry.morphAttributes;
vendor: 28,356 bytes, lines 11897-12564
11897	        const keys = Object.keys(morphAttributes);
11898	        if (keys.length > 0) {
11899	            const morphAttribute = morphAttributes[keys[0]];
11900	            if (morphAttribute !== undefined) {
11901	                this.morphTargetInfluences = [];
11902	                this.morphTargetDictionary = {};
11903	                for(let m = 0, ml = morphAttribute.length; m < ml; m++){
11904	                    const name = morphAttribute[m].name || String(m);
11905	                    this.morphTargetInfluences.push(0);
11906	                    this.morphTargetDictionary[name] = m;
11907	                }
11908	            }
11909	        }
11910	    }
11911	    /**
11912		 * Returns the local-space position of the vertex at the given index, taking into
11913		 * account the current animation state of both morph targets and skinning.
11914		 *
11915		 * @param {number} index - The vertex index.
11916		 * @param {Vector3} target - The target object that is used to store the method's result.
11917		 * @return {Vector3} The vertex position in local space.
11918		 */ getVertexPosition(index, target) {
11919	        const geometry = this.geometry;
11920	        const position = geometry.attributes.position;
11921	        const morphPosition = geometry.morphAttributes.position;
11922	        const morphTargetsRelative = geometry.morphTargetsRelative;
11923	        target.fromBufferAttribute(position, index);
11924	        const morphInfluences = this.morphTargetInfluences;
11925	        if (morphPosition && morphInfluences) {
11926	            _morphA.set(0, 0, 0);
11927	            for(let i = 0, il = morphPosition.length; i < il; i++){
11928	                const influence = morphInfluences[i];
11929	                const morphAttribute = morphPosition[i];
11930	                if (influence === 0) continue;
11931	                _tempA.fromBufferAttribute(morphAttribute, index);
11932	                if (morphTargetsRelative) {
11933	                    _morphA.addScaledVector(_tempA, influence);
11934	                } else {
11935	                    _morphA.addScaledVector(_tempA.sub(target), influence);
11936	                }
11937	            }
11938	            target.add(_morphA);
11939	        }
11940	        return target;
11941	    }
11942	    /**
11943		 * Computes intersection points between a casted ray and this line.
11944		 *
11945		 * @param {Raycaster} raycaster - The raycaster.
11946		 * @param {Array<Object>} intersects - The target array that holds the intersection points.
11947		 */ raycast(raycaster, intersects) {
11948	        const geometry = this.geometry;
11949	        const material = this.material;
11950	        const matrixWorld = this.matrixWorld;
11951	        if (material === undefined) return;
11952	        // test with bounding sphere in world space
11953	        if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
11954	        _sphere$6.copy(geometry.boundingSphere);
11955	        _sphere$6.applyMatrix4(matrixWorld);
11956	        // check distance from ray origin to bounding sphere
11957	        _ray$3.copy(raycaster.ray).recast(raycaster.near);
11958	        if (_sphere$6.containsPoint(_ray$3.origin) === false) {
11959	            if (_ray$3.intersectSphere(_sphere$6, _sphereHitAt) === null) return;
11960	            if (_ray$3.origin.distanceToSquared(_sphereHitAt) > (raycaster.far - raycaster.near) ** 2) return;
11961	        }
11962	        // convert ray to local space of mesh
11963	        _inverseMatrix$3.copy(matrixWorld).invert();
11964	        _ray$3.copy(raycaster.ray).applyMatrix4(_inverseMatrix$3);
11965	        // test with bounding box in local space
11966	        if (geometry.boundingBox !== null) {
11967	            if (_ray$3.intersectsBox(geometry.boundingBox) === false) return;
11968	        }
11969	        // test for intersections with geometry
11970	        this._computeIntersections(raycaster, intersects, _ray$3);
11971	    }
11972	    _computeIntersections(raycaster, intersects, rayLocalSpace) {
11973	        let intersection;
11974	        const geometry = this.geometry;
11975	        const material = this.material;
11976	        const index = geometry.index;
11977	        const position = geometry.attributes.position;
11978	        const uv = geometry.attributes.uv;
11979	        const uv1 = geometry.attributes.uv1;
11980	        const normal = geometry.attributes.normal;
11981	        const groups = geometry.groups;
11982	        const drawRange = geometry.drawRange;
11983	        if (index !== null) {
11984	            // indexed buffer geometry
11985	            if (Array.isArray(material)) {
11986	                for(let i = 0, il = groups.length; i < il; i++){
11987	                    const group = groups[i];
11988	                    const groupMaterial = material[group.materialIndex];
11989	                    const start = Math.max(group.start, drawRange.start);
11990	                    const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
11991	                    for(let j = start, jl = end; j < jl; j += 3){
11992	                        const a = index.getX(j);
11993	                        const b = index.getX(j + 1);
11994	                        const c = index.getX(j + 2);
11995	                        intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c);
11996	                        if (intersection) {
11997	                            intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics
11998	                            intersection.face.materialIndex = group.materialIndex;
11999	                            intersects.push(intersection);
12000	                        }
12001	                    }
12002	                }
12003	            } else {
12004	                const start = Math.max(0, drawRange.start);
12005	                const end = Math.min(index.count, drawRange.start + drawRange.count);
12006	                for(let i = start, il = end; i < il; i += 3){
12007	                    const a = index.getX(i);
12008	                    const b = index.getX(i + 1);
12009	                    const c = index.getX(i + 2);
12010	                    intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c);
12011	                    if (intersection) {
12012	                        intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics
12013	                        intersects.push(intersection);
12014	                    }
12015	                }
12016	            }
12017	        } else if (position !== undefined) {
12018	            // non-indexed buffer geometry
12019	            if (Array.isArray(material)) {
12020	                for(let i = 0, il = groups.length; i < il; i++){
12021	                    const group = groups[i];
12022	                    const groupMaterial = material[group.materialIndex];
12023	                    const start = Math.max(group.start, drawRange.start);
12024	                    const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
12025	                    for(let j = start, jl = end; j < jl; j += 3){
12026	                        const a = j;
12027	                        const b = j + 1;
12028	                        const c = j + 2;
12029	                        intersection = checkGeometryIntersection(this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c);
12030	                        if (intersection) {
12031	                            intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics
12032	                            intersection.face.materialIndex = group.materialIndex;
12033	                            intersects.push(intersection);
12034	                        }
12035	                    }
12036	                }
12037	            } else {
12038	                const start = Math.max(0, drawRange.start);
12039	                const end = Math.min(position.count, drawRange.start + drawRange.count);
12040	                for(let i = start, il = end; i < il; i += 3){
12041	                    const a = i;
12042	                    const b = i + 1;
12043	                    const c = i + 2;
12044	                    intersection = checkGeometryIntersection(this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c);
12045	                    if (intersection) {
12046	                        intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics
12047	                        intersects.push(intersection);
12048	                    }
12049	                }
12050	            }
12051	        }
12052	    }
12053	    /**
12054		 * Constructs a new mesh.
12055		 *
12056		 * @param {BufferGeometry} [geometry] - The mesh geometry.
12057		 * @param {Material|Array<Material>} [material] - The mesh material.
12058		 */ constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()){
12059	        super();
12060	        /**
12061			 * This flag can be used for type testing.
12062			 *
12063			 * @type {boolean}
12064			 * @readonly
12065			 * @default true
12066			 */ this.isMesh = true;
12067	        this.type = 'Mesh';
12068	        /**
12069			 * The mesh geometry.
12070			 *
12071			 * @type {BufferGeometry}
12072			 */ this.geometry = geometry;
12073	        /**
12074			 * The mesh material.
12075			 *
12076			 * @type {Material|Array<Material>}
12077			 * @default MeshBasicMaterial
12078			 */ this.material = material;
12079	        /**
12080			 * A dictionary representing the morph targets in the geometry. The key is the
12081			 * morph targets name, the value its attribute index. This member is `undefined`
12082			 * by default and only set when morph targets are detected in the geometry.
12083			 *
12084			 * @type {Object<String,number>|undefined}
12085			 * @default undefined
12086			 */ this.morphTargetDictionary = undefined;
12087	        /**
12088			 * An array of weights typically in the range `[0,1]` that specify how much of the morph
12089			 * is applied. This member is `undefined` by default and only set when morph targets are
12090			 * detected in the geometry.
12091			 *
12092			 * @type {Array<number>|undefined}
12093			 * @default undefined
12094			 */ this.morphTargetInfluences = undefined;
12095	        this.updateMorphTargets();
12096	    }
12097	}
12098	function checkIntersection$1(object, material, raycaster, ray, pA, pB, pC, point) {
12099	    let intersect;
12100	    if (material.side === BackSide) {
12101	        intersect = ray.intersectTriangle(pC, pB, pA, true, point);
12102	    } else {
12103	        intersect = ray.intersectTriangle(pA, pB, pC, material.side === FrontSide, point);
12104	    }
12105	    if (intersect === null) return null;
12106	    _intersectionPointWorld.copy(point);
12107	    _intersectionPointWorld.applyMatrix4(object.matrixWorld);
12108	    const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld);
12109	    if (distance < raycaster.near || distance > raycaster.far) return null;
12110	    return {
12111	        distance: distance,
12112	        point: _intersectionPointWorld.clone(),
12113	        object: object
12114	    };
12115	}
12116	function checkGeometryIntersection(object, material, raycaster, ray, uv, uv1, normal, a, b, c) {
12117	    object.getVertexPosition(a, _vA$1);
12118	    object.getVertexPosition(b, _vB$1);
12119	    object.getVertexPosition(c, _vC$1);
12120	    const intersection = checkIntersection$1(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint);
12121	    if (intersection) {
12122	        const barycoord = new Vector3();
12123	        Triangle.getBarycoord(_intersectionPoint, _vA$1, _vB$1, _vC$1, barycoord);
12124	        if (uv) {
12125	            intersection.uv = Triangle.getInterpolatedAttribute(uv, a, b, c, barycoord, new Vector2());
12126	        }
12127	        if (uv1) {
12128	            intersection.uv1 = Triangle.getInterpolatedAttribute(uv1, a, b, c, barycoord, new Vector2());
12129	        }
12130	        if (normal) {
12131	            intersection.normal = Triangle.getInterpolatedAttribute(normal, a, b, c, barycoord, new Vector3());
12132	            if (intersection.normal.dot(ray.direction) > 0) {
12133	                intersection.normal.multiplyScalar(-1);
12134	            }
12135	        }
12136	        const face = {
12137	            a: a,
12138	            b: b,
12139	            c: c,
12140	            normal: new Vector3(),
12141	            materialIndex: 0
12142	        };
12143	        Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal);
12144	        intersection.face = face;
12145	        intersection.barycoord = barycoord;
12146	    }
12147	    return intersection;
12148	}
12149	/**
12150	 * A geometry class for a rectangular cuboid with a given width, height, and depth.
12151	 * On creation, the cuboid is centred on the origin, with each edge parallel to one
12152	 * of the axes.
12153	 *
12154	 * ```js
12155	 * const geometry = new THREE.BoxGeometry( 1, 1, 1 );
12156	 * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
12157	 * const cube = new THREE.Mesh( geometry, material );
12158	 * scene.add( cube );
12159	 * ```
12160	 *
12161	 * @augments BufferGeometry
12162	 */ class BoxGeometry extends BufferGeometry {
12163	    copy(source) {
12164	        super.copy(source);
12165	        this.parameters = Object.assign({}, source.parameters);
12166	        return this;
12167	    }
12168	    /**
12169		 * Factory method for creating an instance of this class from the given
12170		 * JSON object.
12171		 *
12172		 * @param {Object} data - A JSON object representing the serialized geometry.
12173		 * @return {BoxGeometry} A new instance.
12174		 */ static fromJSON(data) {
12175	        return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments);
12176	    }
12177	    /**
12178		 * Constructs a new box geometry.
12179		 *
12180		 * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis.
12181		 * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis.
12182		 * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis.
12183		 * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides.
12184		 * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides.
12185		 * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides.
12186		 */ constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1){
12187	        super();
12188	        this.type = 'BoxGeometry';
12189	        /**
12190			 * Holds the constructor parameters that have been
12191			 * used to generate the geometry. Any modification
12192			 * after instantiation does not change the geometry.
12193			 *
12194			 * @type {Object}
12195			 */ this.parameters = {
12196	            width: width,
12197	            height: height,
12198	            depth: depth,
12199	            widthSegments: widthSegments,
12200	            heightSegments: heightSegments,
12201	            depthSegments: depthSegments
12202	        };
12203	        const scope = this;
12204	        // segments
12205	        widthSegments = Math.floor(widthSegments);
12206	        heightSegments = Math.floor(heightSegments);
12207	        depthSegments = Math.floor(depthSegments);
12208	        // buffers
12209	        const indices = [];
12210	        const vertices = [];
12211	        const normals = [];
12212	        const uvs = [];
12213	        // helper variables
12214	        let numberOfVertices = 0;
12215	        let groupStart = 0;
12216	        // build each side of the box geometry
12217	        buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px
12218	        buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx
12219	        buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py
12220	        buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny
12221	        buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz
12222	        buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz
12223	        // build geometry
12224	        this.setIndex(indices);
12225	        this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
12226	        this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
12227	        this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
12228	        function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) {
12229	            const segmentWidth = width / gridX;
12230	            const segmentHeight = height / gridY;
12231	            const widthHalf = width / 2;
12232	            const heightHalf = height / 2;
12233	            const depthHalf = depth / 2;
12234	            const gridX1 = gridX + 1;
12235	            const gridY1 = gridY + 1;
12236	            let vertexCounter = 0;
12237	            let groupCount = 0;
12238	            const vector = new Vector3();
12239	            // generate vertices, normals and uvs
12240	            for(let iy = 0; iy < gridY1; iy++){
12241	                const y = iy * segmentHeight - heightHalf;
12242	                for(let ix = 0; ix < gridX1; ix++){
12243	                    const x = ix * segmentWidth - widthHalf;
12244	                    // set values to correct vector component
12245	                    vector[u] = x * udir;
12246	                    vector[v] = y * vdir;
12247	                    vector[w] = depthHalf;
12248	                    // now apply vector to vertex buffer
12249	                    vertices.push(vector.x, vector.y, vector.z);
12250	                    // set values to correct vector component
12251	                    vector[u] = 0;
12252	                    vector[v] = 0;
12253	                    vector[w] = depth > 0 ? 1 : -1;
12254	                    // now apply vector to normal buffer
12255	                    normals.push(vector.x, vector.y, vector.z);
12256	                    // uvs
12257	                    uvs.push(ix / gridX);
12258	                    uvs.push(1 - iy / gridY);
12259	                    // counters
12260	                    vertexCounter += 1;
12261	                }
12262	            }
12263	            // indices
12264	            // 1. you need three indices to draw a single face
12265	            // 2. a single segment consists of two faces
12266	            // 3. so we need to generate six (2*3) indices per segment
12267	            for(let iy = 0; iy < gridY; iy++){
12268	                for(let ix = 0; ix < gridX; ix++){
12269	                    const a = numberOfVertices + ix + gridX1 * iy;
12270	                    const b = numberOfVertices + ix + gridX1 * (iy + 1);
12271	                    const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1);
12272	                    const d = numberOfVertices + (ix + 1) + gridX1 * iy;
12273	                    // faces
12274	                    indices.push(a, b, d);
12275	                    indices.push(b, c, d);
12276	                    // increase counter
12277	                    groupCount += 6;
12278	                }
12279	            }
12280	            // add a group to the geometry. this will ensure multi material support
12281	            scope.addGroup(groupStart, groupCount, materialIndex);
12282	            // calculate new start value for groups
12283	            groupStart += groupCount;
12284	            // update total number of vertices
12285	            numberOfVertices += vertexCounter;
12286	        }
12287	    }
12288	}
12289	/**
12290	 * Uniform Utilities
12291	 */ function cloneUniforms(src) {
12292	    const dst = {};
12293	    for(const u in src){
12294	        dst[u] = {};
12295	        for(const p in src[u]){
12296	            const property = src[u][p];
12297	            if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) {
12298	                if (property.isRenderTargetTexture) {
12299	                    console.warn('UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().');
12300	                    dst[u][p] = null;
12301	                } else {
12302	                    dst[u][p] = property.clone();
12303	                }
12304	            } else if (Array.isArray(property)) {
12305	                dst[u][p] = property.slice();
12306	            } else {
12307	                dst[u][p] = property;
12308	            }
12309	        }
12310	    }
12311	    return dst;
12312	}
12313	function mergeUniforms(uniforms) {
12314	    const merged = {};
12315	    for(let u = 0; u < uniforms.length; u++){
12316	        const tmp = cloneUniforms(uniforms[u]);
12317	        for(const p in tmp){
12318	            merged[p] = tmp[p];
12319	        }
12320	    }
12321	    return merged;
12322	}
12323	function cloneUniformsGroups(src) {
12324	    const dst = [];
12325	    for(let u = 0; u < src.length; u++){
12326	        dst.push(src[u].clone());
12327	    }
12328	    return dst;
12329	}
12330	function getUnlitUniformColorSpace(renderer) {
12331	    const currentRenderTarget = renderer.getRenderTarget();
12332	    if (currentRenderTarget === null) {
12333	        // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398
12334	        return renderer.outputColorSpace;
12335	    }
12336	    // https://github.com/mrdoob/three.js/issues/27868
12337	    if (currentRenderTarget.isXRRenderTarget === true) {
12338	        return currentRenderTarget.texture.colorSpace;
12339	    }
12340	    return ColorManagement.workingColorSpace;
12341	}
12342	// Legacy
12343	const UniformsUtils = {
12344	    clone: cloneUniforms,
12345	    merge: mergeUniforms
12346	};
12347	var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
12348	var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
12349	class ShaderMaterial extends Material$1 {
12350	    copy(source) {
12351	        super.copy(source);
12352	        this.fragmentShader = source.fragmentShader;
12353	        this.vertexShader = source.vertexShader;
12354	        this.uniforms = cloneUniforms(source.uniforms);
12355	        this.uniformsGroups = cloneUniformsGroups(source.uniformsGroups);
12356	        this.defines = Object.assign({}, source.defines);
12357	        this.wireframe = source.wireframe;
12358	        this.wireframeLinewidth = source.wireframeLinewidth;
12359	        this.fog = source.fog;
12360	        this.lights = source.lights;
12361	        this.clipping = source.clipping;
12362	        this.extensions = Object.assign({}, source.extensions);
12363	        this.glslVersion = source.glslVersion;
12364	        return this;
12365	    }
12366	    toJSON(meta) {
12367	        const data = super.toJSON(meta);
12368	        data.glslVersion = this.glslVersion;
12369	        data.uniforms = {};
12370	        for(const name in this.uniforms){
12371	            const uniform = this.uniforms[name];
12372	            const value = uniform.value;
12373	            if (value && value.isTexture) {
12374	                data.uniforms[name] = {
12375	                    type: 't',
12376	                    value: value.toJSON(meta).uuid
12377	                };
12378	            } else if (value && value.isColor) {
12379	                data.uniforms[name] = {
12380	                    type: 'c',
12381	                    value: value.getHex()
12382	                };
12383	            } else if (value && value.isVector2) {
12384	                data.uniforms[name] = {
12385	                    type: 'v2',
12386	                    value: value.toArray()
12387	                };
12388	            } else if (value && value.isVector3) {
12389	                data.uniforms[name] = {
12390	                    type: 'v3',
12391	                    value: value.toArray()
12392	                };
12393	            } else if (value && value.isVector4) {
12394	                data.uniforms[name] = {
12395	                    type: 'v4',
12396	                    value: value.toArray()
12397	                };
12398	            } else if (value && value.isMatrix3) {
12399	                data.uniforms[name] = {
12400	                    type: 'm3',
12401	                    value: value.toArray()
12402	                };
12403	            } else if (value && value.isMatrix4) {
12404	                data.uniforms[name] = {
12405	                    type: 'm4',
12406	                    value: value.toArray()
12407	                };
12408	            } else {
12409	                data.uniforms[name] = {
12410	                    value: value
12411	                };
12412	            // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
12413	            }
12414	        }
12415	        if (Object.keys(this.defines).length > 0) data.defines = this.defines;
12416	        data.vertexShader = this.vertexShader;
12417	        data.fragmentShader = this.fragmentShader;
12418	        data.lights = this.lights;
12419	        data.clipping = this.clipping;
12420	        const extensions = {};
12421	        for(const key in this.extensions){
12422	            if (this.extensions[key] === true) extensions[key] = true;
12423	        }
12424	        if (Object.keys(extensions).length > 0) data.extensions = extensions;
12425	        return data;
12426	    }
12427	    constructor(parameters){
12428	        super();
12429	        this.isShaderMaterial = true;
12430	        this.type = 'ShaderMaterial';
12431	        this.defines = {};
12432	        this.uniforms = {};
12433	        this.uniformsGroups = [];
12434	        this.vertexShader = default_vertex;
12435	        this.fragmentShader = default_fragment;
12436	        this.linewidth = 1;
12437	        this.wireframe = false;
12438	        this.wireframeLinewidth = 1;
12439	        this.fog = false; // set to use scene fog
12440	        this.lights = false; // set to use scene lights
12441	        this.clipping = false; // set to use user-defined clipping planes
12442	        this.forceSinglePass = true;
12443	        this.extensions = {
12444	            clipCullDistance: false,
12445	            multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID
12446	        };
12447	        // When rendered geometry doesn't include these attributes but the material does,
12448	        // use these default values in WebGL. This avoids errors when buffer data is missing.
12449	        this.defaultAttributeValues = {
12450	            'color': [
12451	                1,
12452	                1,
12453	                1
12454	            ],
12455	            'uv': [
12456	                0,
12457	                0
12458	            ],
12459	            'uv1': [
12460	                0,
12461	                0
12462	            ]
12463	        };
12464	        this.index0AttributeName = undefined;
12465	        this.uniformsNeedUpdate = false;
12466	        this.glslVersion = null;
12467	        if (parameters !== undefined) {
12468	            this.setValues(parameters);
12469	        }
12470	    }
12471	}
12472	/**
12473	 * Abstract base class for cameras. This class should always be inherited
12474	 * when you build a new camera.
12475	 *
12476	 * @abstract
12477	 * @augments Object3D
12478	 */ class Camera extends Object3D {
12479	    copy(source, recursive) {
12480	        super.copy(source, recursive);
12481	        this.matrixWorldInverse.copy(source.matrixWorldInverse);
12482	        this.projectionMatrix.copy(source.projectionMatrix);
12483	        this.projectionMatrixInverse.copy(source.projectionMatrixInverse);
12484	        this.coordinateSystem = source.coordinateSystem;
12485	        return this;
12486	    }
12487	    /**
12488		 * Returns a vector representing the ("look") direction of the 3D object in world space.
12489		 *
12490		 * This method is overwritten since cameras have a different forward vector compared to other
12491		 * 3D objects. A camera looks down its local, negative z-axis by default.
12492		 *
12493		 * @param {Vector3} target - The target vector the result is stored to.
12494		 * @return {Vector3} The 3D object's direction in world space.
12495		 */ getWorldDirection(target) {
12496	        return super.getWorldDirection(target).negate();
12497	    }
12498	    updateMatrixWorld(force) {
12499	        super.updateMatrixWorld(force);
12500	        this.matrixWorldInverse.copy(this.matrixWorld).invert();
12501	    }
12502	    updateWorldMatrix(updateParents, updateChildren) {
12503	        super.updateWorldMatrix(updateParents, updateChildren);
12504	        this.matrixWorldInverse.copy(this.matrixWorld).invert();
12505	    }
12506	    clone() {
12507	        return new this.constructor().copy(this);
12508	    }
12509	    /**
12510		 * Constructs a new camera.
12511		 */ constructor(){
12512	        super();
12513	        /**
12514			 * This flag can be used for type testing.
12515			 *
12516			 * @type {boolean}
12517			 * @readonly
12518			 * @default true
12519			 */ this.isCamera = true;
12520	        this.type = 'Camera';
12521	        /**
12522			 * The inverse of the camera's world matrix.
12523			 *
12524			 * @type {Matrix4}
12525			 */ this.matrixWorldInverse = new Matrix4();
12526	        /**
12527			 * The camera's projection matrix.
12528			 *
12529			 * @type {Matrix4}
12530			 */ this.projectionMatrix = new Matrix4();
12531	        /**
12532			 * The inverse of the camera's projection matrix.
12533			 *
12534			 * @type {Matrix4}
12535			 */ this.projectionMatrixInverse = new Matrix4();
12536	        /**
12537			 * The coordinate system in which the camera is used.
12538			 *
12539			 * @type {(WebGLCoordinateSystem|WebGPUCoordinateSystem)}
12540			 */ this.coordinateSystem = WebGLCoordinateSystem;
12541	    }
12542	}
12543	const _v3$1 = /*@__PURE__*/ new Vector3();
12544	const _minTarget = /*@__PURE__*/ new Vector2();
12545	const _maxTarget = /*@__PURE__*/ new Vector2();
12546	/**
12547	 * Camera that uses [perspective projection]{@link https://en.wikipedia.org/wiki/Perspective_(graphical)}.
12548	 *
12549	 * This projection mode is designed to mimic the way the human eye sees. It
12550	 * is the most common projection mode used for rendering a 3D scene.
12551	 *
12552	 * ```js
12553	 * const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
12554	 * scene.add( camera );
12555	 * ```
12556	 *
12557	 * @augments Camera
12558	 */ class PerspectiveCamera extends Camera {
12559	    copy(source, recursive) {
12560	        super.copy(source, recursive);
12561	        this.fov = source.fov;
12562	        this.zoom = source.zoom;
12563	        this.near = source.near;
12564	        this.far = source.far;
vendor: 6,152 bytes, lines 12565-12709
12565	        this.focus = source.focus;
12566	        this.aspect = source.aspect;
12567	        this.view = source.view === null ? null : Object.assign({}, source.view);
12568	        this.filmGauge = source.filmGauge;
12569	        this.filmOffset = source.filmOffset;
12570	        return this;
12571	    }
12572	    /**
12573		 * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}.
12574		 *
12575		 * The default film gauge is 35, so that the focal length can be specified for
12576		 * a 35mm (full frame) camera.
12577		 *
12578		 * @param {number} focalLength - Values for focal length and film gauge must have the same unit.
12579		 */ setFocalLength(focalLength) {
12580	        /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
12581	        this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope);
12582	        this.updateProjectionMatrix();
12583	    }
12584	    /**
12585		 * Returns the focal length from the current {@link PerspectiveCamera#fov} and
12586		 * {@link PerspectiveCamera#filmGauge}.
12587		 *
12588		 * @return {number} The computed focal length.
12589		 */ getFocalLength() {
12590	        const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov);
12591	        return 0.5 * this.getFilmHeight() / vExtentSlope;
12592	    }
12593	    /**
12594		 * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}.
12595		 *
12596		 * @return {number} The effective FOV.
12597		 */ getEffectiveFOV() {
12598	        return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom);
12599	    }
12600	    /**
12601		 * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
12602		 * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
12603		 *
12604		 * @return {number} The film width.
12605		 */ getFilmWidth() {
12606	        // film not completely covered in portrait format (aspect < 1)
12607	        return this.filmGauge * Math.min(this.aspect, 1);
12608	    }
12609	    /**
12610		 * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or
12611		 * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}.
12612		 *
12613		 * @return {number} The film width.
12614		 */ getFilmHeight() {
12615	        // film not completely covered in landscape format (aspect > 1)
12616	        return this.filmGauge / Math.max(this.aspect, 1);
12617	    }
12618	    /**
12619		 * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction.
12620		 * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle.
12621		 *
12622		 * @param {number} distance - The viewing distance.
12623		 * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector.
12624		 * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector.
12625		 */ getViewBounds(distance, minTarget, maxTarget) {
12626	        _v3$1.set(-1, -1, 0.5).applyMatrix4(this.projectionMatrixInverse);
12627	        minTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance / _v3$1.z);
12628	        _v3$1.set(1, 1, 0.5).applyMatrix4(this.projectionMatrixInverse);
12629	        maxTarget.set(_v3$1.x, _v3$1.y).multiplyScalar(-distance / _v3$1.z);
12630	    }
12631	    /**
12632		 * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction.
12633		 *
12634		 * @param {number} distance - The viewing distance.
12635		 * @param {Vector2} target - The target vector that is used to store result where x is width and y is height.
12636		 * @returns {Vector2} The view size.
12637		 */ getViewSize(distance, target) {
12638	        this.getViewBounds(distance, _minTarget, _maxTarget);
12639	        return target.subVectors(_maxTarget, _minTarget);
12640	    }
12641	    /**
12642		 * Sets an offset in a larger frustum. This is useful for multi-window or
12643		 * multi-monitor/multi-machine setups.
12644		 *
12645		 * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
12646		 * the monitors are in grid like this
12647		 *```
12648		 *   +---+---+---+
12649		 *   | A | B | C |
12650		 *   +---+---+---+
12651		 *   | D | E | F |
12652		 *   +---+---+---+
12653		 *```
12654		 * then for each monitor you would call it like this:
12655		 *```js
12656		 * const w = 1920;
12657		 * const h = 1080;
12658		 * const fullWidth = w * 3;
12659		 * const fullHeight = h * 2;
12660		 *
12661		 * // --A--
12662		 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
12663		 * // --B--
12664		 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
12665		 * // --C--
12666		 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
12667		 * // --D--
12668		 * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
12669		 * // --E--
12670		 * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
12671		 * // --F--
12672		 * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
12673		 * ```
12674		 *
12675		 * Note there is no reason monitors have to be the same size or in a grid.
12676		 *
12677		 * @param {number} fullWidth - The full width of multiview setup.
12678		 * @param {number} fullHeight - The full height of multiview setup.
12679		 * @param {number} x - The horizontal offset of the subcamera.
12680		 * @param {number} y - The vertical offset of the subcamera.
12681		 * @param {number} width - The width of subcamera.
12682		 * @param {number} height - The height of subcamera.
12683		 */ setViewOffset(fullWidth, fullHeight, x, y, width, height) {
12684	        this.aspect = fullWidth / fullHeight;
12685	        if (this.view === null) {
12686	            this.view = {
12687	                enabled: true,
12688	                fullWidth: 1,
12689	                fullHeight: 1,
12690	                offsetX: 0,
12691	                offsetY: 0,
12692	                width: 1,
12693	                height: 1
12694	            };
12695	        }
12696	        this.view.enabled = true;
12697	        this.view.fullWidth = fullWidth;
12698	        this.view.fullHeight = fullHeight;
12699	        this.view.offsetX = x;
12700	        this.view.offsetY = y;
12701	        this.view.width = width;
12702	        this.view.height = height;
12703	        this.updateProjectionMatrix();
12704	    }
12705	    /**
12706		 * Removes the view offset from the projection matrix.
12707		 */ clearViewOffset() {
12708	        if (this.view !== null) {
12709	            this.view.enabled = false;
vendor: 4,613 bytes, lines 12710-12841
12710	        }
12711	        this.updateProjectionMatrix();
12712	    }
12713	    /**
12714		 * Updates the camera's projection matrix. Must be called after any change of
12715		 * camera properties.
12716		 */ updateProjectionMatrix() {
12717	        const near = this.near;
12718	        let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom;
12719	        let height = 2 * top;
12720	        let width = this.aspect * height;
12721	        let left = -0.5 * width;
12722	        const view = this.view;
12723	        if (this.view !== null && this.view.enabled) {
12724	            const fullWidth = view.fullWidth, fullHeight = view.fullHeight;
12725	            left += view.offsetX * width / fullWidth;
12726	            top -= view.offsetY * height / fullHeight;
12727	            width *= view.width / fullWidth;
12728	            height *= view.height / fullHeight;
12729	        }
12730	        const skew = this.filmOffset;
12731	        if (skew !== 0) left += near * skew / this.getFilmWidth();
12732	        this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far, this.coordinateSystem);
12733	        this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
12734	    }
12735	    toJSON(meta) {
12736	        const data = super.toJSON(meta);
12737	        data.object.fov = this.fov;
12738	        data.object.zoom = this.zoom;
12739	        data.object.near = this.near;
12740	        data.object.far = this.far;
12741	        data.object.focus = this.focus;
12742	        data.object.aspect = this.aspect;
12743	        if (this.view !== null) data.object.view = Object.assign({}, this.view);
12744	        data.object.filmGauge = this.filmGauge;
12745	        data.object.filmOffset = this.filmOffset;
12746	        return data;
12747	    }
12748	    /**
12749		 * Constructs a new perspective camera.
12750		 *
12751		 * @param {number} [fov=50] - The vertical field of view.
12752		 * @param {number} [aspect=1] - The aspect ratio.
12753		 * @param {number} [near=0.1] - The camera's near plane.
12754		 * @param {number} [far=2000] - The camera's far plane.
12755		 */ constructor(fov = 50, aspect = 1, near = 0.1, far = 2000){
12756	        super();
12757	        /**
12758			 * This flag can be used for type testing.
12759			 *
12760			 * @type {boolean}
12761			 * @readonly
12762			 * @default true
12763			 */ this.isPerspectiveCamera = true;
12764	        this.type = 'PerspectiveCamera';
12765	        /**
12766			 * The vertical field of view, from bottom to top of view,
12767			 * in degrees.
12768			 *
12769			 * @type {number}
12770			 * @default 50
12771			 */ this.fov = fov;
12772	        /**
12773			 * The zoom factor of the camera.
12774			 *
12775			 * @type {number}
12776			 * @default 1
12777			 */ this.zoom = 1;
12778	        /**
12779			 * The camera's near plane. The valid range is greater than `0`
12780			 * and less than the current value of {@link PerspectiveCamera#far}.
12781			 *
12782			 * Note that, unlike for the {@link OrthographicCamera}, `0` is <em>not</em> a
12783			 * valid value for a perspective camera's near plane.
12784			 *
12785			 * @type {number}
12786			 * @default 0.1
12787			 */ this.near = near;
12788	        /**
12789			 * The camera's far plane. Must be greater than the
12790			 * current value of {@link PerspectiveCamera#near}.
12791			 *
12792			 * @type {number}
12793			 * @default 2000
12794			 */ this.far = far;
12795	        /**
12796			 * Object distance used for stereoscopy and depth-of-field effects. This
12797			 * parameter does not influence the projection matrix unless a
12798			 * {@link StereoCamera} is being used.
12799			 *
12800			 * @type {number}
12801			 * @default 10
12802			 */ this.focus = 10;
12803	        /**
12804			 * The aspect ratio, usually the canvas width / canvas height.
12805			 *
12806			 * @type {number}
12807			 * @default 1
12808			 */ this.aspect = aspect;
12809	        /**
12810			 * Represents the frustum window specification. This property should not be edited
12811			 * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}.
12812			 *
12813			 * @type {?Object}
12814			 * @default null
12815			 */ this.view = null;
12816	        /**
12817			 * Film size used for the larger axis. Default is `35` (millimeters). This
12818			 * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset}
12819			 * is set to a nonzero value.
12820			 *
12821			 * @type {number}
12822			 * @default 35
12823			 */ this.filmGauge = 35;
12824	        /**
12825			 * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}.
12826			 *
12827			 * @type {number}
12828			 * @default 0
12829			 */ this.filmOffset = 0;
12830	        this.updateProjectionMatrix();
12831	    }
12832	}
12833	const fov = -90; // negative fov is not an error
12834	const aspect = 1;
12835	/**
12836	 * A special type of camera that is positioned in 3D space to render its surroundings into a
12837	 * cube render target. The render target can then be used as an environment map for rendering
12838	 * realtime reflections in your scene.
12839	 *
12840	 * ```js
12841	 * // Create cube render target
12842	 * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } );
12843	 *
12844	 * // Create cube camera
12845	 * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget );
12846	 * scene.add( cubeCamera );
12847	 *
12848	 * // Create car
12849	 * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } );
12850	 * const car = new THREE.Mesh( carGeometry, chromeMaterial );
12851	 * scene.add( car );
12852	 *
12853	 * // Update the render target cube
12854	 * car.visible = false;
12855	 * cubeCamera.position.copy( car.position );
12856	 * cubeCamera.update( renderer, scene );
12857	 *
12858	 * // Render the scene
12859	 * car.visible = true;
12860	 * renderer.render( scene, camera );
12861	 * ```
12862	 *
12863	 * @augments Object3D
12864	 */ class CubeCamera extends Object3D {
12865	    /**
12866		 * Must be called when the coordinate system of the cube camera is changed.
12867		 */ updateCoordinateSystem() {
12868	        const coordinateSystem = this.coordinateSystem;
12869	        const cameras = this.children.concat();
12870	        const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = cameras;
12871	        for (const camera of cameras)this.remove(camera);
12872	        if (coordinateSystem === WebGLCoordinateSystem) {
12873	            cameraPX.up.set(0, 1, 0);
12874	            cameraPX.lookAt(1, 0, 0);
12875	            cameraNX.up.set(0, 1, 0);
12876	            cameraNX.lookAt(-1, 0, 0);
12877	            cameraPY.up.set(0, 0, -1);
12878	            cameraPY.lookAt(0, 1, 0);
12879	            cameraNY.up.set(0, 0, 1);
12880	            cameraNY.lookAt(0, -1, 0);
12881	            cameraPZ.up.set(0, 1, 0);
12882	            cameraPZ.lookAt(0, 0, 1);
12883	            cameraNZ.up.set(0, 1, 0);
12884	            cameraNZ.lookAt(0, 0, -1);
12885	        } else if (coordinateSystem === WebGPUCoordinateSystem) {
12886	            cameraPX.up.set(0, -1, 0);
12887	            cameraPX.lookAt(-1, 0, 0);
12888	            cameraNX.up.set(0, -1, 0);
12889	            cameraNX.lookAt(1, 0, 0);
12890	            cameraPY.up.set(0, 0, 1);
12891	            cameraPY.lookAt(0, 1, 0);
12892	            cameraNY.up.set(0, 0, -1);
12893	            cameraNY.lookAt(0, -1, 0);
12894	            cameraPZ.up.set(0, -1, 0);
12895	            cameraPZ.lookAt(0, 0, 1);
12896	            cameraNZ.up.set(0, -1, 0);
12897	            cameraNZ.lookAt(0, 0, -1);
12898	        } else {
12899	            throw new Error('THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem);
12900	        }
12901	        for (const camera of cameras){
12902	            this.add(camera);
12903	            camera.updateMatrixWorld();
12904	        }
12905	    }
12906	    /**
12907		 * Calling this method will render the given scene with the given renderer
12908		 * into the cube render target of the camera.
12909		 *
12910		 * @param {(Renderer|WebGLRenderer)} renderer - The renderer.
12911		 * @param {Scene} scene - The scene to render.
12912		 */ update(renderer, scene) {
12913	        if (this.parent === null) this.updateMatrixWorld();
12914	        const { renderTarget, activeMipmapLevel } = this;
12915	        if (this.coordinateSystem !== renderer.coordinateSystem) {
12916	            this.coordinateSystem = renderer.coordinateSystem;
12917	            this.updateCoordinateSystem();
12918	        }
12919	        const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children;
12920	        const currentRenderTarget = renderer.getRenderTarget();
12921	        const currentActiveCubeFace = renderer.getActiveCubeFace();
12922	        const currentActiveMipmapLevel = renderer.getActiveMipmapLevel();
12923	        const currentXrEnabled = renderer.xr.enabled;
12924	        renderer.xr.enabled = false;
12925	        const generateMipmaps = renderTarget.texture.generateMipmaps;
12926	        renderTarget.texture.generateMipmaps = false;
12927	        renderer.setRenderTarget(renderTarget, 0, activeMipmapLevel);
12928	        renderer.render(scene, cameraPX);
12929	        renderer.setRenderTarget(renderTarget, 1, activeMipmapLevel);
12930	        renderer.render(scene, cameraNX);
12931	        renderer.setRenderTarget(renderTarget, 2, activeMipmapLevel);
12932	        renderer.render(scene, cameraPY);
12933	        renderer.setRenderTarget(renderTarget, 3, activeMipmapLevel);
12934	        renderer.render(scene, cameraNY);
12935	        renderer.setRenderTarget(renderTarget, 4, activeMipmapLevel);
12936	        renderer.render(scene, cameraPZ);
12937	        // mipmaps are generated during the last call of render()
12938	        // at this point, all sides of the cube render target are defined
12939	        renderTarget.texture.generateMipmaps = generateMipmaps;
12940	        renderer.setRenderTarget(renderTarget, 5, activeMipmapLevel);
12941	        renderer.render(scene, cameraNZ);
12942	        renderer.setRenderTarget(currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel);
12943	        renderer.xr.enabled = currentXrEnabled;
12944	        renderTarget.texture.needsPMREMUpdate = true;
12945	    }
12946	    /**
12947		 * Constructs a new cube camera.
12948		 *
12949		 * @param {number} near - The camera's near plane.
12950		 * @param {number} far - The camera's far plane.
vendor: 4,586 bytes, lines 12951-13088
12951		 * @param {WebGLCubeRenderTarget} renderTarget - The cube render target.
12952		 */ constructor(near, far, renderTarget){
12953	        super();
12954	        this.type = 'CubeCamera';
12955	        /**
12956			 * A reference to the cube render target.
12957			 *
12958			 * @type {WebGLCubeRenderTarget}
12959			 */ this.renderTarget = renderTarget;
12960	        /**
12961			 * The current active coordinate system.
12962			 *
12963			 * @type {?(WebGLCoordinateSystem|WebGPUCoordinateSystem)}
12964			 * @default null
12965			 */ this.coordinateSystem = null;
12966	        /**
12967			 * The current active mipmap level
12968			 *
12969			 * @type {number}
12970			 * @default 0
12971			 */ this.activeMipmapLevel = 0;
12972	        const cameraPX = new PerspectiveCamera(fov, aspect, near, far);
12973	        cameraPX.layers = this.layers;
12974	        this.add(cameraPX);
12975	        const cameraNX = new PerspectiveCamera(fov, aspect, near, far);
12976	        cameraNX.layers = this.layers;
12977	        this.add(cameraNX);
12978	        const cameraPY = new PerspectiveCamera(fov, aspect, near, far);
12979	        cameraPY.layers = this.layers;
12980	        this.add(cameraPY);
12981	        const cameraNY = new PerspectiveCamera(fov, aspect, near, far);
12982	        cameraNY.layers = this.layers;
12983	        this.add(cameraNY);
12984	        const cameraPZ = new PerspectiveCamera(fov, aspect, near, far);
12985	        cameraPZ.layers = this.layers;
12986	        this.add(cameraPZ);
12987	        const cameraNZ = new PerspectiveCamera(fov, aspect, near, far);
12988	        cameraNZ.layers = this.layers;
12989	        this.add(cameraNZ);
12990	    }
12991	}
12992	class CubeTexture extends Texture$1 {
12993	    get images() {
12994	        return this.image;
12995	    }
12996	    set images(value) {
12997	        this.image = value;
12998	    }
12999	    constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace){
13000	        images = images !== undefined ? images : [];
13001	        mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
13002	        super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace);
13003	        this.isCubeTexture = true;
13004	        this.flipY = false;
13005	    }
13006	}
13007	class WebGLCubeRenderTarget extends WebGLRenderTarget {
13008	    fromEquirectangularTexture(renderer, texture) {
13009	        this.texture.type = texture.type;
13010	        this.texture.colorSpace = texture.colorSpace;
13011	        this.texture.generateMipmaps = texture.generateMipmaps;
13012	        this.texture.minFilter = texture.minFilter;
13013	        this.texture.magFilter = texture.magFilter;
13014	        const shader = {
13015	            uniforms: {
13016	                tEquirect: {
13017	                    value: null
13018	                }
13019	            },
13020	            vertexShader: /* glsl */ `
13021
13022				varying vec3 vWorldDirection;
13023
13024				vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
13025
13026					return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
13027
13028				}
13029
13030				void main() {
13031
13032					vWorldDirection = transformDirection( position, modelMatrix );
13033
13034					#include <begin_vertex>
13035					#include <project_vertex>
13036
13037				}
13038			`,
13039	            fragmentShader: /* glsl */ `
13040
13041				uniform sampler2D tEquirect;
13042
13043				varying vec3 vWorldDirection;
13044
13045				#include <common>
13046
13047				void main() {
13048
13049					vec3 direction = normalize( vWorldDirection );
13050
13051					vec2 sampleUV = equirectUv( direction );
13052
13053					gl_FragColor = texture2D( tEquirect, sampleUV );
13054
13055				}
13056			`
13057	        };
13058	        const geometry = new BoxGeometry(5, 5, 5);
13059	        const material = new ShaderMaterial({
13060	            name: 'CubemapFromEquirect',
13061	            uniforms: cloneUniforms(shader.uniforms),
13062	            vertexShader: shader.vertexShader,
13063	            fragmentShader: shader.fragmentShader,
13064	            side: BackSide,
13065	            blending: NoBlending
13066	        });
13067	        material.uniforms.tEquirect.value = texture;
13068	        const mesh = new Mesh(geometry, material);
13069	        const currentMinFilter = texture.minFilter;
13070	        // Avoid blurred poles
13071	        if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter;
13072	        const camera = new CubeCamera(1, 10, this);
13073	        camera.update(renderer, mesh);
13074	        texture.minFilter = currentMinFilter;
13075	        mesh.geometry.dispose();
13076	        mesh.material.dispose();
13077	        return this;
13078	    }
13079	    clear(renderer, color, depth, stencil) {
13080	        const currentRenderTarget = renderer.getRenderTarget();
13081	        for(let i = 0; i < 6; i++){
13082	            renderer.setRenderTarget(this, i);
13083	            renderer.clear(color, depth, stencil);
13084	        }
13085	        renderer.setRenderTarget(currentRenderTarget);
13086	    }
13087	    constructor(size = 1, options = {}){
13088	        super(size, size, options);
vendor: 4,708 bytes, lines 13089-13218
13089	        this.isWebGLCubeRenderTarget = true;
13090	        const image = {
13091	            width: size,
13092	            height: size,
13093	            depth: 1
13094	        };
13095	        const images = [
13096	            image,
13097	            image,
13098	            image,
13099	            image,
13100	            image,
13101	            image
13102	        ];
13103	        this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.colorSpace);
13104	        // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)
13105	        // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,
13106	        // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.
13107	        // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped
13108	        // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture
13109	        // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).
13110	        this.texture.isRenderTargetTexture = true;
13111	        this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
13112	        this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
13113	    }
13114	}
13115	/**
13116	 * This is almost identical to an {@link Object3D}. Its purpose is to
13117	 * make working with groups of objects syntactically clearer.
13118	 *
13119	 * ```js
13120	 * // Create a group and add the two cubes.
13121	 * // These cubes can now be rotated / scaled etc as a group.
13122	 * const group = new THREE.Group();
13123	 *
13124	 * group.add( meshA );
13125	 * group.add( meshB );
13126	 *
13127	 * scene.add( group );
13128	 * ```
13129	 *
13130	 * @augments Object3D
13131	 */ class Group extends Object3D {
13132	    constructor(){
13133	        super();
13134	        /**
13135			 * This flag can be used for type testing.
13136			 *
13137			 * @type {boolean}
13138			 * @readonly
13139			 * @default true
13140			 */ this.isGroup = true;
13141	        this.type = 'Group';
13142	    }
13143	}
13144	const _moveEvent = {
13145	    type: 'move'
13146	};
13147	class WebXRController {
13148	    getHandSpace() {
13149	        if (this._hand === null) {
13150	            this._hand = new Group();
13151	            this._hand.matrixAutoUpdate = false;
13152	            this._hand.visible = false;
13153	            this._hand.joints = {};
13154	            this._hand.inputState = {
13155	                pinching: false
13156	            };
13157	        }
13158	        return this._hand;
13159	    }
13160	    getTargetRaySpace() {
13161	        if (this._targetRay === null) {
13162	            this._targetRay = new Group();
13163	            this._targetRay.matrixAutoUpdate = false;
13164	            this._targetRay.visible = false;
13165	            this._targetRay.hasLinearVelocity = false;
13166	            this._targetRay.linearVelocity = new Vector3();
13167	            this._targetRay.hasAngularVelocity = false;
13168	            this._targetRay.angularVelocity = new Vector3();
13169	        }
13170	        return this._targetRay;
13171	    }
13172	    getGripSpace() {
13173	        if (this._grip === null) {
13174	            this._grip = new Group();
13175	            this._grip.matrixAutoUpdate = false;
13176	            this._grip.visible = false;
13177	            this._grip.hasLinearVelocity = false;
13178	            this._grip.linearVelocity = new Vector3();
13179	            this._grip.hasAngularVelocity = false;
13180	            this._grip.angularVelocity = new Vector3();
13181	        }
13182	        return this._grip;
13183	    }
13184	    dispatchEvent(event) {
13185	        if (this._targetRay !== null) {
13186	            this._targetRay.dispatchEvent(event);
13187	        }
13188	        if (this._grip !== null) {
13189	            this._grip.dispatchEvent(event);
13190	        }
13191	        if (this._hand !== null) {
13192	            this._hand.dispatchEvent(event);
13193	        }
13194	        return this;
13195	    }
13196	    connect(inputSource) {
13197	        if (inputSource && inputSource.hand) {
13198	            const hand = this._hand;
13199	            if (hand) {
13200	                for (const inputjoint of inputSource.hand.values()){
13201	                    // Initialize hand with joints when connected
13202	                    this._getHandJoint(hand, inputjoint);
13203	                }
13204	            }
13205	        }
13206	        this.dispatchEvent({
13207	            type: 'connected',
13208	            data: inputSource
13209	        });
13210	        return this;
13211	    }
13212	    disconnect(inputSource) {
13213	        this.dispatchEvent({
13214	            type: 'disconnected',
13215	            data: inputSource
13216	        });
13217	        if (this._targetRay !== null) {
13218	            this._targetRay.visible = false;
vendor: 60,135 bytes, lines 13219-14738
13219	        }
13220	        if (this._grip !== null) {
13221	            this._grip.visible = false;
13222	        }
13223	        if (this._hand !== null) {
13224	            this._hand.visible = false;
13225	        }
13226	        return this;
13227	    }
13228	    update(inputSource, frame, referenceSpace) {
13229	        let inputPose = null;
13230	        let gripPose = null;
13231	        let handPose = null;
13232	        const targetRay = this._targetRay;
13233	        const grip = this._grip;
13234	        const hand = this._hand;
13235	        if (inputSource && frame.session.visibilityState !== 'visible-blurred') {
13236	            if (hand && inputSource.hand) {
13237	                handPose = true;
13238	                for (const inputjoint of inputSource.hand.values()){
13239	                    // Update the joints groups with the XRJoint poses
13240	                    const jointPose = frame.getJointPose(inputjoint, referenceSpace);
13241	                    // The transform of this joint will be updated with the joint pose on each frame
13242	                    const joint = this._getHandJoint(hand, inputjoint);
13243	                    if (jointPose !== null) {
13244	                        joint.matrix.fromArray(jointPose.transform.matrix);
13245	                        joint.matrix.decompose(joint.position, joint.rotation, joint.scale);
13246	                        joint.matrixWorldNeedsUpdate = true;
13247	                        joint.jointRadius = jointPose.radius;
13248	                    }
13249	                    joint.visible = jointPose !== null;
13250	                }
13251	                // Custom events
13252	                // Check pinchz
13253	                const indexTip = hand.joints['index-finger-tip'];
13254	                const thumbTip = hand.joints['thumb-tip'];
13255	                const distance = indexTip.position.distanceTo(thumbTip.position);
13256	                const distanceToPinch = 0.02;
13257	                const threshold = 0.005;
13258	                if (hand.inputState.pinching && distance > distanceToPinch + threshold) {
13259	                    hand.inputState.pinching = false;
13260	                    this.dispatchEvent({
13261	                        type: 'pinchend',
13262	                        handedness: inputSource.handedness,
13263	                        target: this
13264	                    });
13265	                } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) {
13266	                    hand.inputState.pinching = true;
13267	                    this.dispatchEvent({
13268	                        type: 'pinchstart',
13269	                        handedness: inputSource.handedness,
13270	                        target: this
13271	                    });
13272	                }
13273	            } else {
13274	                if (grip !== null && inputSource.gripSpace) {
13275	                    gripPose = frame.getPose(inputSource.gripSpace, referenceSpace);
13276	                    if (gripPose !== null) {
13277	                        grip.matrix.fromArray(gripPose.transform.matrix);
13278	                        grip.matrix.decompose(grip.position, grip.rotation, grip.scale);
13279	                        grip.matrixWorldNeedsUpdate = true;
13280	                        if (gripPose.linearVelocity) {
13281	                            grip.hasLinearVelocity = true;
13282	                            grip.linearVelocity.copy(gripPose.linearVelocity);
13283	                        } else {
13284	                            grip.hasLinearVelocity = false;
13285	                        }
13286	                        if (gripPose.angularVelocity) {
13287	                            grip.hasAngularVelocity = true;
13288	                            grip.angularVelocity.copy(gripPose.angularVelocity);
13289	                        } else {
13290	                            grip.hasAngularVelocity = false;
13291	                        }
13292	                    }
13293	                }
13294	            }
13295	            if (targetRay !== null) {
13296	                inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace);
13297	                // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it
13298	                if (inputPose === null && gripPose !== null) {
13299	                    inputPose = gripPose;
13300	                }
13301	                if (inputPose !== null) {
13302	                    targetRay.matrix.fromArray(inputPose.transform.matrix);
13303	                    targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale);
13304	                    targetRay.matrixWorldNeedsUpdate = true;
13305	                    if (inputPose.linearVelocity) {
13306	                        targetRay.hasLinearVelocity = true;
13307	                        targetRay.linearVelocity.copy(inputPose.linearVelocity);
13308	                    } else {
13309	                        targetRay.hasLinearVelocity = false;
13310	                    }
13311	                    if (inputPose.angularVelocity) {
13312	                        targetRay.hasAngularVelocity = true;
13313	                        targetRay.angularVelocity.copy(inputPose.angularVelocity);
13314	                    } else {
13315	                        targetRay.hasAngularVelocity = false;
13316	                    }
13317	                    this.dispatchEvent(_moveEvent);
13318	                }
13319	            }
13320	        }
13321	        if (targetRay !== null) {
13322	            targetRay.visible = inputPose !== null;
13323	        }
13324	        if (grip !== null) {
13325	            grip.visible = gripPose !== null;
13326	        }
13327	        if (hand !== null) {
13328	            hand.visible = handPose !== null;
13329	        }
13330	        return this;
13331	    }
13332	    // private method
13333	    _getHandJoint(hand, inputjoint) {
13334	        if (hand.joints[inputjoint.jointName] === undefined) {
13335	            const joint = new Group();
13336	            joint.matrixAutoUpdate = false;
13337	            joint.visible = false;
13338	            hand.joints[inputjoint.jointName] = joint;
13339	            hand.add(joint);
13340	        }
13341	        return hand.joints[inputjoint.jointName];
13342	    }
13343	    constructor(){
13344	        this._targetRay = null;
13345	        this._grip = null;
13346	        this._hand = null;
13347	    }
13348	}
13349	/**
13350	 * Scenes allow you to set up what is to be rendered and where by three.js.
13351	 * This is where you place 3D objects like meshes, lines or lights.
13352	 *
13353	 * @augments Object3D
13354	 */ class Scene extends Object3D {
13355	    copy(source, recursive) {
13356	        super.copy(source, recursive);
13357	        if (source.background !== null) this.background = source.background.clone();
13358	        if (source.environment !== null) this.environment = source.environment.clone();
13359	        if (source.fog !== null) this.fog = source.fog.clone();
13360	        this.backgroundBlurriness = source.backgroundBlurriness;
13361	        this.backgroundIntensity = source.backgroundIntensity;
13362	        this.backgroundRotation.copy(source.backgroundRotation);
13363	        this.environmentIntensity = source.environmentIntensity;
13364	        this.environmentRotation.copy(source.environmentRotation);
13365	        if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone();
13366	        this.matrixAutoUpdate = source.matrixAutoUpdate;
13367	        return this;
13368	    }
13369	    toJSON(meta) {
13370	        const data = super.toJSON(meta);
13371	        if (this.fog !== null) data.object.fog = this.fog.toJSON();
13372	        if (this.backgroundBlurriness > 0) data.object.backgroundBlurriness = this.backgroundBlurriness;
13373	        if (this.backgroundIntensity !== 1) data.object.backgroundIntensity = this.backgroundIntensity;
13374	        data.object.backgroundRotation = this.backgroundRotation.toArray();
13375	        if (this.environmentIntensity !== 1) data.object.environmentIntensity = this.environmentIntensity;
13376	        data.object.environmentRotation = this.environmentRotation.toArray();
13377	        return data;
13378	    }
13379	    /**
13380		 * Constructs a new scene.
13381		 */ constructor(){
13382	        super();
13383	        /**
13384			 * This flag can be used for type testing.
13385			 *
13386			 * @type {boolean}
13387			 * @readonly
13388			 * @default true
13389			 */ this.isScene = true;
13390	        this.type = 'Scene';
13391	        /**
13392			 * Defines the background of the scene. Valid inputs are:
13393			 *
13394			 * - A color for defining a uniform colored background.
13395			 * - A texture for defining a (flat) textured background.
13396			 * - Cube textures or equirectangular textures for defining a skybox.
13397			 *
13398			 * @type {?(Color|Texture)}
13399			 * @default null
13400			 */ this.background = null;
13401	        /**
13402			 * Sets the environment map for all physical materials in the scene. However,
13403			 * it's not possible to overwrite an existing texture assigned to the `envMap`
13404			 * material property.
13405			 *
13406			 * @type {?Texture}
13407			 * @default null
13408			 */ this.environment = null;
13409	        /**
13410			 * A fog instance defining the type of fog that affects everything
13411			 * rendered in the scene.
13412			 *
13413			 * @type {?(Fog|FogExp2)}
13414			 * @default null
13415			 */ this.fog = null;
13416	        /**
13417			 * Sets the blurriness of the background. Only influences environment maps
13418			 * assigned to {@link Scene#background}. Valid input is a float between `0`
13419			 * and `1`.
13420			 *
13421			 * @type {number}
13422			 * @default 0
13423			 */ this.backgroundBlurriness = 0;
13424	        /**
13425			 * Attenuates the color of the background. Only applies to background textures.
13426			 *
13427			 * @type {number}
13428			 * @default 1
13429			 */ this.backgroundIntensity = 1;
13430	        /**
13431			 * The rotation of the background in radians. Only influences environment maps
13432			 * assigned to {@link Scene#background}.
13433			 *
13434			 * @type {Euler}
13435			 * @default (0,0,0)
13436			 */ this.backgroundRotation = new Euler();
13437	        /**
13438			 * Attenuates the color of the environment. Only influences environment maps
13439			 * assigned to {@link Scene#environment}.
13440			 *
13441			 * @type {number}
13442			 * @default 1
13443			 */ this.environmentIntensity = 1;
13444	        /**
13445			 * The rotation of the environment map in radians. Only influences physical materials
13446			 * in the scene when {@link Scene#environment} is used.
13447			 *
13448			 * @type {Euler}
13449			 * @default (0,0,0)
13450			 */ this.environmentRotation = new Euler();
13451	        /**
13452			 * Forces everything in the scene to be rendered with the defined material.
13453			 *
13454			 * @type {?Material}
13455			 * @default null
13456			 */ this.overrideMaterial = null;
13457	        if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
13458	            __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
13459	                detail: this
13460	            }));
13461	        }
13462	    }
13463	}
13464	class InterleavedBuffer {
13465	    onUploadCallback() {}
13466	    set needsUpdate(value) {
13467	        if (value === true) this.version++;
13468	    }
13469	    setUsage(value) {
13470	        this.usage = value;
13471	        return this;
13472	    }
13473	    addUpdateRange(start, count) {
13474	        this.updateRanges.push({
13475	            start,
13476	            count
13477	        });
13478	    }
13479	    clearUpdateRanges() {
13480	        this.updateRanges.length = 0;
13481	    }
13482	    copy(source) {
13483	        this.array = new source.array.constructor(source.array);
13484	        this.count = source.count;
13485	        this.stride = source.stride;
13486	        this.usage = source.usage;
13487	        return this;
13488	    }
13489	    copyAt(index1, attribute, index2) {
13490	        index1 *= this.stride;
13491	        index2 *= attribute.stride;
13492	        for(let i = 0, l = this.stride; i < l; i++){
13493	            this.array[index1 + i] = attribute.array[index2 + i];
13494	        }
13495	        return this;
13496	    }
13497	    set(value, offset = 0) {
13498	        this.array.set(value, offset);
13499	        return this;
13500	    }
13501	    clone(data) {
13502	        if (data.arrayBuffers === undefined) {
13503	            data.arrayBuffers = {};
13504	        }
13505	        if (this.array.buffer._uuid === undefined) {
13506	            this.array.buffer._uuid = generateUUID();
13507	        }
13508	        if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
13509	            data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer;
13510	        }
13511	        const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]);
13512	        const ib = new this.constructor(array, this.stride);
13513	        ib.setUsage(this.usage);
13514	        return ib;
13515	    }
13516	    onUpload(callback) {
13517	        this.onUploadCallback = callback;
13518	        return this;
13519	    }
13520	    toJSON(data) {
13521	        if (data.arrayBuffers === undefined) {
13522	            data.arrayBuffers = {};
13523	        }
13524	        // generate UUID for array buffer if necessary
13525	        if (this.array.buffer._uuid === undefined) {
13526	            this.array.buffer._uuid = generateUUID();
13527	        }
13528	        if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
13529	            data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer));
13530	        }
13531	        //
13532	        return {
13533	            uuid: this.uuid,
13534	            buffer: this.array.buffer._uuid,
13535	            type: this.array.constructor.name,
13536	            stride: this.stride
13537	        };
13538	    }
13539	    constructor(array, stride){
13540	        this.isInterleavedBuffer = true;
13541	        this.array = array;
13542	        this.stride = stride;
13543	        this.count = array !== undefined ? array.length / stride : 0;
13544	        this.usage = StaticDrawUsage;
13545	        this.updateRanges = [];
13546	        this.version = 0;
13547	        this.uuid = generateUUID();
13548	    }
13549	}
13550	const _vector$7 = /*@__PURE__*/ new Vector3();
13551	class InterleavedBufferAttribute {
13552	    get count() {
13553	        return this.data.count;
13554	    }
13555	    get array() {
13556	        return this.data.array;
13557	    }
13558	    set needsUpdate(value) {
13559	        this.data.needsUpdate = value;
13560	    }
13561	    applyMatrix4(m) {
13562	        for(let i = 0, l = this.data.count; i < l; i++){
13563	            _vector$7.fromBufferAttribute(this, i);
13564	            _vector$7.applyMatrix4(m);
13565	            this.setXYZ(i, _vector$7.x, _vector$7.y, _vector$7.z);
13566	        }
13567	        return this;
13568	    }
13569	    applyNormalMatrix(m) {
13570	        for(let i = 0, l = this.count; i < l; i++){
13571	            _vector$7.fromBufferAttribute(this, i);
13572	            _vector$7.applyNormalMatrix(m);
13573	            this.setXYZ(i, _vector$7.x, _vector$7.y, _vector$7.z);
13574	        }
13575	        return this;
13576	    }
13577	    transformDirection(m) {
13578	        for(let i = 0, l = this.count; i < l; i++){
13579	            _vector$7.fromBufferAttribute(this, i);
13580	            _vector$7.transformDirection(m);
13581	            this.setXYZ(i, _vector$7.x, _vector$7.y, _vector$7.z);
13582	        }
13583	        return this;
13584	    }
13585	    getComponent(index, component) {
13586	        let value = this.array[index * this.data.stride + this.offset + component];
13587	        if (this.normalized) value = denormalize(value, this.array);
13588	        return value;
13589	    }
13590	    setComponent(index, component, value) {
13591	        if (this.normalized) value = normalize(value, this.array);
13592	        this.data.array[index * this.data.stride + this.offset + component] = value;
13593	        return this;
13594	    }
13595	    setX(index, x) {
13596	        if (this.normalized) x = normalize(x, this.array);
13597	        this.data.array[index * this.data.stride + this.offset] = x;
13598	        return this;
13599	    }
13600	    setY(index, y) {
13601	        if (this.normalized) y = normalize(y, this.array);
13602	        this.data.array[index * this.data.stride + this.offset + 1] = y;
13603	        return this;
13604	    }
13605	    setZ(index, z) {
13606	        if (this.normalized) z = normalize(z, this.array);
13607	        this.data.array[index * this.data.stride + this.offset + 2] = z;
13608	        return this;
13609	    }
13610	    setW(index, w) {
13611	        if (this.normalized) w = normalize(w, this.array);
13612	        this.data.array[index * this.data.stride + this.offset + 3] = w;
13613	        return this;
13614	    }
13615	    getX(index) {
13616	        let x = this.data.array[index * this.data.stride + this.offset];
13617	        if (this.normalized) x = denormalize(x, this.array);
13618	        return x;
13619	    }
13620	    getY(index) {
13621	        let y = this.data.array[index * this.data.stride + this.offset + 1];
13622	        if (this.normalized) y = denormalize(y, this.array);
13623	        return y;
13624	    }
13625	    getZ(index) {
13626	        let z = this.data.array[index * this.data.stride + this.offset + 2];
13627	        if (this.normalized) z = denormalize(z, this.array);
13628	        return z;
13629	    }
13630	    getW(index) {
13631	        let w = this.data.array[index * this.data.stride + this.offset + 3];
13632	        if (this.normalized) w = denormalize(w, this.array);
13633	        return w;
13634	    }
13635	    setXY(index, x, y) {
13636	        index = index * this.data.stride + this.offset;
13637	        if (this.normalized) {
13638	            x = normalize(x, this.array);
13639	            y = normalize(y, this.array);
13640	        }
13641	        this.data.array[index + 0] = x;
13642	        this.data.array[index + 1] = y;
13643	        return this;
13644	    }
13645	    setXYZ(index, x, y, z) {
13646	        index = index * this.data.stride + this.offset;
13647	        if (this.normalized) {
13648	            x = normalize(x, this.array);
13649	            y = normalize(y, this.array);
13650	            z = normalize(z, this.array);
13651	        }
13652	        this.data.array[index + 0] = x;
13653	        this.data.array[index + 1] = y;
13654	        this.data.array[index + 2] = z;
13655	        return this;
13656	    }
13657	    setXYZW(index, x, y, z, w) {
13658	        index = index * this.data.stride + this.offset;
13659	        if (this.normalized) {
13660	            x = normalize(x, this.array);
13661	            y = normalize(y, this.array);
13662	            z = normalize(z, this.array);
13663	            w = normalize(w, this.array);
13664	        }
13665	        this.data.array[index + 0] = x;
13666	        this.data.array[index + 1] = y;
13667	        this.data.array[index + 2] = z;
13668	        this.data.array[index + 3] = w;
13669	        return this;
13670	    }
13671	    clone(data) {
13672	        if (data === undefined) {
13673	            console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.');
13674	            const array = [];
13675	            for(let i = 0; i < this.count; i++){
13676	                const index = i * this.data.stride + this.offset;
13677	                for(let j = 0; j < this.itemSize; j++){
13678	                    array.push(this.data.array[index + j]);
13679	                }
13680	            }
13681	            return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized);
13682	        } else {
13683	            if (data.interleavedBuffers === undefined) {
13684	                data.interleavedBuffers = {};
13685	            }
13686	            if (data.interleavedBuffers[this.data.uuid] === undefined) {
13687	                data.interleavedBuffers[this.data.uuid] = this.data.clone(data);
13688	            }
13689	            return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized);
13690	        }
13691	    }
13692	    toJSON(data) {
13693	        if (data === undefined) {
13694	            console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.');
13695	            const array = [];
13696	            for(let i = 0; i < this.count; i++){
13697	                const index = i * this.data.stride + this.offset;
13698	                for(let j = 0; j < this.itemSize; j++){
13699	                    array.push(this.data.array[index + j]);
13700	                }
13701	            }
13702	            // de-interleave data and save it as an ordinary buffer attribute for now
13703	            return {
13704	                itemSize: this.itemSize,
13705	                type: this.array.constructor.name,
13706	                array: array,
13707	                normalized: this.normalized
13708	            };
13709	        } else {
13710	            // save as true interleaved attribute
13711	            if (data.interleavedBuffers === undefined) {
13712	                data.interleavedBuffers = {};
13713	            }
13714	            if (data.interleavedBuffers[this.data.uuid] === undefined) {
13715	                data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data);
13716	            }
13717	            return {
13718	                isInterleavedBufferAttribute: true,
13719	                itemSize: this.itemSize,
13720	                data: this.data.uuid,
13721	                offset: this.offset,
13722	                normalized: this.normalized
13723	            };
13724	        }
13725	    }
13726	    constructor(interleavedBuffer, itemSize, offset, normalized = false){
13727	        this.isInterleavedBufferAttribute = true;
13728	        this.name = '';
13729	        this.data = interleavedBuffer;
13730	        this.itemSize = itemSize;
13731	        this.offset = offset;
13732	        this.normalized = normalized;
13733	    }
13734	}
13735	const _basePosition = /*@__PURE__*/ new Vector3();
13736	const _skinIndex = /*@__PURE__*/ new Vector4();
13737	const _skinWeight = /*@__PURE__*/ new Vector4();
13738	const _vector3 = /*@__PURE__*/ new Vector3();
13739	const _matrix4 = /*@__PURE__*/ new Matrix4();
13740	const _vertex = /*@__PURE__*/ new Vector3();
13741	const _sphere$5 = /*@__PURE__*/ new Sphere();
13742	const _inverseMatrix$2 = /*@__PURE__*/ new Matrix4();
13743	const _ray$2 = /*@__PURE__*/ new Ray();
13744	/**
13745	 * A mesh that has a {@link Skeleton} that can then be used to animate the
13746	 * vertices of the geometry with skinning/skeleton animation.
13747	 *
13748	 * Next to a valid skeleton, the skinned mesh requires skin indices and weights
13749	 * as buffer attributes in its geometry. These attribute define which bones affect a single
13750	 * vertex to a certain extend.
13751	 *
13752	 * Typically skinned meshes are not created manually but loaders like {@link GLTFLoader}
13753	 * or {@link FBXLoader } import respective models.
13754	 *
13755	 * @augments Mesh
13756	 */ class SkinnedMesh extends Mesh {
13757	    /**
13758		 * Computes the bounding box of the skinned mesh, and updates {@link SkinnedMesh#boundingBox}.
13759		 * The bounding box is not automatically computed by the engine; this method must be called by your app.
13760		 * If the skinned mesh is animated, the bounding box should be recomputed per frame in order to reflect
13761		 * the current animation state.
13762		 */ computeBoundingBox() {
13763	        const geometry = this.geometry;
13764	        if (this.boundingBox === null) {
13765	            this.boundingBox = new Box3();
13766	        }
13767	        this.boundingBox.makeEmpty();
13768	        const positionAttribute = geometry.getAttribute('position');
13769	        for(let i = 0; i < positionAttribute.count; i++){
13770	            this.getVertexPosition(i, _vertex);
13771	            this.boundingBox.expandByPoint(_vertex);
13772	        }
13773	    }
13774	    /**
13775		 * Computes the bounding sphere of the skinned mesh, and updates {@link SkinnedMesh#boundingSphere}.
13776		 * The bounding sphere is automatically computed by the engine once when it is needed, e.g., for ray casting
13777		 * and view frustum culling. If the skinned mesh is animated, the bounding sphere should be recomputed
13778		 * per frame in order to reflect the current animation state.
13779		 */ computeBoundingSphere() {
13780	        const geometry = this.geometry;
13781	        if (this.boundingSphere === null) {
13782	            this.boundingSphere = new Sphere();
13783	        }
13784	        this.boundingSphere.makeEmpty();
13785	        const positionAttribute = geometry.getAttribute('position');
13786	        for(let i = 0; i < positionAttribute.count; i++){
13787	            this.getVertexPosition(i, _vertex);
13788	            this.boundingSphere.expandByPoint(_vertex);
13789	        }
13790	    }
13791	    copy(source, recursive) {
13792	        super.copy(source, recursive);
13793	        this.bindMode = source.bindMode;
13794	        this.bindMatrix.copy(source.bindMatrix);
13795	        this.bindMatrixInverse.copy(source.bindMatrixInverse);
13796	        this.skeleton = source.skeleton;
13797	        if (source.boundingBox !== null) this.boundingBox = source.boundingBox.clone();
13798	        if (source.boundingSphere !== null) this.boundingSphere = source.boundingSphere.clone();
13799	        return this;
13800	    }
13801	    raycast(raycaster, intersects) {
13802	        const material = this.material;
13803	        const matrixWorld = this.matrixWorld;
13804	        if (material === undefined) return;
13805	        // test with bounding sphere in world space
13806	        if (this.boundingSphere === null) this.computeBoundingSphere();
13807	        _sphere$5.copy(this.boundingSphere);
13808	        _sphere$5.applyMatrix4(matrixWorld);
13809	        if (raycaster.ray.intersectsSphere(_sphere$5) === false) return;
13810	        // convert ray to local space of skinned mesh
13811	        _inverseMatrix$2.copy(matrixWorld).invert();
13812	        _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2);
13813	        // test with bounding box in local space
13814	        if (this.boundingBox !== null) {
13815	            if (_ray$2.intersectsBox(this.boundingBox) === false) return;
13816	        }
13817	        // test for intersections with geometry
13818	        this._computeIntersections(raycaster, intersects, _ray$2);
13819	    }
13820	    getVertexPosition(index, target) {
13821	        super.getVertexPosition(index, target);
13822	        this.applyBoneTransform(index, target);
13823	        return target;
13824	    }
13825	    /**
13826		 * Binds the given skeleton to the skinned mesh.
13827		 *
13828		 * @param {Skeleton} skeleton - The skeleton to bind.
13829		 * @param {Matrix4} [bindMatrix] - The bind matrix. If no bind matrix is provided,
13830		 * the skinned mesh's world matrix will be used instead.
13831		 */ bind(skeleton, bindMatrix) {
13832	        this.skeleton = skeleton;
13833	        if (bindMatrix === undefined) {
13834	            this.updateMatrixWorld(true);
13835	            this.skeleton.calculateInverses();
13836	            bindMatrix = this.matrixWorld;
13837	        }
13838	        this.bindMatrix.copy(bindMatrix);
13839	        this.bindMatrixInverse.copy(bindMatrix).invert();
13840	    }
13841	    /**
13842		 * This method sets the skinned mesh in the rest pose).
13843		 */ pose() {
13844	        this.skeleton.pose();
13845	    }
13846	    /**
13847		 * Normalizes the skin weights which are defined as a buffer attribute
13848		 * in the skinned mesh's geometry.
13849		 */ normalizeSkinWeights() {
13850	        const vector = new Vector4();
13851	        const skinWeight = this.geometry.attributes.skinWeight;
13852	        for(let i = 0, l = skinWeight.count; i < l; i++){
13853	            vector.fromBufferAttribute(skinWeight, i);
13854	            const scale = 1.0 / vector.manhattanLength();
13855	            if (scale !== Infinity) {
13856	                vector.multiplyScalar(scale);
13857	            } else {
13858	                vector.set(1, 0, 0, 0); // do something reasonable
13859	            }
13860	            skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w);
13861	        }
13862	    }
13863	    updateMatrixWorld(force) {
13864	        super.updateMatrixWorld(force);
13865	        if (this.bindMode === AttachedBindMode) {
13866	            this.bindMatrixInverse.copy(this.matrixWorld).invert();
13867	        } else if (this.bindMode === DetachedBindMode) {
13868	            this.bindMatrixInverse.copy(this.bindMatrix).invert();
13869	        } else {
13870	            console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode);
13871	        }
13872	    }
13873	    /**
13874		 * Applies the bone transform associated with the given index to the given
13875		 * vertex position. Returns the updated vector.
13876		 *
13877		 * @param {number} index - The vertex index.
13878		 * @param {Vector3} target - The target object that is used to store the method's result.
13879		 * the skinned mesh's world matrix will be used instead.
13880		 * @return {Vector3} The updated vertex position.
13881		 */ applyBoneTransform(index, target) {
13882	        const skeleton = this.skeleton;
13883	        const geometry = this.geometry;
13884	        _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index);
13885	        _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index);
13886	        _basePosition.copy(target).applyMatrix4(this.bindMatrix);
13887	        target.set(0, 0, 0);
13888	        for(let i = 0; i < 4; i++){
13889	            const weight = _skinWeight.getComponent(i);
13890	            if (weight !== 0) {
13891	                const boneIndex = _skinIndex.getComponent(i);
13892	                _matrix4.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]);
13893	                target.addScaledVector(_vector3.copy(_basePosition).applyMatrix4(_matrix4), weight);
13894	            }
13895	        }
13896	        return target.applyMatrix4(this.bindMatrixInverse);
13897	    }
13898	    /**
13899		 * Constructs a new skinned mesh.
13900		 *
13901		 * @param {BufferGeometry} [geometry] - The mesh geometry.
13902		 * @param {Material|Array<Material>} [material] - The mesh material.
13903		 */ constructor(geometry, material){
13904	        super(geometry, material);
13905	        /**
13906			 * This flag can be used for type testing.
13907			 *
13908			 * @type {boolean}
13909			 * @readonly
13910			 * @default true
13911			 */ this.isSkinnedMesh = true;
13912	        this.type = 'SkinnedMesh';
13913	        /**
13914			 * `AttachedBindMode` means the skinned mesh shares the same world space as the skeleton.
13915			 * This is not true when using `DetachedBindMode` which is useful when sharing a skeleton
13916			 * across multiple skinned meshes.
13917			 *
13918			 * @type {(AttachedBindMode|DetachedBindMode)}
13919			 * @default AttachedBindMode
13920			 */ this.bindMode = AttachedBindMode;
13921	        /**
13922			 * The base matrix that is used for the bound bone transforms.
13923			 *
13924			 * @type {Matrix4}
13925			 */ this.bindMatrix = new Matrix4();
13926	        /**
13927			 * The base matrix that is used for resetting the bound bone transforms.
13928			 *
13929			 * @type {Matrix4}
13930			 */ this.bindMatrixInverse = new Matrix4();
13931	        /**
13932			 * The bounding box of the skinned mesh. Can be computed via {@link SkinnedMesh#computeBoundingBox}.
13933			 *
13934			 * @type {?Box3}
13935			 * @default null
13936			 */ this.boundingBox = null;
13937	        /**
13938			 * The bounding sphere of the skinned mesh. Can be computed via {@link SkinnedMesh#computeBoundingSphere}.
13939			 *
13940			 * @type {?Sphere}
13941			 * @default null
13942			 */ this.boundingSphere = null;
13943	    }
13944	}
13945	/**
13946	 * A bone which is part of a {@link Skeleton}. The skeleton in turn is used by
13947	 * the {@link SkinnedMesh}.
13948	 *
13949	 * ```js
13950	 * const root = new THREE.Bone();
13951	 * const child = new THREE.Bone();
13952	 *
13953	 * root.add( child );
13954	 * child.position.y = 5;
13955	 * ```
13956	 *
13957	 * @augments Object3D
13958	 */ class Bone extends Object3D {
13959	    /**
13960		 * Constructs a new bone.
13961		 */ constructor(){
13962	        super();
13963	        /**
13964			 * This flag can be used for type testing.
13965			 *
13966			 * @type {boolean}
13967			 * @readonly
13968			 * @default true
13969			 */ this.isBone = true;
13970	        this.type = 'Bone';
13971	    }
13972	}
13973	class DataTexture extends Texture$1 {
13974	    constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, colorSpace){
13975	        super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace);
13976	        this.isDataTexture = true;
13977	        this.image = {
13978	            data: data,
13979	            width: width,
13980	            height: height
13981	        };
13982	        this.generateMipmaps = false;
13983	        this.flipY = false;
13984	        this.unpackAlignment = 1;
13985	    }
13986	}
13987	const _offsetMatrix = /*@__PURE__*/ new Matrix4();
13988	const _identityMatrix$1 = /*@__PURE__*/ new Matrix4();
13989	/**
13990	 * Class for representing the armatures in `three.js`. The skeleton
13991	 * is defined by a hierarchy of bones.
13992	 *
13993	 * ```js
13994	 * const bones = [];
13995	 *
13996	 * const shoulder = new THREE.Bone();
13997	 * const elbow = new THREE.Bone();
13998	 * const hand = new THREE.Bone();
13999	 *
14000	 * shoulder.add( elbow );
14001	 * elbow.add( hand );
14002	 *
14003	 * bones.push( shoulder , elbow, hand);
14004	 *
14005	 * shoulder.position.y = -5;
14006	 * elbow.position.y = 0;
14007	 * hand.position.y = 5;
14008	 *
14009	 * const armSkeleton = new THREE.Skeleton( bones );
14010	 * ```
14011	 */ class Skeleton {
14012	    /**
14013		 * Initializes the skeleton. This method gets automatically called by the constructor
14014		 * but depending on how the skeleton is created it might be necessary to call this method
14015		 * manually.
14016		 */ init() {
14017	        const bones = this.bones;
14018	        const boneInverses = this.boneInverses;
14019	        this.boneMatrices = new Float32Array(bones.length * 16);
14020	        // calculate inverse bone matrices if necessary
14021	        if (boneInverses.length === 0) {
14022	            this.calculateInverses();
14023	        } else {
14024	            // handle special case
14025	            if (bones.length !== boneInverses.length) {
14026	                console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.');
14027	                this.boneInverses = [];
14028	                for(let i = 0, il = this.bones.length; i < il; i++){
14029	                    this.boneInverses.push(new Matrix4());
14030	                }
14031	            }
14032	        }
14033	    }
14034	    /**
14035		 * Computes the bone inverse matrices. This method resets {@link Skeleton#boneInverses}
14036		 * and fills it with new matrices.
14037		 */ calculateInverses() {
14038	        this.boneInverses.length = 0;
14039	        for(let i = 0, il = this.bones.length; i < il; i++){
14040	            const inverse = new Matrix4();
14041	            if (this.bones[i]) {
14042	                inverse.copy(this.bones[i].matrixWorld).invert();
14043	            }
14044	            this.boneInverses.push(inverse);
14045	        }
14046	    }
14047	    /**
14048		 * Resets the skeleton to the base pose.
14049		 */ pose() {
14050	        // recover the bind-time world matrices
14051	        for(let i = 0, il = this.bones.length; i < il; i++){
14052	            const bone = this.bones[i];
14053	            if (bone) {
14054	                bone.matrixWorld.copy(this.boneInverses[i]).invert();
14055	            }
14056	        }
14057	        // compute the local matrices, positions, rotations and scales
14058	        for(let i = 0, il = this.bones.length; i < il; i++){
14059	            const bone = this.bones[i];
14060	            if (bone) {
14061	                if (bone.parent && bone.parent.isBone) {
14062	                    bone.matrix.copy(bone.parent.matrixWorld).invert();
14063	                    bone.matrix.multiply(bone.matrixWorld);
14064	                } else {
14065	                    bone.matrix.copy(bone.matrixWorld);
14066	                }
14067	                bone.matrix.decompose(bone.position, bone.quaternion, bone.scale);
14068	            }
14069	        }
14070	    }
14071	    /**
14072		 * Resets the skeleton to the base pose.
14073		 */ update() {
14074	        const bones = this.bones;
14075	        const boneInverses = this.boneInverses;
14076	        const boneMatrices = this.boneMatrices;
14077	        const boneTexture = this.boneTexture;
14078	        // flatten bone matrices to array
14079	        for(let i = 0, il = bones.length; i < il; i++){
14080	            // compute the offset between the current and the original transform
14081	            const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix$1;
14082	            _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]);
14083	            _offsetMatrix.toArray(boneMatrices, i * 16);
14084	        }
14085	        if (boneTexture !== null) {
14086	            boneTexture.needsUpdate = true;
14087	        }
14088	    }
14089	    /**
14090		 * Returns a new skeleton with copied values from this instance.
14091		 *
14092		 * @return {Skeleton} A clone of this instance.
14093		 */ clone() {
14094	        return new Skeleton(this.bones, this.boneInverses);
14095	    }
14096	    /**
14097		 * Computes a data texture for passing bone data to the vertex shader.
14098		 *
14099		 * @return {Skeleton} A reference of this instance.
14100		 */ computeBoneTexture() {
14101	        // layout (1 matrix = 4 pixels)
14102	        //      RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
14103	        //  with  8x8  pixel texture max   16 bones * 4 pixels =  (8 * 8)
14104	        //       16x16 pixel texture max   64 bones * 4 pixels = (16 * 16)
14105	        //       32x32 pixel texture max  256 bones * 4 pixels = (32 * 32)
14106	        //       64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
14107	        let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix
14108	        size = Math.ceil(size / 4) * 4;
14109	        size = Math.max(size, 4);
14110	        const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
14111	        boneMatrices.set(this.boneMatrices); // copy current values
14112	        const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);
14113	        boneTexture.needsUpdate = true;
14114	        this.boneMatrices = boneMatrices;
14115	        this.boneTexture = boneTexture;
14116	        return this;
14117	    }
14118	    /**
14119		 * Searches through the skeleton's bone array and returns the first with a
14120		 * matching name.
14121		 *
14122		 * @param {string} name - The name of the bone.
14123		 * @return {Bone|undefined} The found bone. `undefined` if no bone has been found.
14124		 */ getBoneByName(name) {
14125	        for(let i = 0, il = this.bones.length; i < il; i++){
14126	            const bone = this.bones[i];
14127	            if (bone.name === name) {
14128	                return bone;
14129	            }
14130	        }
14131	        return undefined;
14132	    }
14133	    /**
14134		 * Frees the GPU-related resources allocated by this instance. Call this
14135		 * method whenever this instance is no longer used in your app.
14136		 */ dispose() {
14137	        if (this.boneTexture !== null) {
14138	            this.boneTexture.dispose();
14139	            this.boneTexture = null;
14140	        }
14141	    }
14142	    /**
14143		 * Setups the skeleton by the given JSON and bones.
14144		 *
14145		 * @param {Object} json - The skeleton as serialized JSON.
14146		 * @param {Array<Bone>} bones - An array of bones.
14147		 * @return {Skeleton} A reference of this instance.
14148		 */ fromJSON(json, bones) {
14149	        this.uuid = json.uuid;
14150	        for(let i = 0, l = json.bones.length; i < l; i++){
14151	            const uuid = json.bones[i];
14152	            let bone = bones[uuid];
14153	            if (bone === undefined) {
14154	                console.warn('THREE.Skeleton: No bone found with UUID:', uuid);
14155	                bone = new Bone();
14156	            }
14157	            this.bones.push(bone);
14158	            this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i]));
14159	        }
14160	        this.init();
14161	        return this;
14162	    }
14163	    /**
14164		 * Serializes the skeleton into JSON.
14165		 *
14166		 * @return {Object} A JSON object representing the serialized skeleton.
14167		 * @see {@link ObjectLoader#parse}
14168		 */ toJSON() {
14169	        const data = {
14170	            metadata: {
14171	                version: 4.6,
14172	                type: 'Skeleton',
14173	                generator: 'Skeleton.toJSON'
14174	            },
14175	            bones: [],
14176	            boneInverses: []
14177	        };
14178	        data.uuid = this.uuid;
14179	        const bones = this.bones;
14180	        const boneInverses = this.boneInverses;
14181	        for(let i = 0, l = bones.length; i < l; i++){
14182	            const bone = bones[i];
14183	            data.bones.push(bone.uuid);
14184	            const boneInverse = boneInverses[i];
14185	            data.boneInverses.push(boneInverse.toArray());
14186	        }
14187	        return data;
14188	    }
14189	    /**
14190		 * Constructs a new skeleton.
14191		 *
14192		 * @param {Array<Bone>} [bones] - An array of bones.
14193		 * @param {Array<Matrix4>} [boneInverses] - An array of bone inverse matrices.
14194		 * If not provided, these matrices will be computed automatically via {@link Skeleton#calculateInverses}.
14195		 */ constructor(bones = [], boneInverses = []){
14196	        this.uuid = generateUUID();
14197	        /**
14198			 * An array of bones defining the skeleton.
14199			 *
14200			 * @type {Array<Bone>}
14201			 */ this.bones = bones.slice(0);
14202	        /**
14203			 * An array of bone inverse matrices.
14204			 *
14205			 * @type {Array<Matrix4>}
14206			 */ this.boneInverses = boneInverses;
14207	        /**
14208			 * An array buffer holding the bone data.
14209			 * Input data for {@link Skeleton#boneTexture}.
14210			 *
14211			 * @type {?Float32Array}
14212			 * @default null
14213			 */ this.boneMatrices = null;
14214	        /**
14215			 * A texture holding the bone data for use
14216			 * in the vertex shader.
14217			 *
14218			 * @type {?DataTexture}
14219			 * @default null
14220			 */ this.boneTexture = null;
14221	        this.init();
14222	    }
14223	}
14224	class InstancedBufferAttribute extends BufferAttribute {
14225	    copy(source) {
14226	        super.copy(source);
14227	        this.meshPerAttribute = source.meshPerAttribute;
14228	        return this;
14229	    }
14230	    toJSON() {
14231	        const data = super.toJSON();
14232	        data.meshPerAttribute = this.meshPerAttribute;
14233	        data.isInstancedBufferAttribute = true;
14234	        return data;
14235	    }
14236	    constructor(array, itemSize, normalized, meshPerAttribute = 1){
14237	        super(array, itemSize, normalized);
14238	        this.isInstancedBufferAttribute = true;
14239	        this.meshPerAttribute = meshPerAttribute;
14240	    }
14241	}
14242	const _instanceLocalMatrix = /*@__PURE__*/ new Matrix4();
14243	const _instanceWorldMatrix = /*@__PURE__*/ new Matrix4();
14244	const _instanceIntersects = [];
14245	const _box3 = /*@__PURE__*/ new Box3();
14246	const _identity = /*@__PURE__*/ new Matrix4();
14247	const _mesh$1 = /*@__PURE__*/ new Mesh();
14248	const _sphere$4 = /*@__PURE__*/ new Sphere();
14249	/**
14250	 * A special version of a mesh with instanced rendering support. Use
14251	 * this class if you have to render a large number of objects with the same
14252	 * geometry and material(s) but with different world transformations. The usage
14253	 * of 'InstancedMesh' will help you to reduce the number of draw calls and thus
14254	 * improve the overall rendering performance in your application.
14255	 *
14256	 * @augments Mesh
14257	 */ class InstancedMesh extends Mesh {
14258	    /**
14259		 * Computes the bounding box of the instanced mesh, and updates {@link InstancedMesh#boundingBox}.
14260		 * The bounding box is not automatically computed by the engine; this method must be called by your app.
14261		 * You may need to recompute the bounding box if an instance is transformed via {@link InstancedMesh#setMatrixAt}.
14262		 */ computeBoundingBox() {
14263	        const geometry = this.geometry;
14264	        const count = this.count;
14265	        if (this.boundingBox === null) {
14266	            this.boundingBox = new Box3();
14267	        }
14268	        if (geometry.boundingBox === null) {
14269	            geometry.computeBoundingBox();
14270	        }
14271	        this.boundingBox.makeEmpty();
14272	        for(let i = 0; i < count; i++){
14273	            this.getMatrixAt(i, _instanceLocalMatrix);
14274	            _box3.copy(geometry.boundingBox).applyMatrix4(_instanceLocalMatrix);
14275	            this.boundingBox.union(_box3);
14276	        }
14277	    }
14278	    /**
14279		 * Computes the bounding sphere of the instanced mesh, and updates {@link InstancedMesh#boundingSphere}
14280		 * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling.
14281		 * You may need to recompute the bounding sphere if an instance is transformed via {@link InstancedMesh#setMatrixAt}.
14282		 */ computeBoundingSphere() {
14283	        const geometry = this.geometry;
14284	        const count = this.count;
14285	        if (this.boundingSphere === null) {
14286	            this.boundingSphere = new Sphere();
14287	        }
14288	        if (geometry.boundingSphere === null) {
14289	            geometry.computeBoundingSphere();
14290	        }
14291	        this.boundingSphere.makeEmpty();
14292	        for(let i = 0; i < count; i++){
14293	            this.getMatrixAt(i, _instanceLocalMatrix);
14294	            _sphere$4.copy(geometry.boundingSphere).applyMatrix4(_instanceLocalMatrix);
14295	            this.boundingSphere.union(_sphere$4);
14296	        }
14297	    }
14298	    copy(source, recursive) {
14299	        super.copy(source, recursive);
14300	        this.instanceMatrix.copy(source.instanceMatrix);
14301	        if (source.morphTexture !== null) this.morphTexture = source.morphTexture.clone();
14302	        if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone();
14303	        this.count = source.count;
14304	        if (source.boundingBox !== null) this.boundingBox = source.boundingBox.clone();
14305	        if (source.boundingSphere !== null) this.boundingSphere = source.boundingSphere.clone();
14306	        return this;
14307	    }
14308	    /**
14309		 * Gets the color of the defined instance.
14310		 *
14311		 * @param {number} index - The instance index.
14312		 * @param {Color} color - The target object that is used to store the method's result.
14313		 */ getColorAt(index, color) {
14314	        color.fromArray(this.instanceColor.array, index * 3);
14315	    }
14316	    /**
14317		 * Gets the local transformation matrix of the defined instance.
14318		 *
14319		 * @param {number} index - The instance index.
14320		 * @param {Matrix4} matrix - The target object that is used to store the method's result.
14321		 */ getMatrixAt(index, matrix) {
14322	        matrix.fromArray(this.instanceMatrix.array, index * 16);
14323	    }
14324	    /**
14325		 * Gets the morph target weights of the defined instance.
14326		 *
14327		 * @param {number} index - The instance index.
14328		 * @param {Mesh} object - The target object that is used to store the method's result.
14329		 */ getMorphAt(index, object) {
14330	        const objectInfluences = object.morphTargetInfluences;
14331	        const array = this.morphTexture.source.data.data;
14332	        const len = objectInfluences.length + 1; // All influences + the baseInfluenceSum
14333	        const dataIndex = index * len + 1; // Skip the baseInfluenceSum at the beginning
14334	        for(let i = 0; i < objectInfluences.length; i++){
14335	            objectInfluences[i] = array[dataIndex + i];
14336	        }
14337	    }
14338	    raycast(raycaster, intersects) {
14339	        const matrixWorld = this.matrixWorld;
14340	        const raycastTimes = this.count;
14341	        _mesh$1.geometry = this.geometry;
14342	        _mesh$1.material = this.material;
14343	        if (_mesh$1.material === undefined) return;
14344	        // test with bounding sphere first
14345	        if (this.boundingSphere === null) this.computeBoundingSphere();
14346	        _sphere$4.copy(this.boundingSphere);
14347	        _sphere$4.applyMatrix4(matrixWorld);
14348	        if (raycaster.ray.intersectsSphere(_sphere$4) === false) return;
14349	        // now test each instance
14350	        for(let instanceId = 0; instanceId < raycastTimes; instanceId++){
14351	            // calculate the world matrix for each instance
14352	            this.getMatrixAt(instanceId, _instanceLocalMatrix);
14353	            _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix);
14354	            // the mesh represents this single instance
14355	            _mesh$1.matrixWorld = _instanceWorldMatrix;
14356	            _mesh$1.raycast(raycaster, _instanceIntersects);
14357	            // process the result of raycast
14358	            for(let i = 0, l = _instanceIntersects.length; i < l; i++){
14359	                const intersect = _instanceIntersects[i];
14360	                intersect.instanceId = instanceId;
14361	                intersect.object = this;
14362	                intersects.push(intersect);
14363	            }
14364	            _instanceIntersects.length = 0;
14365	        }
14366	    }
14367	    /**
14368		 * Sets the given color to the defined instance. Make sure you set the `needsUpdate` flag of
14369		 * {@link InstancedMesh#instanceColor} to `true` after updating all the colors.
14370		 *
14371		 * @param {number} index - The instance index.
14372		 * @param {Color} color - The instance color.
14373		 */ setColorAt(index, color) {
14374	        if (this.instanceColor === null) {
14375	            this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3).fill(1), 3);
14376	        }
14377	        color.toArray(this.instanceColor.array, index * 3);
14378	    }
14379	    /**
14380		 * Sets the given local transformation matrix to the defined instance. Make sure you set the `needsUpdate` flag of
14381		 * {@link InstancedMesh#instanceMatrix} to `true` after updating all the colors.
14382		 *
14383		 * @param {number} index - The instance index.
14384		 * @param {Matrix4} matrix - The the local transformation.
14385		 */ setMatrixAt(index, matrix) {
14386	        matrix.toArray(this.instanceMatrix.array, index * 16);
14387	    }
14388	    /**
14389		 * Sets the morph target weights to the defined instance. Make sure you set the `needsUpdate` flag of
14390		 * {@link InstancedMesh#morphTexture} to `true` after updating all the influences.
14391		 *
14392		 * @param {number} index - The instance index.
14393		 * @param {Mesh} object -  A mesh which `morphTargetInfluences` property containing the morph target weights
14394		 * of a single instance.
14395		 */ setMorphAt(index, object) {
14396	        const objectInfluences = object.morphTargetInfluences;
14397	        const len = objectInfluences.length + 1; // morphBaseInfluence + all influences
14398	        if (this.morphTexture === null) {
14399	            this.morphTexture = new DataTexture(new Float32Array(len * this.count), len, this.count, RedFormat, FloatType);
14400	        }
14401	        const array = this.morphTexture.source.data.data;
14402	        let morphInfluencesSum = 0;
14403	        for(let i = 0; i < objectInfluences.length; i++){
14404	            morphInfluencesSum += objectInfluences[i];
14405	        }
14406	        const morphBaseInfluence = this.geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
14407	        const dataIndex = len * index;
14408	        array[dataIndex] = morphBaseInfluence;
14409	        array.set(objectInfluences, dataIndex + 1);
14410	    }
14411	    updateMorphTargets() {}
14412	    /**
14413		 * Frees the GPU-related resources allocated by this instance. Call this
14414		 * method whenever this instance is no longer used in your app.
14415		 */ dispose() {
14416	        this.dispatchEvent({
14417	            type: 'dispose'
14418	        });
14419	        if (this.morphTexture !== null) {
14420	            this.morphTexture.dispose();
14421	            this.morphTexture = null;
14422	        }
14423	    }
14424	    /**
14425		 * Constructs a new instanced mesh.
14426		 *
14427		 * @param {BufferGeometry} [geometry] - The mesh geometry.
14428		 * @param {Material|Array<Material>} [material] - The mesh material.
14429		 * @param {number} count - The number of instances.
14430		 */ constructor(geometry, material, count){
14431	        super(geometry, material);
14432	        /**
14433			 * This flag can be used for type testing.
14434			 *
14435			 * @type {boolean}
14436			 * @readonly
14437			 * @default true
14438			 */ this.isInstancedMesh = true;
14439	        /**
14440			 * Represents the local transformation of all instances. You have to set its
14441			 * {@link BufferAttribute#needsUpdate} flag to true if you modify instanced data
14442			 * via {@link InstancedMesh#setMatrixAt}.
14443			 *
14444			 * @type {InstancedBufferAttribute}
14445			 */ this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16);
14446	        /**
14447			 * Represents the color of all instances. You have to set its
14448			 * {@link BufferAttribute#needsUpdate} flag to true if you modify instanced data
14449			 * via {@link InstancedMesh#setColorAt}.
14450			 *
14451			 * @type {?InstancedBufferAttribute}
14452			 * @default null
14453			 */ this.instanceColor = null;
14454	        /**
14455			 * Represents the morph target weights of all instances. You have to set its
14456			 * {@link Texture#needsUpdate} flag to true if you modify instanced data
14457			 * via {@link InstancedMesh#setMorphAt}.
14458			 *
14459			 * @type {?InstancedBufferAttribute}
14460			 * @default null
14461			 */ this.morphTexture = null;
14462	        /**
14463			 * The number of instances.
14464			 *
14465			 * @type {number}
14466			 */ this.count = count;
14467	        /**
14468			 * The bounding box of the instanced mesh. Can be computed via {@link InstancedMesh#computeBoundingBox}.
14469			 *
14470			 * @type {?Box3}
14471			 * @default null
14472			 */ this.boundingBox = null;
14473	        /**
14474			 * The bounding sphere of the instanced mesh. Can be computed via {@link InstancedMesh#computeBoundingSphere}.
14475			 *
14476			 * @type {?Sphere}
14477			 * @default null
14478			 */ this.boundingSphere = null;
14479	        for(let i = 0; i < count; i++){
14480	            this.setMatrixAt(i, _identity);
14481	        }
14482	    }
14483	}
14484	const _vector1 = /*@__PURE__*/ new Vector3();
14485	const _vector2 = /*@__PURE__*/ new Vector3();
14486	const _normalMatrix = /*@__PURE__*/ new Matrix3();
14487	/**
14488	 * A two dimensional surface that extends infinitely in 3D space, represented
14489	 * in [Hessian normal form]{@link http://mathworld.wolfram.com/HessianNormalForm.html}
14490	 * by a unit length normal vector and a constant.
14491	 */ class Plane {
14492	    /**
14493		 * Sets the plane components by copying the given values.
14494		 *
14495		 * @param {Vector3} normal - The normal.
14496		 * @param {number} constant - The constant.
14497		 * @return {Plane} A reference to this plane.
14498		 */ set(normal, constant) {
14499	        this.normal.copy(normal);
14500	        this.constant = constant;
14501	        return this;
14502	    }
14503	    /**
14504		 * Sets the plane components by defining `x`, `y`, `z` as the
14505		 * plane normal and `w` as the constant.
14506		 *
14507		 * @param {number} x - The value for the normal's x component.
14508		 * @param {number} y - The value for the normal's y component.
14509		 * @param {number} z - The value for the normal's z component.
14510		 * @param {number} w - The constant value.
14511		 * @return {Plane} A reference to this plane.
14512		 */ setComponents(x, y, z, w) {
14513	        this.normal.set(x, y, z);
14514	        this.constant = w;
14515	        return this;
14516	    }
14517	    /**
14518		 * Sets the plane from the given normal and coplanar point (that is a point
14519		 * that lies onto the plane).
14520		 *
14521		 * @param {Vector3} normal - The normal.
14522		 * @param {Vector3} point - A coplanar point.
14523		 * @return {Plane} A reference to this plane.
14524		 */ setFromNormalAndCoplanarPoint(normal, point) {
14525	        this.normal.copy(normal);
14526	        this.constant = -point.dot(this.normal);
14527	        return this;
14528	    }
14529	    /**
14530		 * Sets the plane from three coplanar points. The winding order is
14531		 * assumed to be counter-clockwise, and determines the direction of
14532		 * the plane normal.
14533		 *
14534		 * @param {Vector3} a - The first coplanar point.
14535		 * @param {Vector3} b - The second coplanar point.
14536		 * @param {Vector3} c - The third coplanar point.
14537		 * @return {Plane} A reference to this plane.
14538		 */ setFromCoplanarPoints(a, b, c) {
14539	        const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize();
14540	        // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
14541	        this.setFromNormalAndCoplanarPoint(normal, a);
14542	        return this;
14543	    }
14544	    /**
14545		 * Copies the values of the given plane to this instance.
14546		 *
14547		 * @param {Plane} plane - The plane to copy.
14548		 * @return {Plane} A reference to this plane.
14549		 */ copy(plane) {
14550	        this.normal.copy(plane.normal);
14551	        this.constant = plane.constant;
14552	        return this;
14553	    }
14554	    /**
14555		 * Normalizes the plane normal and adjusts the constant accordingly.
14556		 *
14557		 * @return {Plane} A reference to this plane.
14558		 */ normalize() {
14559	        // Note: will lead to a divide by zero if the plane is invalid.
14560	        const inverseNormalLength = 1.0 / this.normal.length();
14561	        this.normal.multiplyScalar(inverseNormalLength);
14562	        this.constant *= inverseNormalLength;
14563	        return this;
14564	    }
14565	    /**
14566		 * Negates both the plane normal and the constant.
14567		 *
14568		 * @return {Plane} A reference to this plane.
14569		 */ negate() {
14570	        this.constant *= -1;
14571	        this.normal.negate();
14572	        return this;
14573	    }
14574	    /**
14575		 * Returns the signed distance from the given point to this plane.
14576		 *
14577		 * @param {Vector3} point - The point to compute the distance for.
14578		 * @return {number} The signed distance.
14579		 */ distanceToPoint(point) {
14580	        return this.normal.dot(point) + this.constant;
14581	    }
14582	    /**
14583		 * Returns the signed distance from the given sphere to this plane.
14584		 *
14585		 * @param {Sphere} sphere - The sphere to compute the distance for.
14586		 * @return {number} The signed distance.
14587		 */ distanceToSphere(sphere) {
14588	        return this.distanceToPoint(sphere.center) - sphere.radius;
14589	    }
14590	    /**
14591		 * Projects a the given point onto the plane.
14592		 *
14593		 * @param {Vector3} point - The point to project.
14594		 * @param {Vector3} target - The target vector that is used to store the method's result.
14595		 * @return {Vector3} The projected point on the plane.
14596		 */ projectPoint(point, target) {
14597	        return target.copy(point).addScaledVector(this.normal, -this.distanceToPoint(point));
14598	    }
14599	    /**
14600		 * Returns the intersection point of the passed line and the plane. Returns
14601		 * `null` if the line does not intersect. Returns the line's starting point if
14602		 * the line is coplanar with the plane.
14603		 *
14604		 * @param {Line3} line - The line to compute the intersection for.
14605		 * @param {Vector3} target - The target vector that is used to store the method's result.
14606		 * @return {?Vector3} The intersection point.
14607		 */ intersectLine(line, target) {
14608	        const direction = line.delta(_vector1);
14609	        const denominator = this.normal.dot(direction);
14610	        if (denominator === 0) {
14611	            // line is coplanar, return origin
14612	            if (this.distanceToPoint(line.start) === 0) {
14613	                return target.copy(line.start);
14614	            }
14615	            // Unsure if this is the correct method to handle this case.
14616	            return null;
14617	        }
14618	        const t = -(line.start.dot(this.normal) + this.constant) / denominator;
14619	        if (t < 0 || t > 1) {
14620	            return null;
14621	        }
14622	        return target.copy(line.start).addScaledVector(direction, t);
14623	    }
14624	    /**
14625		 * Returns `true` if the given line segment intersects with (passes through) the plane.
14626		 *
14627		 * @param {Line3} line - The line to test.
14628		 * @return {boolean} Whether the given line segment intersects with the plane or not.
14629		 */ intersectsLine(line) {
14630	        // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
14631	        const startSign = this.distanceToPoint(line.start);
14632	        const endSign = this.distanceToPoint(line.end);
14633	        return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
14634	    }
14635	    /**
14636		 * Returns `true` if the given bounding box intersects with the plane.
14637		 *
14638		 * @param {Box3} box - The bounding box to test.
14639		 * @return {boolean} Whether the given bounding box intersects with the plane or not.
14640		 */ intersectsBox(box) {
14641	        return box.intersectsPlane(this);
14642	    }
14643	    /**
14644		 * Returns `true` if the given bounding sphere intersects with the plane.
14645		 *
14646		 * @param {Sphere} sphere - The bounding sphere to test.
14647		 * @return {boolean} Whether the given bounding sphere intersects with the plane or not.
14648		 */ intersectsSphere(sphere) {
14649	        return sphere.intersectsPlane(this);
14650	    }
14651	    /**
14652		 * Returns a coplanar vector to the plane, by calculating the
14653		 * projection of the normal at the origin onto the plane.
14654		 *
14655		 * @param {Vector3} target - The target vector that is used to store the method's result.
14656		 * @return {Vector3} The coplanar point.
14657		 */ coplanarPoint(target) {
14658	        return target.copy(this.normal).multiplyScalar(-this.constant);
14659	    }
14660	    /**
14661		 * Apply a 4x4 matrix to the plane. The matrix must be an affine, homogeneous transform.
14662		 *
14663		 * The optional normal matrix can be pre-computed like so:
14664		 * ```js
14665		 * const optionalNormalMatrix = new THREE.Matrix3().getNormalMatrix( matrix );
14666		 * ```
14667		 *
14668		 * @param {Matrix4} matrix - The transformation matrix.
14669		 * @param {Matrix4} [optionalNormalMatrix] - A pre-computed normal matrix.
14670		 * @return {Plane} A reference to this plane.
14671		 */ applyMatrix4(matrix, optionalNormalMatrix) {
14672	        const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
14673	        const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
14674	        const normal = this.normal.applyMatrix3(normalMatrix).normalize();
14675	        this.constant = -referencePoint.dot(normal);
14676	        return this;
14677	    }
14678	    /**
14679		 * Translates the plane by the distance defined by the given offset vector.
14680		 * Note that this only affects the plane constant and will not affect the normal vector.
14681		 *
14682		 * @param {Vector3} offset - The offset vector.
14683		 * @return {Plane} A reference to this plane.
14684		 */ translate(offset) {
14685	        this.constant -= offset.dot(this.normal);
14686	        return this;
14687	    }
14688	    /**
14689		 * Returns `true` if this plane is equal with the given one.
14690		 *
14691		 * @param {Plane} plane - The plane to test for equality.
14692		 * @return {boolean} Whether this plane is equal with the given one.
14693		 */ equals(plane) {
14694	        return plane.normal.equals(this.normal) && plane.constant === this.constant;
14695	    }
14696	    /**
14697		 * Returns a new plane with copied values from this instance.
14698		 *
14699		 * @return {Plane} A clone of this instance.
14700		 */ clone() {
14701	        return new this.constructor().copy(this);
14702	    }
14703	    /**
14704		 * Constructs a new plane.
14705		 *
14706		 * @param {Vector3} [normal=(1,0,0)] - A unit length vector defining the normal of the plane.
14707		 * @param {number} [constant=0] - The signed distance from the origin to the plane.
14708		 */ constructor(normal = new Vector3(1, 0, 0), constant = 0){
14709	        /**
14710			 * This flag can be used for type testing.
14711			 *
14712			 * @type {boolean}
14713			 * @readonly
14714			 * @default true
14715			 */ this.isPlane = true;
14716	        /**
14717			 * A unit length vector defining the normal of the plane.
14718			 *
14719			 * @type {Vector3}
14720			 */ this.normal = normal;
14721	        /**
14722			 * The signed distance from the origin to the plane.
14723			 *
14724			 * @type {number}
14725			 * @default 0
14726			 */ this.constant = constant;
14727	    }
14728	}
14729	const _sphere$3 = /*@__PURE__*/ new Sphere();
14730	const _vector$6 = /*@__PURE__*/ new Vector3();
14731	/**
14732	 * Frustums are used to determine what is inside the camera's field of view.
14733	 * They help speed up the rendering process - objects which lie outside a camera's
14734	 * frustum can safely be excluded from rendering.
14735	 *
14736	 * This class is mainly intended for use internally by a renderer.
14737	 */ class Frustum {
14738	    /**
vendor: 4,611 bytes, lines 14739-14835
14739		 * Sets the frustum planes by copying the given planes.
14740		 *
14741		 * @param {Plane} [p0] - The first plane that encloses the frustum.
14742		 * @param {Plane} [p1] - The second plane that encloses the frustum.
14743		 * @param {Plane} [p2] - The third plane that encloses the frustum.
14744		 * @param {Plane} [p3] - The fourth plane that encloses the frustum.
14745		 * @param {Plane} [p4] - The fifth plane that encloses the frustum.
14746		 * @param {Plane} [p5] - The sixth plane that encloses the frustum.
14747		 * @return {Frustum} A reference to this frustum.
14748		 */ set(p0, p1, p2, p3, p4, p5) {
14749	        const planes = this.planes;
14750	        planes[0].copy(p0);
14751	        planes[1].copy(p1);
14752	        planes[2].copy(p2);
14753	        planes[3].copy(p3);
14754	        planes[4].copy(p4);
14755	        planes[5].copy(p5);
14756	        return this;
14757	    }
14758	    /**
14759		 * Copies the values of the given frustum to this instance.
14760		 *
14761		 * @param {Frustum} frustum - The frustum to copy.
14762		 * @return {Frustum} A reference to this frustum.
14763		 */ copy(frustum) {
14764	        const planes = this.planes;
14765	        for(let i = 0; i < 6; i++){
14766	            planes[i].copy(frustum.planes[i]);
14767	        }
14768	        return this;
14769	    }
14770	    /**
14771		 * Sets the frustum planes from the given projection matrix.
14772		 *
14773		 * @param {Matrix4} m - The projection matrix.
14774		 * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} coordinateSystem - The coordinate system.
14775		 * @return {Frustum} A reference to this frustum.
14776		 */ setFromProjectionMatrix(m, coordinateSystem = WebGLCoordinateSystem) {
14777	        const planes = this.planes;
14778	        const me = m.elements;
14779	        const me0 = me[0], me1 = me[1], me2 = me[2], me3 = me[3];
14780	        const me4 = me[4], me5 = me[5], me6 = me[6], me7 = me[7];
14781	        const me8 = me[8], me9 = me[9], me10 = me[10], me11 = me[11];
14782	        const me12 = me[12], me13 = me[13], me14 = me[14], me15 = me[15];
14783	        planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize();
14784	        planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize();
14785	        planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize();
14786	        planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize();
14787	        planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize();
14788	        if (coordinateSystem === WebGLCoordinateSystem) {
14789	            planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize();
14790	        } else if (coordinateSystem === WebGPUCoordinateSystem) {
14791	            planes[5].setComponents(me2, me6, me10, me14).normalize();
14792	        } else {
14793	            throw new Error('THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: ' + coordinateSystem);
14794	        }
14795	        return this;
14796	    }
14797	    /**
14798		 * Returns `true` if the 3D object's bounding sphere is intersecting this frustum.
14799		 *
14800		 * Note that the 3D object must have a geometry so that the bounding sphere can be calculated.
14801		 *
14802		 * @param {Object3D} object - The 3D object to test.
14803		 * @return {boolean} Whether the 3D object's bounding sphere is intersecting this frustum or not.
14804		 */ intersectsObject(object) {
14805	        if (object.boundingSphere !== undefined) {
14806	            if (object.boundingSphere === null) object.computeBoundingSphere();
14807	            _sphere$3.copy(object.boundingSphere).applyMatrix4(object.matrixWorld);
14808	        } else {
14809	            const geometry = object.geometry;
14810	            if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
14811	            _sphere$3.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld);
14812	        }
14813	        return this.intersectsSphere(_sphere$3);
14814	    }
14815	    /**
14816		 * Returns `true` if the given sprite is intersecting this frustum.
14817		 *
14818		 * @param {Sprite} sprite - The sprite to test.
14819		 * @return {boolean} Whether the sprite is intersecting this frustum or not.
14820		 */ intersectsSprite(sprite) {
14821	        _sphere$3.center.set(0, 0, 0);
14822	        _sphere$3.radius = 0.7071067811865476;
14823	        _sphere$3.applyMatrix4(sprite.matrixWorld);
14824	        return this.intersectsSphere(_sphere$3);
14825	    }
14826	    /**
14827		 * Returns `true` if the given bounding sphere is intersecting this frustum.
14828		 *
14829		 * @param {Sphere} sphere - The bounding sphere to test.
14830		 * @return {boolean} Whether the bounding sphere is intersecting this frustum or not.
14831		 */ intersectsSphere(sphere) {
14832	        const planes = this.planes;
14833	        const center = sphere.center;
14834	        const negRadius = -sphere.radius;
14835	        for(let i = 0; i < 6; i++){
vendor: 21,668 bytes, lines 14836-15382
14836	            const distance = planes[i].distanceToPoint(center);
14837	            if (distance < negRadius) {
14838	                return false;
14839	            }
14840	        }
14841	        return true;
14842	    }
14843	    /**
14844		 * Returns `true` if the given bounding box is intersecting this frustum.
14845		 *
14846		 * @param {Box3} box - The bounding box to test.
14847		 * @return {boolean} Whether the bounding box is intersecting this frustum or not.
14848		 */ intersectsBox(box) {
14849	        const planes = this.planes;
14850	        for(let i = 0; i < 6; i++){
14851	            const plane = planes[i];
14852	            // corner at max distance
14853	            _vector$6.x = plane.normal.x > 0 ? box.max.x : box.min.x;
14854	            _vector$6.y = plane.normal.y > 0 ? box.max.y : box.min.y;
14855	            _vector$6.z = plane.normal.z > 0 ? box.max.z : box.min.z;
14856	            if (plane.distanceToPoint(_vector$6) < 0) {
14857	                return false;
14858	            }
14859	        }
14860	        return true;
14861	    }
14862	    /**
14863		 * Returns `true` if the given point lies within the frustum.
14864		 *
14865		 * @param {Vector3} point - The point to test.
14866		 * @return {boolean} Whether the point lies within this frustum or not.
14867		 */ containsPoint(point) {
14868	        const planes = this.planes;
14869	        for(let i = 0; i < 6; i++){
14870	            if (planes[i].distanceToPoint(point) < 0) {
14871	                return false;
14872	            }
14873	        }
14874	        return true;
14875	    }
14876	    /**
14877		 * Returns a new frustum with copied values from this instance.
14878		 *
14879		 * @return {Frustum} A clone of this instance.
14880		 */ clone() {
14881	        return new this.constructor().copy(this);
14882	    }
14883	    /**
14884		 * Constructs a new frustum.
14885		 *
14886		 * @param {Plane} [p0] - The first plane that encloses the frustum.
14887		 * @param {Plane} [p1] - The second plane that encloses the frustum.
14888		 * @param {Plane} [p2] - The third plane that encloses the frustum.
14889		 * @param {Plane} [p3] - The fourth plane that encloses the frustum.
14890		 * @param {Plane} [p4] - The fifth plane that encloses the frustum.
14891		 * @param {Plane} [p5] - The sixth plane that encloses the frustum.
14892		 */ constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()){
14893	        /**
14894			 * This array holds the planes that enclose the frustum.
14895			 *
14896			 * @type {Array<Plane>}
14897			 */ this.planes = [
14898	            p0,
14899	            p1,
14900	            p2,
14901	            p3,
14902	            p4,
14903	            p5
14904	        ];
14905	    }
14906	}
14907	class LineBasicMaterial extends Material$1 {
14908	    copy(source) {
14909	        super.copy(source);
14910	        this.color.copy(source.color);
14911	        this.map = source.map;
14912	        this.linewidth = source.linewidth;
14913	        this.linecap = source.linecap;
14914	        this.linejoin = source.linejoin;
14915	        this.fog = source.fog;
14916	        return this;
14917	    }
14918	    constructor(parameters){
14919	        super();
14920	        this.isLineBasicMaterial = true;
14921	        this.type = 'LineBasicMaterial';
14922	        this.color = new Color(0xffffff);
14923	        this.map = null;
14924	        this.linewidth = 1;
14925	        this.linecap = 'round';
14926	        this.linejoin = 'round';
14927	        this.fog = true;
14928	        this.setValues(parameters);
14929	    }
14930	}
14931	const _vStart = /*@__PURE__*/ new Vector3();
14932	const _vEnd = /*@__PURE__*/ new Vector3();
14933	const _inverseMatrix$1 = /*@__PURE__*/ new Matrix4();
14934	const _ray$1 = /*@__PURE__*/ new Ray();
14935	const _sphere$1 = /*@__PURE__*/ new Sphere();
14936	const _intersectPointOnRay = /*@__PURE__*/ new Vector3();
14937	const _intersectPointOnSegment = /*@__PURE__*/ new Vector3();
14938	/**
14939	 * A continuous line. The line are rendered by connecting consecutive
14940	 * vertices with straight lines.
14941	 *
14942	 * ```js
14943	 * const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );
14944	 *
14945	 * const points = [];
14946	 * points.push( new THREE.Vector3( - 10, 0, 0 ) );
14947	 * points.push( new THREE.Vector3( 0, 10, 0 ) );
14948	 * points.push( new THREE.Vector3( 10, 0, 0 ) );
14949	 *
14950	 * const geometry = new THREE.BufferGeometry().setFromPoints( points );
14951	 *
14952	 * const line = new THREE.Line( geometry, material );
14953	 * scene.add( line );
14954	 * ```
14955	 *
14956	 * @augments Object3D
14957	 */ class Line extends Object3D {
14958	    copy(source, recursive) {
14959	        super.copy(source, recursive);
14960	        this.material = Array.isArray(source.material) ? source.material.slice() : source.material;
14961	        this.geometry = source.geometry;
14962	        return this;
14963	    }
14964	    /**
14965		 * Computes an array of distance values which are necessary for rendering dashed lines.
14966		 * For each vertex in the geometry, the method calculates the cumulative length from the
14967		 * current point to the very beginning of the line.
14968		 *
14969		 * @return {Line} A reference to this line.
14970		 */ computeLineDistances() {
14971	        const geometry = this.geometry;
14972	        // we assume non-indexed geometry
14973	        if (geometry.index === null) {
14974	            const positionAttribute = geometry.attributes.position;
14975	            const lineDistances = [
14976	                0
14977	            ];
14978	            for(let i = 1, l = positionAttribute.count; i < l; i++){
14979	                _vStart.fromBufferAttribute(positionAttribute, i - 1);
14980	                _vEnd.fromBufferAttribute(positionAttribute, i);
14981	                lineDistances[i] = lineDistances[i - 1];
14982	                lineDistances[i] += _vStart.distanceTo(_vEnd);
14983	            }
14984	            geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
14985	        } else {
14986	            console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
14987	        }
14988	        return this;
14989	    }
14990	    /**
14991		 * Computes intersection points between a casted ray and this line.
14992		 *
14993		 * @param {Raycaster} raycaster - The raycaster.
14994		 * @param {Array<Object>} intersects - The target array that holds the intersection points.
14995		 */ raycast(raycaster, intersects) {
14996	        const geometry = this.geometry;
14997	        const matrixWorld = this.matrixWorld;
14998	        const threshold = raycaster.params.Line.threshold;
14999	        const drawRange = geometry.drawRange;
15000	        // Checking boundingSphere distance to ray
15001	        if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
15002	        _sphere$1.copy(geometry.boundingSphere);
15003	        _sphere$1.applyMatrix4(matrixWorld);
15004	        _sphere$1.radius += threshold;
15005	        if (raycaster.ray.intersectsSphere(_sphere$1) === false) return;
15006	        //
15007	        _inverseMatrix$1.copy(matrixWorld).invert();
15008	        _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1);
15009	        const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
15010	        const localThresholdSq = localThreshold * localThreshold;
15011	        const step = this.isLineSegments ? 2 : 1;
15012	        const index = geometry.index;
15013	        const attributes = geometry.attributes;
15014	        const positionAttribute = attributes.position;
15015	        if (index !== null) {
15016	            const start = Math.max(0, drawRange.start);
15017	            const end = Math.min(index.count, drawRange.start + drawRange.count);
15018	            for(let i = start, l = end - 1; i < l; i += step){
15019	                const a = index.getX(i);
15020	                const b = index.getX(i + 1);
15021	                const intersect = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a, b, i);
15022	                if (intersect) {
15023	                    intersects.push(intersect);
15024	                }
15025	            }
15026	            if (this.isLineLoop) {
15027	                const a = index.getX(end - 1);
15028	                const b = index.getX(start);
15029	                const intersect = checkIntersection(this, raycaster, _ray$1, localThresholdSq, a, b, end - 1);
15030	                if (intersect) {
15031	                    intersects.push(intersect);
15032	                }
15033	            }
15034	        } else {
15035	            const start = Math.max(0, drawRange.start);
15036	            const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
15037	            for(let i = start, l = end - 1; i < l; i += step){
15038	                const intersect = checkIntersection(this, raycaster, _ray$1, localThresholdSq, i, i + 1, i);
15039	                if (intersect) {
15040	                    intersects.push(intersect);
15041	                }
15042	            }
15043	            if (this.isLineLoop) {
15044	                const intersect = checkIntersection(this, raycaster, _ray$1, localThresholdSq, end - 1, start, end - 1);
15045	                if (intersect) {
15046	                    intersects.push(intersect);
15047	                }
15048	            }
15049	        }
15050	    }
15051	    /**
15052		 * Sets the values of {@link Line#morphTargetDictionary} and {@link Line#morphTargetInfluences}
15053		 * to make sure existing morph targets can influence this 3D object.
15054		 */ updateMorphTargets() {
15055	        const geometry = this.geometry;
15056	        const morphAttributes = geometry.morphAttributes;
15057	        const keys = Object.keys(morphAttributes);
15058	        if (keys.length > 0) {
15059	            const morphAttribute = morphAttributes[keys[0]];
15060	            if (morphAttribute !== undefined) {
15061	                this.morphTargetInfluences = [];
15062	                this.morphTargetDictionary = {};
15063	                for(let m = 0, ml = morphAttribute.length; m < ml; m++){
15064	                    const name = morphAttribute[m].name || String(m);
15065	                    this.morphTargetInfluences.push(0);
15066	                    this.morphTargetDictionary[name] = m;
15067	                }
15068	            }
15069	        }
15070	    }
15071	    /**
15072		 * Constructs a new line.
15073		 *
15074		 * @param {BufferGeometry} [geometry] - The line geometry.
15075		 * @param {Material|Array<Material>} [material] - The line material.
15076		 */ constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()){
15077	        super();
15078	        /**
15079			 * This flag can be used for type testing.
15080			 *
15081			 * @type {boolean}
15082			 * @readonly
15083			 * @default true
15084			 */ this.isLine = true;
15085	        this.type = 'Line';
15086	        /**
15087			 * The line geometry.
15088			 *
15089			 * @type {BufferGeometry}
15090			 */ this.geometry = geometry;
15091	        /**
15092			 * The line material.
15093			 *
15094			 * @type {Material|Array<Material>}
15095			 * @default LineBasicMaterial
15096			 */ this.material = material;
15097	        /**
15098			 * A dictionary representing the morph targets in the geometry. The key is the
15099			 * morph targets name, the value its attribute index. This member is `undefined`
15100			 * by default and only set when morph targets are detected in the geometry.
15101			 *
15102			 * @type {Object<String,number>|undefined}
15103			 * @default undefined
15104			 */ this.morphTargetDictionary = undefined;
15105	        /**
15106			 * An array of weights typically in the range `[0,1]` that specify how much of the morph
15107			 * is applied. This member is `undefined` by default and only set when morph targets are
15108			 * detected in the geometry.
15109			 *
15110			 * @type {Array<number>|undefined}
15111			 * @default undefined
15112			 */ this.morphTargetInfluences = undefined;
15113	        this.updateMorphTargets();
15114	    }
15115	}
15116	function checkIntersection(object, raycaster, ray, thresholdSq, a, b, i) {
15117	    const positionAttribute = object.geometry.attributes.position;
15118	    _vStart.fromBufferAttribute(positionAttribute, a);
15119	    _vEnd.fromBufferAttribute(positionAttribute, b);
15120	    const distSq = ray.distanceSqToSegment(_vStart, _vEnd, _intersectPointOnRay, _intersectPointOnSegment);
15121	    if (distSq > thresholdSq) return;
15122	    _intersectPointOnRay.applyMatrix4(object.matrixWorld); // Move back to world space for distance calculation
15123	    const distance = raycaster.ray.origin.distanceTo(_intersectPointOnRay);
15124	    if (distance < raycaster.near || distance > raycaster.far) return;
15125	    return {
15126	        distance: distance,
15127	        // What do we want? intersection point on the ray or on the segment??
15128	        // point: raycaster.ray.at( distance ),
15129	        point: _intersectPointOnSegment.clone().applyMatrix4(object.matrixWorld),
15130	        index: i,
15131	        face: null,
15132	        faceIndex: null,
15133	        barycoord: null,
15134	        object: object
15135	    };
15136	}
15137	const _start = /*@__PURE__*/ new Vector3();
15138	const _end = /*@__PURE__*/ new Vector3();
15139	/**
15140	 * A series of lines drawn between pairs of vertices.
15141	 *
15142	 * @augments Line
15143	 */ class LineSegments extends Line {
15144	    computeLineDistances() {
15145	        const geometry = this.geometry;
15146	        // we assume non-indexed geometry
15147	        if (geometry.index === null) {
15148	            const positionAttribute = geometry.attributes.position;
15149	            const lineDistances = [];
15150	            for(let i = 0, l = positionAttribute.count; i < l; i += 2){
15151	                _start.fromBufferAttribute(positionAttribute, i);
15152	                _end.fromBufferAttribute(positionAttribute, i + 1);
15153	                lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1];
15154	                lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end);
15155	            }
15156	            geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
15157	        } else {
15158	            console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
15159	        }
15160	        return this;
15161	    }
15162	    /**
15163		 * Constructs a new line segments.
15164		 *
15165		 * @param {BufferGeometry} [geometry] - The line geometry.
15166		 * @param {Material|Array<Material>} [material] - The line material.
15167		 */ constructor(geometry, material){
15168	        super(geometry, material);
15169	        /**
15170			 * This flag can be used for type testing.
15171			 *
15172			 * @type {boolean}
15173			 * @readonly
15174			 * @default true
15175			 */ this.isLineSegments = true;
15176	        this.type = 'LineSegments';
15177	    }
15178	}
15179	/**
15180	 * A continuous line. This is nearly the same as {@link Line} the only difference
15181	 * is that the last vertex is connected with the first vertex in order to close
15182	 * the line to form a loop.
15183	 *
15184	 * @augments Line
15185	 */ class LineLoop extends Line {
15186	    /**
15187		 * Constructs a new line loop.
15188		 *
15189		 * @param {BufferGeometry} [geometry] - The line geometry.
15190		 * @param {Material|Array<Material>} [material] - The line material.
15191		 */ constructor(geometry, material){
15192	        super(geometry, material);
15193	        /**
15194			 * This flag can be used for type testing.
15195			 *
15196			 * @type {boolean}
15197			 * @readonly
15198			 * @default true
15199			 */ this.isLineLoop = true;
15200	        this.type = 'LineLoop';
15201	    }
15202	}
15203	class PointsMaterial extends Material$1 {
15204	    copy(source) {
15205	        super.copy(source);
15206	        this.color.copy(source.color);
15207	        this.map = source.map;
15208	        this.alphaMap = source.alphaMap;
15209	        this.size = source.size;
15210	        this.sizeAttenuation = source.sizeAttenuation;
15211	        this.fog = source.fog;
15212	        return this;
15213	    }
15214	    constructor(parameters){
15215	        super();
15216	        this.isPointsMaterial = true;
15217	        this.type = 'PointsMaterial';
15218	        this.color = new Color(0xffffff);
15219	        this.map = null;
15220	        this.alphaMap = null;
15221	        this.size = 1;
15222	        this.sizeAttenuation = true;
15223	        this.fog = true;
15224	        this.setValues(parameters);
15225	    }
15226	}
15227	const _inverseMatrix = /*@__PURE__*/ new Matrix4();
15228	const _ray = /*@__PURE__*/ new Ray();
15229	const _sphere = /*@__PURE__*/ new Sphere();
15230	const _position$2 = /*@__PURE__*/ new Vector3();
15231	/**
15232	 * A class for displaying points or point clouds.
15233	 *
15234	 * @augments Object3D
15235	 */ class Points extends Object3D {
15236	    copy(source, recursive) {
15237	        super.copy(source, recursive);
15238	        this.material = Array.isArray(source.material) ? source.material.slice() : source.material;
15239	        this.geometry = source.geometry;
15240	        return this;
15241	    }
15242	    /**
15243		 * Computes intersection points between a casted ray and this point cloud.
15244		 *
15245		 * @param {Raycaster} raycaster - The raycaster.
15246		 * @param {Array<Object>} intersects - The target array that holds the intersection points.
15247		 */ raycast(raycaster, intersects) {
15248	        const geometry = this.geometry;
15249	        const matrixWorld = this.matrixWorld;
15250	        const threshold = raycaster.params.Points.threshold;
15251	        const drawRange = geometry.drawRange;
15252	        // Checking boundingSphere distance to ray
15253	        if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
15254	        _sphere.copy(geometry.boundingSphere);
15255	        _sphere.applyMatrix4(matrixWorld);
15256	        _sphere.radius += threshold;
15257	        if (raycaster.ray.intersectsSphere(_sphere) === false) return;
15258	        //
15259	        _inverseMatrix.copy(matrixWorld).invert();
15260	        _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix);
15261	        const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
15262	        const localThresholdSq = localThreshold * localThreshold;
15263	        const index = geometry.index;
15264	        const attributes = geometry.attributes;
15265	        const positionAttribute = attributes.position;
15266	        if (index !== null) {
15267	            const start = Math.max(0, drawRange.start);
15268	            const end = Math.min(index.count, drawRange.start + drawRange.count);
15269	            for(let i = start, il = end; i < il; i++){
15270	                const a = index.getX(i);
15271	                _position$2.fromBufferAttribute(positionAttribute, a);
15272	                testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this);
15273	            }
15274	        } else {
15275	            const start = Math.max(0, drawRange.start);
15276	            const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
15277	            for(let i = start, l = end; i < l; i++){
15278	                _position$2.fromBufferAttribute(positionAttribute, i);
15279	                testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this);
15280	            }
15281	        }
15282	    }
15283	    /**
15284		 * Sets the values of {@link Points#morphTargetDictionary} and {@link Points#morphTargetInfluences}
15285		 * to make sure existing morph targets can influence this 3D object.
15286		 */ updateMorphTargets() {
15287	        const geometry = this.geometry;
15288	        const morphAttributes = geometry.morphAttributes;
15289	        const keys = Object.keys(morphAttributes);
15290	        if (keys.length > 0) {
15291	            const morphAttribute = morphAttributes[keys[0]];
15292	            if (morphAttribute !== undefined) {
15293	                this.morphTargetInfluences = [];
15294	                this.morphTargetDictionary = {};
15295	                for(let m = 0, ml = morphAttribute.length; m < ml; m++){
15296	                    const name = morphAttribute[m].name || String(m);
15297	                    this.morphTargetInfluences.push(0);
15298	                    this.morphTargetDictionary[name] = m;
15299	                }
15300	            }
15301	        }
15302	    }
15303	    /**
15304		 * Constructs a new point cloud.
15305		 *
15306		 * @param {BufferGeometry} [geometry] - The points geometry.
15307		 * @param {Material|Array<Material>} [material] - The points material.
15308		 */ constructor(geometry = new BufferGeometry(), material = new PointsMaterial()){
15309	        super();
15310	        /**
15311			 * This flag can be used for type testing.
15312			 *
15313			 * @type {boolean}
15314			 * @readonly
15315			 * @default true
15316			 */ this.isPoints = true;
15317	        this.type = 'Points';
15318	        /**
15319			 * The points geometry.
15320			 *
15321			 * @type {BufferGeometry}
15322			 */ this.geometry = geometry;
15323	        /**
15324			 * The line material.
15325			 *
15326			 * @type {Material|Array<Material>}
15327			 * @default PointsMaterial
15328			 */ this.material = material;
15329	        /**
15330			 * A dictionary representing the morph targets in the geometry. The key is the
15331			 * morph targets name, the value its attribute index. This member is `undefined`
15332			 * by default and only set when morph targets are detected in the geometry.
15333			 *
15334			 * @type {Object<String,number>|undefined}
15335			 * @default undefined
15336			 */ this.morphTargetDictionary = undefined;
15337	        /**
15338			 * An array of weights typically in the range `[0,1]` that specify how much of the morph
15339			 * is applied. This member is `undefined` by default and only set when morph targets are
15340			 * detected in the geometry.
15341			 *
15342			 * @type {Array<number>|undefined}
15343			 * @default undefined
15344			 */ this.morphTargetInfluences = undefined;
15345	        this.updateMorphTargets();
15346	    }
15347	}
15348	function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) {
15349	    const rayPointDistanceSq = _ray.distanceSqToPoint(point);
15350	    if (rayPointDistanceSq < localThresholdSq) {
15351	        const intersectPoint = new Vector3();
15352	        _ray.closestPointToPoint(point, intersectPoint);
15353	        intersectPoint.applyMatrix4(matrixWorld);
15354	        const distance = raycaster.ray.origin.distanceTo(intersectPoint);
15355	        if (distance < raycaster.near || distance > raycaster.far) return;
15356	        intersects.push({
15357	            distance: distance,
15358	            distanceToRay: Math.sqrt(rayPointDistanceSq),
15359	            point: intersectPoint,
15360	            index: index,
15361	            face: null,
15362	            faceIndex: null,
15363	            barycoord: null,
15364	            object: object
15365	        });
15366	    }
15367	}
15368	class VideoTexture extends Texture$1 {
15369	    clone() {
15370	        return new this.constructor(this.image).copy(this);
15371	    }
15372	    update() {
15373	        const video = this.image;
15374	        const hasVideoFrameCallback = 'requestVideoFrameCallback' in video;
15375	        if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) {
15376	            this.needsUpdate = true;
15377	        }
15378	    }
15379	    constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy){
15380	        super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
15381	        this.isVideoTexture = true;
15382	        this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
15383	        this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
15384	        this.generateMipmaps = false;
15385	        const scope = this;
15386	        function updateVideo() {
15387	            scope.needsUpdate = true;
15388	            video.requestVideoFrameCallback(updateVideo);
15389	        }
15390	        if ('requestVideoFrameCallback' in video) {
15391	            video.requestVideoFrameCallback(updateVideo);
15392	        }
15393	    }
15394	}
15395	class CompressedTexture extends Texture$1 {
15396	    constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, colorSpace){
15397	        super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace);
15398	        this.isCompressedTexture = true;
15399	        this.image = {
15400	            width: width,
15401	            height: height
15402	        };
15403	        this.mipmaps = mipmaps;
15404	        // no flipping for cube textures
15405	        // (also flipping doesn't work for compressed textures )
15406	        this.flipY = false;
15407	        // can't generate mipmaps for compressed textures
15408	        // mips must be embedded in DDS files
15409	        this.generateMipmaps = false;
15410	    }
15411	}
15412	class CompressedArrayTexture extends CompressedTexture {
15413	    addLayerUpdate(layerIndex) {
15414	        this.layerUpdates.add(layerIndex);
15415	    }
15416	    clearLayerUpdates() {
15417	        this.layerUpdates.clear();
15418	    }
15419	    constructor(mipmaps, width, height, depth, format, type){
15420	        super(mipmaps, width, height, format, type);
15421	        this.isCompressedArrayTexture = true;
15422	        this.image.depth = depth;
15423	        this.wrapR = ClampToEdgeWrapping;
15424	        this.layerUpdates = new Set();
15425	    }
15426	}
15427	class CompressedCubeTexture extends CompressedTexture {
15428	    constructor(images, format, type){
15429	        super(undefined, images[0].width, images[0].height, format, type, CubeReflectionMapping);
15430	        this.isCompressedCubeTexture = true;
15431	        this.isCubeTexture = true;
15432	        this.image = images;
15433	    }
15434	}
15435	class CanvasTexture extends Texture$1 {
15436	    constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy){
15437	        super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
15438	        this.isCanvasTexture = true;
15439	        this.needsUpdate = true;
15440	    }
15441	}
15442	class DepthTexture extends Texture$1 {
15443	    copy(source) {
15444	        super.copy(source);
15445	        this.source = new Source(Object.assign({}, source.image)); // see #30540
15446	        this.compareFunction = source.compareFunction;
15447	        return this;
15448	    }
15449	    toJSON(meta) {
15450	        const data = super.toJSON(meta);
15451	        if (this.compareFunction !== null) data.compareFunction = this.compareFunction;
15452	        return data;
15453	    }
15454	    constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format = DepthFormat){
15455	        if (format !== DepthFormat && format !== DepthStencilFormat) {
15456	            throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat');
15457	        }
15458	        if (type === undefined && format === DepthFormat) type = UnsignedIntType;
15459	        if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type;
15460	        super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
15461	        this.isDepthTexture = true;
15462	        this.image = {
15463	            width: width,
15464	            height: height
15465	        };
15466	        this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
15467	        this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
15468	        this.flipY = false;
15469	        this.generateMipmaps = false;
15470	        this.compareFunction = null;
15471	    }
15472	}
15473	/**
15474	 * A geometry class for representing a plane.
15475	 *
15476	 * ```js
15477	 * const geometry = new THREE.PlaneGeometry( 1, 1 );
15478	 * const material = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
15479	 * const plane = new THREE.Mesh( geometry, material );
15480	 * scene.add( plane );
15481	 * ```
15482	 *
15483	 * @augments BufferGeometry
15484	 */ class PlaneGeometry extends BufferGeometry {
15485	    copy(source) {
15486	        super.copy(source);
15487	        this.parameters = Object.assign({}, source.parameters);
15488	        return this;
15489	    }
15490	    /**
15491		 * Factory method for creating an instance of this class from the given
15492		 * JSON object.
15493		 *
15494		 * @param {Object} data - A JSON object representing the serialized geometry.
15495		 * @return {PlaneGeometry} A new instance.
15496		 */ static fromJSON(data) {
15497	        return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);
15498	    }
15499	    /**
15500		 * Constructs a new plane geometry.
15501		 *
15502		 * @param {number} [width=1] - The width along the X axis.
15503		 * @param {number} [height=1] - The height along the Y axis
15504		 * @param {number} [widthSegments=1] - The number of segments along the X axis.
15505		 * @param {number} [heightSegments=1] - The number of segments along the Y axis.
15506		 */ constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1){
15507	        super();
15508	        this.type = 'PlaneGeometry';
15509	        /**
15510			 * Holds the constructor parameters that have been
15511			 * used to generate the geometry. Any modification
15512			 * after instantiation does not change the geometry.
15513			 *
15514			 * @type {Object}
15515			 */ this.parameters = {
15516	            width: width,
15517	            height: height,
15518	            widthSegments: widthSegments,
15519	            heightSegments: heightSegments
15520	        };
15521	        const width_half = width / 2;
15522	        const height_half = height / 2;
vendor: 15,458 bytes, lines 15523-15923
15523	        const gridX = Math.floor(widthSegments);
15524	        const gridY = Math.floor(heightSegments);
15525	        const gridX1 = gridX + 1;
15526	        const gridY1 = gridY + 1;
15527	        const segment_width = width / gridX;
15528	        const segment_height = height / gridY;
15529	        //
15530	        const indices = [];
15531	        const vertices = [];
15532	        const normals = [];
15533	        const uvs = [];
15534	        for(let iy = 0; iy < gridY1; iy++){
15535	            const y = iy * segment_height - height_half;
15536	            for(let ix = 0; ix < gridX1; ix++){
15537	                const x = ix * segment_width - width_half;
15538	                vertices.push(x, -y, 0);
15539	                normals.push(0, 0, 1);
15540	                uvs.push(ix / gridX);
15541	                uvs.push(1 - iy / gridY);
15542	            }
15543	        }
15544	        for(let iy = 0; iy < gridY; iy++){
15545	            for(let ix = 0; ix < gridX; ix++){
15546	                const a = ix + gridX1 * iy;
15547	                const b = ix + gridX1 * (iy + 1);
15548	                const c = ix + 1 + gridX1 * (iy + 1);
15549	                const d = ix + 1 + gridX1 * iy;
15550	                indices.push(a, b, d);
15551	                indices.push(b, c, d);
15552	            }
15553	        }
15554	        this.setIndex(indices);
15555	        this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
15556	        this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
15557	        this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
15558	    }
15559	}
15560	/**
15561	 * A class for generating a sphere geometry.
15562	 *
15563	 * ```js
15564	 * const geometry = new THREE.SphereGeometry( 15, 32, 16 );
15565	 * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
15566	 * const sphere = new THREE.Mesh( geometry, material );
15567	 * scene.add( sphere );
15568	 * ```
15569	 *
15570	 * @augments BufferGeometry
15571	 */ class SphereGeometry extends BufferGeometry {
15572	    copy(source) {
15573	        super.copy(source);
15574	        this.parameters = Object.assign({}, source.parameters);
15575	        return this;
15576	    }
15577	    /**
15578		 * Factory method for creating an instance of this class from the given
15579		 * JSON object.
15580		 *
15581		 * @param {Object} data - A JSON object representing the serialized geometry.
15582		 * @return {SphereGeometry} A new instance.
15583		 */ static fromJSON(data) {
15584	        return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength);
15585	    }
15586	    /**
15587		 * Constructs a new sphere geometry.
15588		 *
15589		 * @param {number} [radius=1] - The sphere radius.
15590		 * @param {number} [widthSegments=32] - The number of horizontal segments. Minimum value is `3`.
15591		 * @param {number} [heightSegments=16] - The number of vertical segments. Minimum value is `2`.
15592		 * @param {number} [phiStart=0] - The horizontal starting angle in radians.
15593		 * @param {number} [phiLength=Math.PI*2] - The horizontal sweep angle size.
15594		 * @param {number} [thetaStart=0] - The vertical starting angle in radians.
15595		 * @param {number} [thetaLength=Math.PI] - The vertical sweep angle size.
15596		 */ constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI){
15597	        super();
15598	        this.type = 'SphereGeometry';
15599	        /**
15600			 * Holds the constructor parameters that have been
15601			 * used to generate the geometry. Any modification
15602			 * after instantiation does not change the geometry.
15603			 *
15604			 * @type {Object}
15605			 */ this.parameters = {
15606	            radius: radius,
15607	            widthSegments: widthSegments,
15608	            heightSegments: heightSegments,
15609	            phiStart: phiStart,
15610	            phiLength: phiLength,
15611	            thetaStart: thetaStart,
15612	            thetaLength: thetaLength
15613	        };
15614	        widthSegments = Math.max(3, Math.floor(widthSegments));
15615	        heightSegments = Math.max(2, Math.floor(heightSegments));
15616	        const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
15617	        let index = 0;
15618	        const grid = [];
15619	        const vertex = new Vector3();
15620	        const normal = new Vector3();
15621	        // buffers
15622	        const indices = [];
15623	        const vertices = [];
15624	        const normals = [];
15625	        const uvs = [];
15626	        // generate vertices, normals and uvs
15627	        for(let iy = 0; iy <= heightSegments; iy++){
15628	            const verticesRow = [];
15629	            const v = iy / heightSegments;
15630	            // special case for the poles
15631	            let uOffset = 0;
15632	            if (iy === 0 && thetaStart === 0) {
15633	                uOffset = 0.5 / widthSegments;
15634	            } else if (iy === heightSegments && thetaEnd === Math.PI) {
15635	                uOffset = -0.5 / widthSegments;
15636	            }
15637	            for(let ix = 0; ix <= widthSegments; ix++){
15638	                const u = ix / widthSegments;
15639	                // vertex
15640	                vertex.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
15641	                vertex.y = radius * Math.cos(thetaStart + v * thetaLength);
15642	                vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
15643	                vertices.push(vertex.x, vertex.y, vertex.z);
15644	                // normal
15645	                normal.copy(vertex).normalize();
15646	                normals.push(normal.x, normal.y, normal.z);
15647	                // uv
15648	                uvs.push(u + uOffset, 1 - v);
15649	                verticesRow.push(index++);
15650	            }
15651	            grid.push(verticesRow);
15652	        }
15653	        // indices
15654	        for(let iy = 0; iy < heightSegments; iy++){
15655	            for(let ix = 0; ix < widthSegments; ix++){
15656	                const a = grid[iy][ix + 1];
15657	                const b = grid[iy][ix];
15658	                const c = grid[iy + 1][ix];
15659	                const d = grid[iy + 1][ix + 1];
15660	                if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
15661	                if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
15662	            }
15663	        }
15664	        // build geometry
15665	        this.setIndex(indices);
15666	        this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
15667	        this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
15668	        this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
15669	    }
15670	}
15671	class MeshStandardMaterial extends Material$1 {
15672	    copy(source) {
15673	        super.copy(source);
15674	        this.defines = {
15675	            'STANDARD': ''
15676	        };
15677	        this.color.copy(source.color);
15678	        this.roughness = source.roughness;
15679	        this.metalness = source.metalness;
15680	        this.map = source.map;
15681	        this.lightMap = source.lightMap;
15682	        this.lightMapIntensity = source.lightMapIntensity;
15683	        this.aoMap = source.aoMap;
15684	        this.aoMapIntensity = source.aoMapIntensity;
15685	        this.emissive.copy(source.emissive);
15686	        this.emissiveMap = source.emissiveMap;
15687	        this.emissiveIntensity = source.emissiveIntensity;
15688	        this.bumpMap = source.bumpMap;
15689	        this.bumpScale = source.bumpScale;
15690	        this.normalMap = source.normalMap;
15691	        this.normalMapType = source.normalMapType;
15692	        this.normalScale.copy(source.normalScale);
15693	        this.displacementMap = source.displacementMap;
15694	        this.displacementScale = source.displacementScale;
15695	        this.displacementBias = source.displacementBias;
15696	        this.roughnessMap = source.roughnessMap;
15697	        this.metalnessMap = source.metalnessMap;
15698	        this.alphaMap = source.alphaMap;
15699	        this.envMap = source.envMap;
15700	        this.envMapRotation.copy(source.envMapRotation);
15701	        this.envMapIntensity = source.envMapIntensity;
15702	        this.wireframe = source.wireframe;
15703	        this.wireframeLinewidth = source.wireframeLinewidth;
15704	        this.wireframeLinecap = source.wireframeLinecap;
15705	        this.wireframeLinejoin = source.wireframeLinejoin;
15706	        this.flatShading = source.flatShading;
15707	        this.fog = source.fog;
15708	        return this;
15709	    }
15710	    constructor(parameters){
15711	        super();
15712	        this.isMeshStandardMaterial = true;
15713	        this.type = 'MeshStandardMaterial';
15714	        this.defines = {
15715	            'STANDARD': ''
15716	        };
15717	        this.color = new Color(0xffffff); // diffuse
15718	        this.roughness = 1.0;
15719	        this.metalness = 0.0;
15720	        this.map = null;
15721	        this.lightMap = null;
15722	        this.lightMapIntensity = 1.0;
15723	        this.aoMap = null;
15724	        this.aoMapIntensity = 1.0;
15725	        this.emissive = new Color(0x000000);
15726	        this.emissiveIntensity = 1.0;
15727	        this.emissiveMap = null;
15728	        this.bumpMap = null;
15729	        this.bumpScale = 1;
15730	        this.normalMap = null;
15731	        this.normalMapType = TangentSpaceNormalMap;
15732	        this.normalScale = new Vector2(1, 1);
15733	        this.displacementMap = null;
15734	        this.displacementScale = 1;
15735	        this.displacementBias = 0;
15736	        this.roughnessMap = null;
15737	        this.metalnessMap = null;
15738	        this.alphaMap = null;
15739	        this.envMap = null;
15740	        this.envMapRotation = new Euler();
15741	        this.envMapIntensity = 1.0;
15742	        this.wireframe = false;
15743	        this.wireframeLinewidth = 1;
15744	        this.wireframeLinecap = 'round';
15745	        this.wireframeLinejoin = 'round';
15746	        this.flatShading = false;
15747	        this.fog = true;
15748	        this.setValues(parameters);
15749	    }
15750	}
15751	class MeshPhysicalMaterial extends MeshStandardMaterial {
15752	    get anisotropy() {
15753	        return this._anisotropy;
15754	    }
15755	    set anisotropy(value) {
15756	        if (this._anisotropy > 0 !== value > 0) {
15757	            this.version++;
15758	        }
15759	        this._anisotropy = value;
15760	    }
15761	    get clearcoat() {
15762	        return this._clearcoat;
15763	    }
15764	    set clearcoat(value) {
15765	        if (this._clearcoat > 0 !== value > 0) {
15766	            this.version++;
15767	        }
15768	        this._clearcoat = value;
15769	    }
15770	    get iridescence() {
15771	        return this._iridescence;
15772	    }
15773	    set iridescence(value) {
15774	        if (this._iridescence > 0 !== value > 0) {
15775	            this.version++;
15776	        }
15777	        this._iridescence = value;
15778	    }
15779	    get dispersion() {
15780	        return this._dispersion;
15781	    }
15782	    set dispersion(value) {
15783	        if (this._dispersion > 0 !== value > 0) {
15784	            this.version++;
15785	        }
15786	        this._dispersion = value;
15787	    }
15788	    get sheen() {
15789	        return this._sheen;
15790	    }
15791	    set sheen(value) {
15792	        if (this._sheen > 0 !== value > 0) {
15793	            this.version++;
15794	        }
15795	        this._sheen = value;
15796	    }
15797	    get transmission() {
15798	        return this._transmission;
15799	    }
15800	    set transmission(value) {
15801	        if (this._transmission > 0 !== value > 0) {
15802	            this.version++;
15803	        }
15804	        this._transmission = value;
15805	    }
15806	    copy(source) {
15807	        super.copy(source);
15808	        this.defines = {
15809	            'STANDARD': '',
15810	            'PHYSICAL': ''
15811	        };
15812	        this.anisotropy = source.anisotropy;
15813	        this.anisotropyRotation = source.anisotropyRotation;
15814	        this.anisotropyMap = source.anisotropyMap;
15815	        this.clearcoat = source.clearcoat;
15816	        this.clearcoatMap = source.clearcoatMap;
15817	        this.clearcoatRoughness = source.clearcoatRoughness;
15818	        this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
15819	        this.clearcoatNormalMap = source.clearcoatNormalMap;
15820	        this.clearcoatNormalScale.copy(source.clearcoatNormalScale);
15821	        this.dispersion = source.dispersion;
15822	        this.ior = source.ior;
15823	        this.iridescence = source.iridescence;
15824	        this.iridescenceMap = source.iridescenceMap;
15825	        this.iridescenceIOR = source.iridescenceIOR;
15826	        this.iridescenceThicknessRange = [
15827	            ...source.iridescenceThicknessRange
15828	        ];
15829	        this.iridescenceThicknessMap = source.iridescenceThicknessMap;
15830	        this.sheen = source.sheen;
15831	        this.sheenColor.copy(source.sheenColor);
15832	        this.sheenColorMap = source.sheenColorMap;
15833	        this.sheenRoughness = source.sheenRoughness;
15834	        this.sheenRoughnessMap = source.sheenRoughnessMap;
15835	        this.transmission = source.transmission;
15836	        this.transmissionMap = source.transmissionMap;
15837	        this.thickness = source.thickness;
15838	        this.thicknessMap = source.thicknessMap;
15839	        this.attenuationDistance = source.attenuationDistance;
15840	        this.attenuationColor.copy(source.attenuationColor);
15841	        this.specularIntensity = source.specularIntensity;
15842	        this.specularIntensityMap = source.specularIntensityMap;
15843	        this.specularColor.copy(source.specularColor);
15844	        this.specularColorMap = source.specularColorMap;
15845	        return this;
15846	    }
15847	    constructor(parameters){
15848	        super();
15849	        this.isMeshPhysicalMaterial = true;
15850	        this.defines = {
15851	            'STANDARD': '',
15852	            'PHYSICAL': ''
15853	        };
15854	        this.type = 'MeshPhysicalMaterial';
15855	        this.anisotropyRotation = 0;
15856	        this.anisotropyMap = null;
15857	        this.clearcoatMap = null;
15858	        this.clearcoatRoughness = 0.0;
15859	        this.clearcoatRoughnessMap = null;
15860	        this.clearcoatNormalScale = new Vector2(1, 1);
15861	        this.clearcoatNormalMap = null;
15862	        this.ior = 1.5;
15863	        Object.defineProperty(this, 'reflectivity', {
15864	            get: function() {
15865	                return clamp$1(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
15866	            },
15867	            set: function(reflectivity) {
15868	                this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
15869	            }
15870	        });
15871	        this.iridescenceMap = null;
15872	        this.iridescenceIOR = 1.3;
15873	        this.iridescenceThicknessRange = [
15874	            100,
15875	            400
15876	        ];
15877	        this.iridescenceThicknessMap = null;
15878	        this.sheenColor = new Color(0x000000);
15879	        this.sheenColorMap = null;
15880	        this.sheenRoughness = 1.0;
15881	        this.sheenRoughnessMap = null;
15882	        this.transmissionMap = null;
15883	        this.thickness = 0;
15884	        this.thicknessMap = null;
15885	        this.attenuationDistance = Infinity;
15886	        this.attenuationColor = new Color(1, 1, 1);
15887	        this.specularIntensity = 1.0;
15888	        this.specularIntensityMap = null;
15889	        this.specularColor = new Color(1, 1, 1);
15890	        this.specularColorMap = null;
15891	        this._anisotropy = 0;
15892	        this._clearcoat = 0;
15893	        this._dispersion = 0;
15894	        this._iridescence = 0;
15895	        this._sheen = 0.0;
15896	        this._transmission = 0;
15897	        this.setValues(parameters);
15898	    }
15899	}
15900	class MeshDepthMaterial extends Material$1 {
15901	    copy(source) {
15902	        super.copy(source);
15903	        this.depthPacking = source.depthPacking;
15904	        this.map = source.map;
15905	        this.alphaMap = source.alphaMap;
15906	        this.displacementMap = source.displacementMap;
15907	        this.displacementScale = source.displacementScale;
15908	        this.displacementBias = source.displacementBias;
15909	        this.wireframe = source.wireframe;
15910	        this.wireframeLinewidth = source.wireframeLinewidth;
15911	        return this;
15912	    }
15913	    constructor(parameters){
15914	        super();
15915	        this.isMeshDepthMaterial = true;
15916	        this.type = 'MeshDepthMaterial';
15917	        this.depthPacking = BasicDepthPacking;
15918	        this.map = null;
15919	        this.alphaMap = null;
15920	        this.displacementMap = null;
15921	        this.displacementScale = 1;
15922	        this.displacementBias = 0;
15923	        this.wireframe = false;
15924	        this.wireframeLinewidth = 1;
15925	        this.setValues(parameters);
15926	    }
15927	}
15928	class MeshDistanceMaterial extends Material$1 {
15929	    copy(source) {
15930	        super.copy(source);
15931	        this.map = source.map;
15932	        this.alphaMap = source.alphaMap;
15933	        this.displacementMap = source.displacementMap;
15934	        this.displacementScale = source.displacementScale;
15935	        this.displacementBias = source.displacementBias;
15936	        return this;
15937	    }
15938	    constructor(parameters){
15939	        super();
15940	        this.isMeshDistanceMaterial = true;
15941	        this.type = 'MeshDistanceMaterial';
15942	        this.map = null;
15943	        this.alphaMap = null;
15944	        this.displacementMap = null;
15945	        this.displacementScale = 1;
15946	        this.displacementBias = 0;
15947	        this.setValues(parameters);
15948	    }
15949	}
15950	// converts an array to a specific type
15951	function convertArray(array, type, forceClone) {
15952	    if (!array || // let 'undefined' and 'null' pass
15953	    !forceClone && array.constructor === type) return array;
15954	    if (typeof type.BYTES_PER_ELEMENT === 'number') {
15955	        return new type(array); // create typed array
15956	    }
15957	    return Array.prototype.slice.call(array); // create Array
15958	}
15959	function isTypedArray(object) {
15960	    return ArrayBuffer.isView(object) && !(object instanceof DataView);
15961	}
15962	// returns an array by which times and values can be sorted
15963	function getKeyframeOrder(times) {
15964	    function compareTime(i, j) {
15965	        return times[i] - times[j];
15966	    }
15967	    const n = times.length;
15968	    const result = new Array(n);
vendor: 80,912 bytes, lines 15969-18066
15969	    for(let i = 0; i !== n; ++i)result[i] = i;
15970	    result.sort(compareTime);
15971	    return result;
15972	}
15973	// uses the array previously returned by 'getKeyframeOrder' to sort data
15974	function sortedArray(values, stride, order) {
15975	    const nValues = values.length;
15976	    const result = new values.constructor(nValues);
15977	    for(let i = 0, dstOffset = 0; dstOffset !== nValues; ++i){
15978	        const srcOffset = order[i] * stride;
15979	        for(let j = 0; j !== stride; ++j){
15980	            result[dstOffset++] = values[srcOffset + j];
15981	        }
15982	    }
15983	    return result;
15984	}
15985	// function for parsing AOS keyframe formats
15986	function flattenJSON(jsonKeys, times, values, valuePropertyName) {
15987	    let i = 1, key = jsonKeys[0];
15988	    while(key !== undefined && key[valuePropertyName] === undefined){
15989	        key = jsonKeys[i++];
15990	    }
15991	    if (key === undefined) return; // no data
15992	    let value = key[valuePropertyName];
15993	    if (value === undefined) return; // no data
15994	    if (Array.isArray(value)) {
15995	        do {
15996	            value = key[valuePropertyName];
15997	            if (value !== undefined) {
15998	                times.push(key.time);
15999	                values.push(...value); // push all elements
16000	            }
16001	            key = jsonKeys[i++];
16002	        }while (key !== undefined)
16003	    } else if (value.toArray !== undefined) {
16004	        // ...assume THREE.Math-ish
16005	        do {
16006	            value = key[valuePropertyName];
16007	            if (value !== undefined) {
16008	                times.push(key.time);
16009	                value.toArray(values, values.length);
16010	            }
16011	            key = jsonKeys[i++];
16012	        }while (key !== undefined)
16013	    } else {
16014	        // otherwise push as-is
16015	        do {
16016	            value = key[valuePropertyName];
16017	            if (value !== undefined) {
16018	                times.push(key.time);
16019	                values.push(value);
16020	            }
16021	            key = jsonKeys[i++];
16022	        }while (key !== undefined)
16023	    }
16024	}
16025	/**
16026	 * Abstract base class of interpolants over parametric samples.
16027	 *
16028	 * The parameter domain is one dimensional, typically the time or a path
16029	 * along a curve defined by the data.
16030	 *
16031	 * The sample values can have any dimensionality and derived classes may
16032	 * apply special interpretations to the data.
16033	 *
16034	 * This class provides the interval seek in a Template Method, deferring
16035	 * the actual interpolation to derived classes.
16036	 *
16037	 * Time complexity is O(1) for linear access crossing at most two points
16038	 * and O(log N) for random access, where N is the number of positions.
16039	 *
16040	 * References: {@link http://www.oodesign.com/template-method-pattern.html}
16041	 *
16042	 * @abstract
16043	 */ class Interpolant {
16044	    /**
16045		 * Evaluate the interpolant at position `t`.
16046		 *
16047		 * @param {number} t - The interpolation factor.
16048		 * @return {TypedArray} The result buffer.
16049		 */ evaluate(t) {
16050	        const pp = this.parameterPositions;
16051	        let i1 = this._cachedIndex, t1 = pp[i1], t0 = pp[i1 - 1];
16052	        validate_interval: {
16053	            seek: {
16054	                let right;
16055	                linear_scan: {
16056	                    //- See http://jsperf.com/comparison-to-undefined/3
16057	                    //- slower code:
16058	                    //-
16059	                    //- 				if ( t >= t1 || t1 === undefined ) {
16060	                    forward_scan: if (!(t < t1)) {
16061	                        for(let giveUpAt = i1 + 2;;){
16062	                            if (t1 === undefined) {
16063	                                if (t < t0) break forward_scan;
16064	                                // after end
16065	                                i1 = pp.length;
16066	                                this._cachedIndex = i1;
16067	                                return this.copySampleValue_(i1 - 1);
16068	                            }
16069	                            if (i1 === giveUpAt) break; // this loop
16070	                            t0 = t1;
16071	                            t1 = pp[++i1];
16072	                            if (t < t1) {
16073	                                break seek;
16074	                            }
16075	                        }
16076	                        // prepare binary search on the right side of the index
16077	                        right = pp.length;
16078	                        break linear_scan;
16079	                    }
16080	                    //- slower code:
16081	                    //-					if ( t < t0 || t0 === undefined ) {
16082	                    if (!(t >= t0)) {
16083	                        // looping?
16084	                        const t1global = pp[1];
16085	                        if (t < t1global) {
16086	                            i1 = 2; // + 1, using the scan for the details
16087	                            t0 = t1global;
16088	                        }
16089	                        // linear reverse scan
16090	                        for(let giveUpAt = i1 - 2;;){
16091	                            if (t0 === undefined) {
16092	                                // before start
16093	                                this._cachedIndex = 0;
16094	                                return this.copySampleValue_(0);
16095	                            }
16096	                            if (i1 === giveUpAt) break; // this loop
16097	                            t1 = t0;
16098	                            t0 = pp[--i1 - 1];
16099	                            if (t >= t0) {
16100	                                break seek;
16101	                            }
16102	                        }
16103	                        // prepare binary search on the left side of the index
16104	                        right = i1;
16105	                        i1 = 0;
16106	                        break linear_scan;
16107	                    }
16108	                    break validate_interval;
16109	                } // linear scan
16110	                // binary search
16111	                while(i1 < right){
16112	                    const mid = i1 + right >>> 1;
16113	                    if (t < pp[mid]) {
16114	                        right = mid;
16115	                    } else {
16116	                        i1 = mid + 1;
16117	                    }
16118	                }
16119	                t1 = pp[i1];
16120	                t0 = pp[i1 - 1];
16121	                // check boundary cases, again
16122	                if (t0 === undefined) {
16123	                    this._cachedIndex = 0;
16124	                    return this.copySampleValue_(0);
16125	                }
16126	                if (t1 === undefined) {
16127	                    i1 = pp.length;
16128	                    this._cachedIndex = i1;
16129	                    return this.copySampleValue_(i1 - 1);
16130	                }
16131	            } // seek
16132	            this._cachedIndex = i1;
16133	            this.intervalChanged_(i1, t0, t1);
16134	        } // validate_interval
16135	        return this.interpolate_(i1, t0, t, t1);
16136	    }
16137	    /**
16138		 * Returns the interpolation settings.
16139		 *
16140		 * @return {Object} The interpolation settings.
16141		 */ getSettings_() {
16142	        return this.settings || this.DefaultSettings_;
16143	    }
16144	    /**
16145		 * Copies a sample value to the result buffer.
16146		 *
16147		 * @param {number} index - An index into the sample value buffer.
16148		 * @return {TypedArray} The result buffer.
16149		 */ copySampleValue_(index) {
16150	        // copies a sample value to the result buffer
16151	        const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset = index * stride;
16152	        for(let i = 0; i !== stride; ++i){
16153	            result[i] = values[offset + i];
16154	        }
16155	        return result;
16156	    }
16157	    /**
16158		 * Copies a sample value to the result buffer.
16159		 *
16160		 * @abstract
16161		 * @param {number} i1 - An index into the sample value buffer.
16162		 * @param {number} t0 - The previous interpolation factor.
16163		 * @param {number} t - The current interpolation factor.
16164		 * @param {number} t1 - The next interpolation factor.
16165		 * @return {TypedArray} The result buffer.
16166		 */ interpolate_() {
16167	        throw new Error('call to abstract method');
16168	    // implementations shall return this.resultBuffer
16169	    }
16170	    /**
16171		 * Optional method that is executed when the interval has changed.
16172		 *
16173		 * @param {number} i1 - An index into the sample value buffer.
16174		 * @param {number} t0 - The previous interpolation factor.
16175		 * @param {number} t - The current interpolation factor.
16176		 */ intervalChanged_() {
16177	    // empty
16178	    }
16179	    /**
16180		 * Constructs a new interpolant.
16181		 *
16182		 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16183		 * @param {TypedArray} sampleValues - The sample values.
16184		 * @param {number} sampleSize - The sample size
16185		 * @param {TypedArray} [resultBuffer] - The result buffer.
16186		 */ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
16187	        /**
16188			 * The parameter positions.
16189			 *
16190			 * @type {TypedArray}
16191			 */ this.parameterPositions = parameterPositions;
16192	        /**
16193			 * A cache index.
16194			 *
16195			 * @private
16196			 * @type {number}
16197			 * @default 0
16198			 */ this._cachedIndex = 0;
16199	        /**
16200			 * The result buffer.
16201			 *
16202			 * @type {TypedArray}
16203			 */ this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new sampleValues.constructor(sampleSize);
16204	        /**
16205			 * The sample values.
16206			 *
16207			 * @type {TypedArray}
16208			 */ this.sampleValues = sampleValues;
16209	        /**
16210			 * The value size.
16211			 *
16212			 * @type {TypedArray}
16213			 */ this.valueSize = sampleSize;
16214	        /**
16215			 * The interpolation settings.
16216			 *
16217			 * @type {?Object}
16218			 * @default null
16219			 */ this.settings = null;
16220	        /**
16221			 * The default settings object.
16222			 *
16223			 * @type {Object}
16224			 */ this.DefaultSettings_ = {};
16225	    }
16226	}
16227	/**
16228	 * Fast and simple cubic spline interpolant.
16229	 *
16230	 * It was derived from a Hermitian construction setting the first derivative
16231	 * at each sample position to the linear slope between neighboring positions
16232	 * over their parameter interval.
16233	 *
16234	 * @augments Interpolant
16235	 */ class CubicInterpolant extends Interpolant {
16236	    intervalChanged_(i1, t0, t1) {
16237	        const pp = this.parameterPositions;
16238	        let iPrev = i1 - 2, iNext = i1 + 1, tPrev = pp[iPrev], tNext = pp[iNext];
16239	        if (tPrev === undefined) {
16240	            switch(this.getSettings_().endingStart){
16241	                case ZeroSlopeEnding:
16242	                    // f'(t0) = 0
16243	                    iPrev = i1;
16244	                    tPrev = 2 * t0 - t1;
16245	                    break;
16246	                case WrapAroundEnding:
16247	                    // use the other end of the curve
16248	                    iPrev = pp.length - 2;
16249	                    tPrev = t0 + pp[iPrev] - pp[iPrev + 1];
16250	                    break;
16251	                default:
16252	                    // f''(t0) = 0 a.k.a. Natural Spline
16253	                    iPrev = i1;
16254	                    tPrev = t1;
16255	            }
16256	        }
16257	        if (tNext === undefined) {
16258	            switch(this.getSettings_().endingEnd){
16259	                case ZeroSlopeEnding:
16260	                    // f'(tN) = 0
16261	                    iNext = i1;
16262	                    tNext = 2 * t1 - t0;
16263	                    break;
16264	                case WrapAroundEnding:
16265	                    // use the other end of the curve
16266	                    iNext = 1;
16267	                    tNext = t1 + pp[1] - pp[0];
16268	                    break;
16269	                default:
16270	                    // f''(tN) = 0, a.k.a. Natural Spline
16271	                    iNext = i1 - 1;
16272	                    tNext = t0;
16273	            }
16274	        }
16275	        const halfDt = (t1 - t0) * 0.5, stride = this.valueSize;
16276	        this._weightPrev = halfDt / (t0 - tPrev);
16277	        this._weightNext = halfDt / (tNext - t1);
16278	        this._offsetPrev = iPrev * stride;
16279	        this._offsetNext = iNext * stride;
16280	    }
16281	    interpolate_(i1, t0, t, t1) {
16282	        const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, o1 = i1 * stride, o0 = o1 - stride, oP = this._offsetPrev, oN = this._offsetNext, wP = this._weightPrev, wN = this._weightNext, p = (t - t0) / (t1 - t0), pp = p * p, ppp = pp * p;
16283	        // evaluate polynomials
16284	        const sP = -wP * ppp + 2 * wP * pp - wP * p;
16285	        const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1;
16286	        const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p;
16287	        const sN = wN * ppp - wN * pp;
16288	        // combine data linearly
16289	        for(let i = 0; i !== stride; ++i){
16290	            result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i];
16291	        }
16292	        return result;
16293	    }
16294	    /**
16295		 * Constructs a new cubic interpolant.
16296		 *
16297		 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16298		 * @param {TypedArray} sampleValues - The sample values.
16299		 * @param {number} sampleSize - The sample size
16300		 * @param {TypedArray} [resultBuffer] - The result buffer.
16301		 */ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
16302	        super(parameterPositions, sampleValues, sampleSize, resultBuffer);
16303	        this._weightPrev = -0;
16304	        this._offsetPrev = -0;
16305	        this._weightNext = -0;
16306	        this._offsetNext = -0;
16307	        this.DefaultSettings_ = {
16308	            endingStart: ZeroCurvatureEnding,
16309	            endingEnd: ZeroCurvatureEnding
16310	        };
16311	    }
16312	}
16313	/**
16314	 * A basic linear interpolant.
16315	 *
16316	 * @augments Interpolant
16317	 */ class LinearInterpolant extends Interpolant {
16318	    interpolate_(i1, t0, t, t1) {
16319	        const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, offset1 = i1 * stride, offset0 = offset1 - stride, weight1 = (t - t0) / (t1 - t0), weight0 = 1 - weight1;
16320	        for(let i = 0; i !== stride; ++i){
16321	            result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1;
16322	        }
16323	        return result;
16324	    }
16325	    /**
16326		 * Constructs a new linear interpolant.
16327		 *
16328		 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16329		 * @param {TypedArray} sampleValues - The sample values.
16330		 * @param {number} sampleSize - The sample size
16331		 * @param {TypedArray} [resultBuffer] - The result buffer.
16332		 */ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
16333	        super(parameterPositions, sampleValues, sampleSize, resultBuffer);
16334	    }
16335	}
16336	/**
16337	 * Interpolant that evaluates to the sample value at the position preceding
16338	 * the parameter.
16339	 *
16340	 * @augments Interpolant
16341	 */ class DiscreteInterpolant extends Interpolant {
16342	    interpolate_(i1 /*, t0, t, t1 */ ) {
16343	        return this.copySampleValue_(i1 - 1);
16344	    }
16345	    /**
16346		 * Constructs a new discrete interpolant.
16347		 *
16348		 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16349		 * @param {TypedArray} sampleValues - The sample values.
16350		 * @param {number} sampleSize - The sample size
16351		 * @param {TypedArray} [resultBuffer] - The result buffer.
16352		 */ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
16353	        super(parameterPositions, sampleValues, sampleSize, resultBuffer);
16354	    }
16355	}
16356	class KeyframeTrack {
16357	    // Serialization (in static context, because of constructor invocation
16358	    // and automatic invocation of .toJSON):
16359	    static toJSON(track) {
16360	        const trackType = track.constructor;
16361	        let json;
16362	        // derived classes can define a static toJSON method
16363	        if (trackType.toJSON !== this.toJSON) {
16364	            json = trackType.toJSON(track);
16365	        } else {
16366	            // by default, we assume the data can be serialized as-is
16367	            json = {
16368	                'name': track.name,
16369	                'times': convertArray(track.times, Array),
16370	                'values': convertArray(track.values, Array)
16371	            };
16372	            const interpolation = track.getInterpolation();
16373	            if (interpolation !== track.DefaultInterpolation) {
16374	                json.interpolation = interpolation;
16375	            }
16376	        }
16377	        json.type = track.ValueTypeName; // mandatory
16378	        return json;
16379	    }
16380	    InterpolantFactoryMethodDiscrete(result) {
16381	        return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result);
16382	    }
16383	    InterpolantFactoryMethodLinear(result) {
16384	        return new LinearInterpolant(this.times, this.values, this.getValueSize(), result);
16385	    }
16386	    InterpolantFactoryMethodSmooth(result) {
16387	        return new CubicInterpolant(this.times, this.values, this.getValueSize(), result);
16388	    }
16389	    setInterpolation(interpolation) {
16390	        let factoryMethod;
16391	        switch(interpolation){
16392	            case InterpolateDiscrete:
16393	                factoryMethod = this.InterpolantFactoryMethodDiscrete;
16394	                break;
16395	            case InterpolateLinear:
16396	                factoryMethod = this.InterpolantFactoryMethodLinear;
16397	                break;
16398	            case InterpolateSmooth:
16399	                factoryMethod = this.InterpolantFactoryMethodSmooth;
16400	                break;
16401	        }
16402	        if (factoryMethod === undefined) {
16403	            const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name;
16404	            if (this.createInterpolant === undefined) {
16405	                // fall back to default, unless the default itself is messed up
16406	                if (interpolation !== this.DefaultInterpolation) {
16407	                    this.setInterpolation(this.DefaultInterpolation);
16408	                } else {
16409	                    throw new Error(message); // fatal, in this case
16410	                }
16411	            }
16412	            console.warn('THREE.KeyframeTrack:', message);
16413	            return this;
16414	        }
16415	        this.createInterpolant = factoryMethod;
16416	        return this;
16417	    }
16418	    getInterpolation() {
16419	        switch(this.createInterpolant){
16420	            case this.InterpolantFactoryMethodDiscrete:
16421	                return InterpolateDiscrete;
16422	            case this.InterpolantFactoryMethodLinear:
16423	                return InterpolateLinear;
16424	            case this.InterpolantFactoryMethodSmooth:
16425	                return InterpolateSmooth;
16426	        }
16427	    }
16428	    getValueSize() {
16429	        return this.values.length / this.times.length;
16430	    }
16431	    // move all keyframes either forwards or backwards in time
16432	    shift(timeOffset) {
16433	        if (timeOffset !== 0.0) {
16434	            const times = this.times;
16435	            for(let i = 0, n = times.length; i !== n; ++i){
16436	                times[i] += timeOffset;
16437	            }
16438	        }
16439	        return this;
16440	    }
16441	    // scale all keyframe times by a factor (useful for frame <-> seconds conversions)
16442	    scale(timeScale) {
16443	        if (timeScale !== 1.0) {
16444	            const times = this.times;
16445	            for(let i = 0, n = times.length; i !== n; ++i){
16446	                times[i] *= timeScale;
16447	            }
16448	        }
16449	        return this;
16450	    }
16451	    // removes keyframes before and after animation without changing any values within the range [startTime, endTime].
16452	    // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
16453	    trim(startTime, endTime) {
16454	        const times = this.times, nKeys = times.length;
16455	        let from = 0, to = nKeys - 1;
16456	        while(from !== nKeys && times[from] < startTime){
16457	            ++from;
16458	        }
16459	        while(to !== -1 && times[to] > endTime){
16460	            --to;
16461	        }
16462	        ++to; // inclusive -> exclusive bound
16463	        if (from !== 0 || to !== nKeys) {
16464	            // empty tracks are forbidden, so keep at least one keyframe
16465	            if (from >= to) {
16466	                to = Math.max(to, 1);
16467	                from = to - 1;
16468	            }
16469	            const stride = this.getValueSize();
16470	            this.times = times.slice(from, to);
16471	            this.values = this.values.slice(from * stride, to * stride);
16472	        }
16473	        return this;
16474	    }
16475	    // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
16476	    validate() {
16477	        let valid = true;
16478	        const valueSize = this.getValueSize();
16479	        if (valueSize - Math.floor(valueSize) !== 0) {
16480	            console.error('THREE.KeyframeTrack: Invalid value size in track.', this);
16481	            valid = false;
16482	        }
16483	        const times = this.times, values = this.values, nKeys = times.length;
16484	        if (nKeys === 0) {
16485	            console.error('THREE.KeyframeTrack: Track is empty.', this);
16486	            valid = false;
16487	        }
16488	        let prevTime = null;
16489	        for(let i = 0; i !== nKeys; i++){
16490	            const currTime = times[i];
16491	            if (typeof currTime === 'number' && isNaN(currTime)) {
16492	                console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime);
16493	                valid = false;
16494	                break;
16495	            }
16496	            if (prevTime !== null && prevTime > currTime) {
16497	                console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime);
16498	                valid = false;
16499	                break;
16500	            }
16501	            prevTime = currTime;
16502	        }
16503	        if (values !== undefined) {
16504	            if (isTypedArray(values)) {
16505	                for(let i = 0, n = values.length; i !== n; ++i){
16506	                    const value = values[i];
16507	                    if (isNaN(value)) {
16508	                        console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value);
16509	                        valid = false;
16510	                        break;
16511	                    }
16512	                }
16513	            }
16514	        }
16515	        return valid;
16516	    }
16517	    // removes equivalent sequential keys as common in morph target sequences
16518	    // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
16519	    optimize() {
16520	        // times or values may be shared with other tracks, so overwriting is unsafe
16521	        const times = this.times.slice(), values = this.values.slice(), stride = this.getValueSize(), smoothInterpolation = this.getInterpolation() === InterpolateSmooth, lastIndex = times.length - 1;
16522	        let writeIndex = 1;
16523	        for(let i = 1; i < lastIndex; ++i){
16524	            let keep = false;
16525	            const time = times[i];
16526	            const timeNext = times[i + 1];
16527	            // remove adjacent keyframes scheduled at the same time
16528	            if (time !== timeNext && (i !== 1 || time !== times[0])) {
16529	                if (!smoothInterpolation) {
16530	                    // remove unnecessary keyframes same as their neighbors
16531	                    const offset = i * stride, offsetP = offset - stride, offsetN = offset + stride;
16532	                    for(let j = 0; j !== stride; ++j){
16533	                        const value = values[offset + j];
16534	                        if (value !== values[offsetP + j] || value !== values[offsetN + j]) {
16535	                            keep = true;
16536	                            break;
16537	                        }
16538	                    }
16539	                } else {
16540	                    keep = true;
16541	                }
16542	            }
16543	            // in-place compaction
16544	            if (keep) {
16545	                if (i !== writeIndex) {
16546	                    times[writeIndex] = times[i];
16547	                    const readOffset = i * stride, writeOffset = writeIndex * stride;
16548	                    for(let j = 0; j !== stride; ++j){
16549	                        values[writeOffset + j] = values[readOffset + j];
16550	                    }
16551	                }
16552	                ++writeIndex;
16553	            }
16554	        }
16555	        // flush last keyframe (compaction looks ahead)
16556	        if (lastIndex > 0) {
16557	            times[writeIndex] = times[lastIndex];
16558	            for(let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j){
16559	                values[writeOffset + j] = values[readOffset + j];
16560	            }
16561	            ++writeIndex;
16562	        }
16563	        if (writeIndex !== times.length) {
16564	            this.times = times.slice(0, writeIndex);
16565	            this.values = values.slice(0, writeIndex * stride);
16566	        } else {
16567	            this.times = times;
16568	            this.values = values;
16569	        }
16570	        return this;
16571	    }
16572	    clone() {
16573	        const times = this.times.slice();
16574	        const values = this.values.slice();
16575	        const TypedKeyframeTrack = this.constructor;
16576	        const track = new TypedKeyframeTrack(this.name, times, values);
16577	        // Interpolant argument to constructor is not saved, so copy the factory method directly.
16578	        track.createInterpolant = this.createInterpolant;
16579	        return track;
16580	    }
16581	    constructor(name, times, values, interpolation){
16582	        if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined');
16583	        if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + name);
16584	        this.name = name;
16585	        this.times = convertArray(times, this.TimeBufferType);
16586	        this.values = convertArray(values, this.ValueBufferType);
16587	        this.setInterpolation(interpolation || this.DefaultInterpolation);
16588	    }
16589	}
16590	KeyframeTrack.prototype.TimeBufferType = Float32Array;
16591	KeyframeTrack.prototype.ValueBufferType = Float32Array;
16592	KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
16593	/**
16594	 * A Track of Boolean keyframe values.
16595	 */ class BooleanKeyframeTrack extends KeyframeTrack {
16596	    // No interpolation parameter because only InterpolateDiscrete is valid.
16597	    constructor(name, times, values){
16598	        super(name, times, values);
16599	    }
16600	}
16601	BooleanKeyframeTrack.prototype.ValueTypeName = 'bool';
16602	BooleanKeyframeTrack.prototype.ValueBufferType = Array;
16603	BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
16604	BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
16605	BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
16606	/**
16607	 * A Track of keyframe values that represent color.
16608	 */ class ColorKeyframeTrack extends KeyframeTrack {
16609	}
16610	ColorKeyframeTrack.prototype.ValueTypeName = 'color';
16611	/**
16612	 * A Track of numeric keyframe values.
16613	 */ class NumberKeyframeTrack extends KeyframeTrack {
16614	}
16615	NumberKeyframeTrack.prototype.ValueTypeName = 'number';
16616	/**
16617	 * Spherical linear unit quaternion interpolant.
16618	 *
16619	 * @augments Interpolant
16620	 */ class QuaternionLinearInterpolant extends Interpolant {
16621	    interpolate_(i1, t0, t, t1) {
16622	        const result = this.resultBuffer, values = this.sampleValues, stride = this.valueSize, alpha = (t - t0) / (t1 - t0);
16623	        let offset = i1 * stride;
16624	        for(let end = offset + stride; offset !== end; offset += 4){
16625	            Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha);
16626	        }
16627	        return result;
16628	    }
16629	    /**
16630		 * Constructs a new SLERP interpolant.
16631		 *
16632		 * @param {TypedArray} parameterPositions - The parameter positions hold the interpolation factors.
16633		 * @param {TypedArray} sampleValues - The sample values.
16634		 * @param {number} sampleSize - The sample size
16635		 * @param {TypedArray} [resultBuffer] - The result buffer.
16636		 */ constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
16637	        super(parameterPositions, sampleValues, sampleSize, resultBuffer);
16638	    }
16639	}
16640	/**
16641	 * A Track of quaternion keyframe values.
16642	 */ class QuaternionKeyframeTrack extends KeyframeTrack {
16643	    InterpolantFactoryMethodLinear(result) {
16644	        return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result);
16645	    }
16646	}
16647	QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion';
16648	// ValueBufferType is inherited
16649	// DefaultInterpolation is inherited;
16650	QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
16651	/**
16652	 * A Track that interpolates Strings
16653	 */ class StringKeyframeTrack extends KeyframeTrack {
16654	    // No interpolation parameter because only InterpolateDiscrete is valid.
16655	    constructor(name, times, values){
16656	        super(name, times, values);
16657	    }
16658	}
16659	StringKeyframeTrack.prototype.ValueTypeName = 'string';
16660	StringKeyframeTrack.prototype.ValueBufferType = Array;
16661	StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
16662	StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
16663	StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
16664	/**
16665	 * A Track of vectored keyframe values.
16666	 */ class VectorKeyframeTrack extends KeyframeTrack {
16667	}
16668	VectorKeyframeTrack.prototype.ValueTypeName = 'vector';
16669	class AnimationClip {
16670	    static parse(json) {
16671	        const tracks = [], jsonTracks = json.tracks, frameTime = 1.0 / (json.fps || 1.0);
16672	        for(let i = 0, n = jsonTracks.length; i !== n; ++i){
16673	            tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime));
16674	        }
16675	        const clip = new this(json.name, json.duration, tracks, json.blendMode);
16676	        clip.uuid = json.uuid;
16677	        return clip;
16678	    }
16679	    static toJSON(clip) {
16680	        const tracks = [], clipTracks = clip.tracks;
16681	        const json = {
16682	            'name': clip.name,
16683	            'duration': clip.duration,
16684	            'tracks': tracks,
16685	            'uuid': clip.uuid,
16686	            'blendMode': clip.blendMode
16687	        };
16688	        for(let i = 0, n = clipTracks.length; i !== n; ++i){
16689	            tracks.push(KeyframeTrack.toJSON(clipTracks[i]));
16690	        }
16691	        return json;
16692	    }
16693	    static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) {
16694	        const numMorphTargets = morphTargetSequence.length;
16695	        const tracks = [];
16696	        for(let i = 0; i < numMorphTargets; i++){
16697	            let times = [];
16698	            let values = [];
16699	            times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets);
16700	            values.push(0, 1, 0);
16701	            const order = getKeyframeOrder(times);
16702	            times = sortedArray(times, 1, order);
16703	            values = sortedArray(values, 1, order);
16704	            // if there is a key at the first frame, duplicate it as the
16705	            // last frame as well for perfect loop.
16706	            if (!noLoop && times[0] === 0) {
16707	                times.push(numMorphTargets);
16708	                values.push(values[0]);
16709	            }
16710	            tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps));
16711	        }
16712	        return new this(name, -1, tracks);
16713	    }
16714	    static findByName(objectOrClipArray, name) {
16715	        let clipArray = objectOrClipArray;
16716	        if (!Array.isArray(objectOrClipArray)) {
16717	            const o = objectOrClipArray;
16718	            clipArray = o.geometry && o.geometry.animations || o.animations;
16719	        }
16720	        for(let i = 0; i < clipArray.length; i++){
16721	            if (clipArray[i].name === name) {
16722	                return clipArray[i];
16723	            }
16724	        }
16725	        return null;
16726	    }
16727	    static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) {
16728	        const animationToMorphTargets = {};
16729	        // tested with https://regex101.com/ on trick sequences
16730	        // such flamingo_flyA_003, flamingo_run1_003, crdeath0059
16731	        const pattern = /^([\w-]*?)([\d]+)$/;
16732	        // sort morph target names into animation groups based
16733	        // patterns like Walk_001, Walk_002, Run_001, Run_002
16734	        for(let i = 0, il = morphTargets.length; i < il; i++){
16735	            const morphTarget = morphTargets[i];
16736	            const parts = morphTarget.name.match(pattern);
16737	            if (parts && parts.length > 1) {
16738	                const name = parts[1];
16739	                let animationMorphTargets = animationToMorphTargets[name];
16740	                if (!animationMorphTargets) {
16741	                    animationToMorphTargets[name] = animationMorphTargets = [];
16742	                }
16743	                animationMorphTargets.push(morphTarget);
16744	            }
16745	        }
16746	        const clips = [];
16747	        for(const name in animationToMorphTargets){
16748	            clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop));
16749	        }
16750	        return clips;
16751	    }
16752	    // parse the animation.hierarchy format
16753	    static parseAnimation(animation, bones) {
16754	        if (!animation) {
16755	            console.error('THREE.AnimationClip: No animation in JSONLoader data.');
16756	            return null;
16757	        }
16758	        const addNonemptyTrack = function(trackType, trackName, animationKeys, propertyName, destTracks) {
16759	            // only return track if there are actually keys.
16760	            if (animationKeys.length !== 0) {
16761	                const times = [];
16762	                const values = [];
16763	                flattenJSON(animationKeys, times, values, propertyName);
16764	                // empty keys are filtered out, so check again
16765	                if (times.length !== 0) {
16766	                    destTracks.push(new trackType(trackName, times, values));
16767	                }
16768	            }
16769	        };
16770	        const tracks = [];
16771	        const clipName = animation.name || 'default';
16772	        const fps = animation.fps || 30;
16773	        const blendMode = animation.blendMode;
16774	        // automatic length determination in AnimationClip.
16775	        let duration = animation.length || -1;
16776	        const hierarchyTracks = animation.hierarchy || [];
16777	        for(let h = 0; h < hierarchyTracks.length; h++){
16778	            const animationKeys = hierarchyTracks[h].keys;
16779	            // skip empty tracks
16780	            if (!animationKeys || animationKeys.length === 0) continue;
16781	            // process morph targets
16782	            if (animationKeys[0].morphTargets) {
16783	                // figure out all morph targets used in this track
16784	                const morphTargetNames = {};
16785	                let k;
16786	                for(k = 0; k < animationKeys.length; k++){
16787	                    if (animationKeys[k].morphTargets) {
16788	                        for(let m = 0; m < animationKeys[k].morphTargets.length; m++){
16789	                            morphTargetNames[animationKeys[k].morphTargets[m]] = -1;
16790	                        }
16791	                    }
16792	                }
16793	                // create a track for each morph target with all zero
16794	                // morphTargetInfluences except for the keys in which
16795	                // the morphTarget is named.
16796	                for(const morphTargetName in morphTargetNames){
16797	                    const times = [];
16798	                    const values = [];
16799	                    for(let m = 0; m !== animationKeys[k].morphTargets.length; ++m){
16800	                        const animationKey = animationKeys[k];
16801	                        times.push(animationKey.time);
16802	                        values.push(animationKey.morphTarget === morphTargetName ? 1 : 0);
16803	                    }
16804	                    tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values));
16805	                }
16806	                duration = morphTargetNames.length * fps;
16807	            } else {
16808	                // ...assume skeletal animation
16809	                const boneName = '.bones[' + bones[h].name + ']';
16810	                addNonemptyTrack(VectorKeyframeTrack, boneName + '.position', animationKeys, 'pos', tracks);
16811	                addNonemptyTrack(QuaternionKeyframeTrack, boneName + '.quaternion', animationKeys, 'rot', tracks);
16812	                addNonemptyTrack(VectorKeyframeTrack, boneName + '.scale', animationKeys, 'scl', tracks);
16813	            }
16814	        }
16815	        if (tracks.length === 0) {
16816	            return null;
16817	        }
16818	        const clip = new this(clipName, duration, tracks, blendMode);
16819	        return clip;
16820	    }
16821	    resetDuration() {
16822	        const tracks = this.tracks;
16823	        let duration = 0;
16824	        for(let i = 0, n = tracks.length; i !== n; ++i){
16825	            const track = this.tracks[i];
16826	            duration = Math.max(duration, track.times[track.times.length - 1]);
16827	        }
16828	        this.duration = duration;
16829	        return this;
16830	    }
16831	    trim() {
16832	        for(let i = 0; i < this.tracks.length; i++){
16833	            this.tracks[i].trim(0, this.duration);
16834	        }
16835	        return this;
16836	    }
16837	    validate() {
16838	        let valid = true;
16839	        for(let i = 0; i < this.tracks.length; i++){
16840	            valid = valid && this.tracks[i].validate();
16841	        }
16842	        return valid;
16843	    }
16844	    optimize() {
16845	        for(let i = 0; i < this.tracks.length; i++){
16846	            this.tracks[i].optimize();
16847	        }
16848	        return this;
16849	    }
16850	    clone() {
16851	        const tracks = [];
16852	        for(let i = 0; i < this.tracks.length; i++){
16853	            tracks.push(this.tracks[i].clone());
16854	        }
16855	        return new this.constructor(this.name, this.duration, tracks, this.blendMode);
16856	    }
16857	    toJSON() {
16858	        return this.constructor.toJSON(this);
16859	    }
16860	    constructor(name = '', duration = -1, tracks = [], blendMode = NormalAnimationBlendMode){
16861	        this.name = name;
16862	        this.tracks = tracks;
16863	        this.duration = duration;
16864	        this.blendMode = blendMode;
16865	        this.uuid = generateUUID();
16866	        // this means it should figure out its duration by scanning the tracks
16867	        if (this.duration < 0) {
16868	            this.resetDuration();
16869	        }
16870	    }
16871	}
16872	function getTrackTypeForValueTypeName(typeName) {
16873	    switch(typeName.toLowerCase()){
16874	        case 'scalar':
16875	        case 'double':
16876	        case 'float':
16877	        case 'number':
16878	        case 'integer':
16879	            return NumberKeyframeTrack;
16880	        case 'vector':
16881	        case 'vector2':
16882	        case 'vector3':
16883	        case 'vector4':
16884	            return VectorKeyframeTrack;
16885	        case 'color':
16886	            return ColorKeyframeTrack;
16887	        case 'quaternion':
16888	            return QuaternionKeyframeTrack;
16889	        case 'bool':
16890	        case 'boolean':
16891	            return BooleanKeyframeTrack;
16892	        case 'string':
16893	            return StringKeyframeTrack;
16894	    }
16895	    throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName);
16896	}
16897	function parseKeyframeTrack(json) {
16898	    if (json.type === undefined) {
16899	        throw new Error('THREE.KeyframeTrack: track type undefined, can not parse');
16900	    }
16901	    const trackType = getTrackTypeForValueTypeName(json.type);
16902	    if (json.times === undefined) {
16903	        const times = [], values = [];
16904	        flattenJSON(json.keys, times, values, 'value');
16905	        json.times = times;
16906	        json.values = values;
16907	    }
16908	    // derived classes can define a static parse method
16909	    if (trackType.parse !== undefined) {
16910	        return trackType.parse(json);
16911	    } else {
16912	        // by default, we assume a constructor compatible with the base
16913	        return new trackType(json.name, json.times, json.values, json.interpolation);
16914	    }
16915	}
16916	const Cache = {
16917	    enabled: false,
16918	    files: {},
16919	    add: function(key, file) {
16920	        if (this.enabled === false) return;
16921	        // console.log( 'THREE.Cache', 'Adding key:', key );
16922	        this.files[key] = file;
16923	    },
16924	    get: function(key) {
16925	        if (this.enabled === false) return;
16926	        // console.log( 'THREE.Cache', 'Checking key:', key );
16927	        return this.files[key];
16928	    },
16929	    remove: function(key) {
16930	        delete this.files[key];
16931	    },
16932	    clear: function() {
16933	        this.files = {};
16934	    }
16935	};
16936	class LoadingManager {
16937	    constructor(onLoad, onProgress, onError){
16938	        const scope = this;
16939	        let isLoading = false;
16940	        let itemsLoaded = 0;
16941	        let itemsTotal = 0;
16942	        let urlModifier = undefined;
16943	        const handlers = [];
16944	        // Refer to #5689 for the reason why we don't set .onStart
16945	        // in the constructor
16946	        this.onStart = undefined;
16947	        this.onLoad = onLoad;
16948	        this.onProgress = onProgress;
16949	        this.onError = onError;
16950	        this.itemStart = function(url) {
16951	            itemsTotal++;
16952	            if (isLoading === false) {
16953	                if (scope.onStart !== undefined) {
16954	                    scope.onStart(url, itemsLoaded, itemsTotal);
16955	                }
16956	            }
16957	            isLoading = true;
16958	        };
16959	        this.itemEnd = function(url) {
16960	            itemsLoaded++;
16961	            if (scope.onProgress !== undefined) {
16962	                scope.onProgress(url, itemsLoaded, itemsTotal);
16963	            }
16964	            if (itemsLoaded === itemsTotal) {
16965	                isLoading = false;
16966	                if (scope.onLoad !== undefined) {
16967	                    scope.onLoad();
16968	                }
16969	            }
16970	        };
16971	        this.itemError = function(url) {
16972	            if (scope.onError !== undefined) {
16973	                scope.onError(url);
16974	            }
16975	        };
16976	        this.resolveURL = function(url) {
16977	            if (urlModifier) {
16978	                return urlModifier(url);
16979	            }
16980	            return url;
16981	        };
16982	        this.setURLModifier = function(transform) {
16983	            urlModifier = transform;
16984	            return this;
16985	        };
16986	        this.addHandler = function(regex, loader) {
16987	            handlers.push(regex, loader);
16988	            return this;
16989	        };
16990	        this.removeHandler = function(regex) {
16991	            const index = handlers.indexOf(regex);
16992	            if (index !== -1) {
16993	                handlers.splice(index, 2);
16994	            }
16995	            return this;
16996	        };
16997	        this.getHandler = function(file) {
16998	            for(let i = 0, l = handlers.length; i < l; i += 2){
16999	                const regex = handlers[i];
17000	                const loader = handlers[i + 1];
17001	                if (regex.global) regex.lastIndex = 0; // see #17920
17002	                if (regex.test(file)) {
17003	                    return loader;
17004	                }
17005	            }
17006	            return null;
17007	        };
17008	    }
17009	}
17010	const DefaultLoadingManager = /*@__PURE__*/ new LoadingManager();
17011	/**
17012	 * Abstract base class for loaders.
17013	 *
17014	 * @abstract
17015	 */ class Loader {
17016	    /**
17017		 * This method needs to be implemented by all concrete loaders. It holds the
17018		 * logic for loading assets from the backend.
17019		 *
17020		 * @param {string} url - The path/URL of the file to be loaded.
17021		 * @param {Function} onLoad - Executed when the loading process has been finished.
17022		 * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
17023		 * @param {onErrorCallback} onError - Executed when errors occur.
17024		 */ load() {}
17025	    /**
17026		 * A async version of {@link Loader#load}.
17027		 *
17028		 * @param {string} url - The path/URL of the file to be loaded.
17029		 * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
17030		 * @return {Promise} A Promise that resolves when the asset has been loaded.
17031		 */ loadAsync(url, onProgress) {
17032	        const scope = this;
17033	        return new Promise(function(resolve, reject) {
17034	            scope.load(url, resolve, onProgress, reject);
17035	        });
17036	    }
17037	    /**
17038		 * This method needs to be implemented by all concrete loaders. It holds the
17039		 * logic for parsing the asset into three.js entities.
17040		 *
17041		 * @param {any} data - The data to parse.
17042		 */ parse() {}
17043	    /**
17044		 * Sets the `crossOrigin` String to implement CORS for loading the URL
17045		 * from a different domain that allows CORS.
17046		 *
17047		 * @param {string} crossOrigin - The `crossOrigin` value.
17048		 * @return {Loader} A reference to this instance.
17049		 */ setCrossOrigin(crossOrigin) {
17050	        this.crossOrigin = crossOrigin;
17051	        return this;
17052	    }
17053	    /**
17054		 * Whether the XMLHttpRequest uses credentials such as cookies, authorization
17055		 * headers or TLS client certificates, see [XMLHttpRequest.withCredentials]{@link https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials}.
17056		 *
17057		 * Note: This setting has no effect if you are loading files locally or from the same domain.
17058		 *
17059		 * @param {boolean} value - The `withCredentials` value.
17060		 * @return {Loader} A reference to this instance.
17061		 */ setWithCredentials(value) {
17062	        this.withCredentials = value;
17063	        return this;
17064	    }
17065	    /**
17066		 * Sets the base path for the asset.
17067		 *
17068		 * @param {string} path - The base path.
17069		 * @return {Loader} A reference to this instance.
17070		 */ setPath(path) {
17071	        this.path = path;
17072	        return this;
17073	    }
17074	    /**
17075		 * Sets the base path for dependent resources like textures.
17076		 *
17077		 * @param {string} resourcePath - The resource path.
17078		 * @return {Loader} A reference to this instance.
17079		 */ setResourcePath(resourcePath) {
17080	        this.resourcePath = resourcePath;
17081	        return this;
17082	    }
17083	    /**
17084		 * Sets the given request header.
17085		 *
17086		 * @param {Object} requestHeader - A [request header]{@link https://developer.mozilla.org/en-US/docs/Glossary/Request_header}
17087		 * for configuring the HTTP request.
17088		 * @return {Loader} A reference to this instance.
17089		 */ setRequestHeader(requestHeader) {
17090	        this.requestHeader = requestHeader;
17091	        return this;
17092	    }
17093	    /**
17094		 * Constructs a new loader.
17095		 *
17096		 * @param {LoadingManager} [manager] - The loading manager.
17097		 */ constructor(manager){
17098	        /**
17099			 * The loading manager.
17100			 *
17101			 * @type {LoadingManager}
17102			 * @default DefaultLoadingManager
17103			 */ this.manager = manager !== undefined ? manager : DefaultLoadingManager;
17104	        /**
17105			 * The crossOrigin string to implement CORS for loading the url from a
17106			 * different domain that allows CORS.
17107			 *
17108			 * @type {string}
17109			 * @default 'anonymous'
17110			 */ this.crossOrigin = 'anonymous';
17111	        /**
17112			 * Whether the XMLHttpRequest uses credentials.
17113			 *
17114			 * @type {boolean}
17115			 * @default false
17116			 */ this.withCredentials = false;
17117	        /**
17118			 * The base path from which the asset will be loaded.
17119			 *
17120			 * @type {string}
17121			 */ this.path = '';
17122	        /**
17123			 * The base path from which additional resources like textures will be loaded.
17124			 *
17125			 * @type {string}
17126			 */ this.resourcePath = '';
17127	        /**
17128			 * The [request header]{@link https://developer.mozilla.org/en-US/docs/Glossary/Request_header}
17129			 * used in HTTP request.
17130			 *
17131			 * @type {Object}
17132			 */ this.requestHeader = {};
17133	    }
17134	}
17135	/**
17136	 * Callback for onProgress in loaders.
17137	 *
17138	 *
17139	 * @callback onProgressCallback
17140	 * @param {ProgressEvent} event - An instance of `ProgressEvent` that represents the current loading status.
17141	 */ /**
17142	 * Callback for onError in loaders.
17143	 *
17144	 *
17145	 * @callback onErrorCallback
17146	 * @param {Error} error - The error which occurred during the loading process.
17147	 */ /**
17148	 * The default material name that is used by loaders
17149	 * when creating materials for loaded 3D objects.
17150	 *
17151	 * Note: Not all loaders might honor this setting.
17152	 *
17153	 * @static
17154	 * @type {string}
17155	 * @default '__DEFAULT'
17156	 */ Loader.DEFAULT_MATERIAL_NAME = '__DEFAULT';
17157	const loading = {};
17158	class HttpError extends Error {
17159	    constructor(message, response){
17160	        super(message);
17161	        this.response = response;
17162	    }
17163	}
17164	class FileLoader extends Loader {
17165	    load(url, onLoad, onProgress, onError) {
17166	        if (url === undefined) url = '';
17167	        if (this.path !== undefined) url = this.path + url;
17168	        url = this.manager.resolveURL(url);
17169	        const cached = Cache.get(url);
17170	        if (cached !== undefined) {
17171	            this.manager.itemStart(url);
17172	            setTimeout(()=>{
17173	                if (onLoad) onLoad(cached);
17174	                this.manager.itemEnd(url);
17175	            }, 0);
17176	            return cached;
17177	        }
17178	        // Check if request is duplicate
17179	        if (loading[url] !== undefined) {
17180	            loading[url].push({
17181	                onLoad: onLoad,
17182	                onProgress: onProgress,
17183	                onError: onError
17184	            });
17185	            return;
17186	        }
17187	        // Initialise array for duplicate requests
17188	        loading[url] = [];
17189	        loading[url].push({
17190	            onLoad: onLoad,
17191	            onProgress: onProgress,
17192	            onError: onError
17193	        });
17194	        // create request
17195	        const req = new Request(url, {
17196	            headers: new Headers(this.requestHeader),
17197	            credentials: this.withCredentials ? 'include' : 'same-origin'
17198	        });
17199	        // record states ( avoid data race )
17200	        const mimeType = this.mimeType;
17201	        const responseType = this.responseType;
17202	        // start the fetch
17203	        fetch(req).then((response)=>{
17204	            if (response.status === 200 || response.status === 0) {
17205	                // Some browsers return HTTP Status 0 when using non-http protocol
17206	                // e.g. 'file://' or 'data://'. Handle as success.
17207	                if (response.status === 0) {
17208	                    console.warn('THREE.FileLoader: HTTP Status 0 received.');
17209	                }
17210	                // Workaround: Checking if response.body === undefined for Alipay browser #23548
17211	                if (typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined) {
17212	                    return response;
17213	                }
17214	                const callbacks = loading[url];
17215	                const reader = response.body.getReader();
17216	                // Nginx needs X-File-Size check
17217	                // https://serverfault.com/questions/482875/why-does-nginx-remove-content-length-header-for-chunked-content
17218	                const contentLength = response.headers.get('X-File-Size') || response.headers.get('Content-Length');
17219	                const total = contentLength ? parseInt(contentLength) : 0;
17220	                const lengthComputable = total !== 0;
17221	                let loaded = 0;
17222	                // periodically read data into the new stream tracking while download progress
17223	                const stream = new ReadableStream({
17224	                    start (controller) {
17225	                        readData();
17226	                        function readData() {
17227	                            reader.read().then(({ done, value })=>{
17228	                                if (done) {
17229	                                    controller.close();
17230	                                } else {
17231	                                    loaded += value.byteLength;
17232	                                    const event = new ProgressEvent('progress', {
17233	                                        lengthComputable,
17234	                                        loaded,
17235	                                        total
17236	                                    });
17237	                                    for(let i = 0, il = callbacks.length; i < il; i++){
17238	                                        const callback = callbacks[i];
17239	                                        if (callback.onProgress) callback.onProgress(event);
17240	                                    }
17241	                                    controller.enqueue(value);
17242	                                    readData();
17243	                                }
17244	                            }, (e)=>{
17245	                                controller.error(e);
17246	                            });
17247	                        }
17248	                    }
17249	                });
17250	                return new Response(stream);
17251	            } else {
17252	                throw new HttpError(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response);
17253	            }
17254	        }).then((response)=>{
17255	            switch(responseType){
17256	                case 'arraybuffer':
17257	                    return response.arrayBuffer();
17258	                case 'blob':
17259	                    return response.blob();
17260	                case 'document':
17261	                    return response.text().then((text)=>{
17262	                        const parser = new DOMParser();
17263	                        return parser.parseFromString(text, mimeType);
17264	                    });
17265	                case 'json':
17266	                    return response.json();
17267	                default:
17268	                    if (mimeType === undefined) {
17269	                        return response.text();
17270	                    } else {
17271	                        // sniff encoding
17272	                        const re = /charset="?([^;"\s]*)"?/i;
17273	                        const exec = re.exec(mimeType);
17274	                        const label = exec && exec[1] ? exec[1].toLowerCase() : undefined;
17275	                        const decoder = new TextDecoder(label);
17276	                        return response.arrayBuffer().then((ab)=>decoder.decode(ab));
17277	                    }
17278	            }
17279	        }).then((data)=>{
17280	            // Add to cache only on HTTP success, so that we do not cache
17281	            // error response bodies as proper responses to requests.
17282	            Cache.add(url, data);
17283	            const callbacks = loading[url];
17284	            delete loading[url];
17285	            for(let i = 0, il = callbacks.length; i < il; i++){
17286	                const callback = callbacks[i];
17287	                if (callback.onLoad) callback.onLoad(data);
17288	            }
17289	        }).catch((err)=>{
17290	            // Abort errors and other errors are handled the same
17291	            const callbacks = loading[url];
17292	            if (callbacks === undefined) {
17293	                // When onLoad was called and url was deleted in `loading`
17294	                this.manager.itemError(url);
17295	                throw err;
17296	            }
17297	            delete loading[url];
17298	            for(let i = 0, il = callbacks.length; i < il; i++){
17299	                const callback = callbacks[i];
17300	                if (callback.onError) callback.onError(err);
17301	            }
17302	            this.manager.itemError(url);
17303	        }).finally(()=>{
17304	            this.manager.itemEnd(url);
17305	        });
17306	        this.manager.itemStart(url);
17307	    }
17308	    setResponseType(value) {
17309	        this.responseType = value;
17310	        return this;
17311	    }
17312	    setMimeType(value) {
17313	        this.mimeType = value;
17314	        return this;
17315	    }
17316	    constructor(manager){
17317	        super(manager);
17318	    }
17319	}
17320	class ImageLoader extends Loader {
17321	    load(url, onLoad, onProgress, onError) {
17322	        if (this.path !== undefined) url = this.path + url;
17323	        url = this.manager.resolveURL(url);
17324	        const scope = this;
17325	        const cached = Cache.get(url);
17326	        if (cached !== undefined) {
17327	            scope.manager.itemStart(url);
17328	            setTimeout(function() {
17329	                if (onLoad) onLoad(cached);
17330	                scope.manager.itemEnd(url);
17331	            }, 0);
17332	            return cached;
17333	        }
17334	        const image = createElementNS('img');
17335	        function onImageLoad() {
17336	            removeEventListeners();
17337	            Cache.add(url, this);
17338	            if (onLoad) onLoad(this);
17339	            scope.manager.itemEnd(url);
17340	        }
17341	        function onImageError(event) {
17342	            removeEventListeners();
17343	            if (onError) onError(event);
17344	            scope.manager.itemError(url);
17345	            scope.manager.itemEnd(url);
17346	        }
17347	        function removeEventListeners() {
17348	            image.removeEventListener('load', onImageLoad, false);
17349	            image.removeEventListener('error', onImageError, false);
17350	        }
17351	        image.addEventListener('load', onImageLoad, false);
17352	        image.addEventListener('error', onImageError, false);
17353	        if (url.slice(0, 5) !== 'data:') {
17354	            if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin;
17355	        }
17356	        scope.manager.itemStart(url);
17357	        image.src = url;
17358	        return image;
17359	    }
17360	    constructor(manager){
17361	        super(manager);
17362	    }
17363	}
17364	/**
17365	 * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
17366	 *
17367	 * Sub classes have to implement the parse() method which will be used in load().
17368	 */ class DataTextureLoader extends Loader {
17369	    load(url, onLoad, onProgress, onError) {
17370	        const scope = this;
17371	        const texture = new DataTexture();
17372	        const loader = new FileLoader(this.manager);
17373	        loader.setResponseType('arraybuffer');
17374	        loader.setRequestHeader(this.requestHeader);
17375	        loader.setPath(this.path);
17376	        loader.setWithCredentials(scope.withCredentials);
17377	        loader.load(url, function(buffer) {
17378	            let texData;
17379	            try {
17380	                texData = scope.parse(buffer);
17381	            } catch (error) {
17382	                if (onError !== undefined) {
17383	                    onError(error);
17384	                } else {
17385	                    console.error(error);
17386	                    return;
17387	                }
17388	            }
17389	            if (texData.image !== undefined) {
17390	                texture.image = texData.image;
17391	            } else if (texData.data !== undefined) {
17392	                texture.image.width = texData.width;
17393	                texture.image.height = texData.height;
17394	                texture.image.data = texData.data;
17395	            }
17396	            texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
17397	            texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
17398	            texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
17399	            texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
17400	            texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
17401	            if (texData.colorSpace !== undefined) {
17402	                texture.colorSpace = texData.colorSpace;
17403	            }
17404	            if (texData.flipY !== undefined) {
17405	                texture.flipY = texData.flipY;
17406	            }
17407	            if (texData.format !== undefined) {
17408	                texture.format = texData.format;
17409	            }
17410	            if (texData.type !== undefined) {
17411	                texture.type = texData.type;
17412	            }
17413	            if (texData.mipmaps !== undefined) {
17414	                texture.mipmaps = texData.mipmaps;
17415	                texture.minFilter = LinearMipmapLinearFilter; // presumably...
17416	            }
17417	            if (texData.mipmapCount === 1) {
17418	                texture.minFilter = LinearFilter;
17419	            }
17420	            if (texData.generateMipmaps !== undefined) {
17421	                texture.generateMipmaps = texData.generateMipmaps;
17422	            }
17423	            texture.needsUpdate = true;
17424	            if (onLoad) onLoad(texture, texData);
17425	        }, onProgress, onError);
17426	        return texture;
17427	    }
17428	    constructor(manager){
17429	        super(manager);
17430	    }
17431	}
17432	class TextureLoader extends Loader {
17433	    load(url, onLoad, onProgress, onError) {
17434	        const texture = new Texture$1();
17435	        const loader = new ImageLoader(this.manager);
17436	        loader.setCrossOrigin(this.crossOrigin);
17437	        loader.setPath(this.path);
17438	        loader.load(url, function(image) {
17439	            texture.image = image;
17440	            texture.needsUpdate = true;
17441	            if (onLoad !== undefined) {
17442	                onLoad(texture);
17443	            }
17444	        }, onProgress, onError);
17445	        return texture;
17446	    }
17447	    constructor(manager){
17448	        super(manager);
17449	    }
17450	}
17451	/**
17452	 * Abstract base class for lights - all other light types inherit the
17453	 * properties and methods described here.
17454	 *
17455	 * @abstract
17456	 * @augments Object3D
17457	 */ class Light extends Object3D {
17458	    /**
17459		 * Frees the GPU-related resources allocated by this instance. Call this
17460		 * method whenever this instance is no longer used in your app.
17461		 */ dispose() {
17462	    // Empty here in base class; some subclasses override.
17463	    }
17464	    copy(source, recursive) {
17465	        super.copy(source, recursive);
17466	        this.color.copy(source.color);
17467	        this.intensity = source.intensity;
17468	        return this;
17469	    }
17470	    toJSON(meta) {
17471	        const data = super.toJSON(meta);
17472	        data.object.color = this.color.getHex();
17473	        data.object.intensity = this.intensity;
17474	        if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex();
17475	        if (this.distance !== undefined) data.object.distance = this.distance;
17476	        if (this.angle !== undefined) data.object.angle = this.angle;
17477	        if (this.decay !== undefined) data.object.decay = this.decay;
17478	        if (this.penumbra !== undefined) data.object.penumbra = this.penumbra;
17479	        if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON();
17480	        if (this.target !== undefined) data.object.target = this.target.uuid;
17481	        return data;
17482	    }
17483	    /**
17484		 * Constructs a new light.
17485		 *
17486		 * @param {(number|Color|string)} [color=0xffffff] - The light's color.
17487		 * @param {number} [intensity=1] - The light's strength/intensity.
17488		 */ constructor(color, intensity = 1){
17489	        super();
17490	        /**
17491			 * This flag can be used for type testing.
17492			 *
17493			 * @type {boolean}
17494			 * @readonly
17495			 * @default true
17496			 */ this.isLight = true;
17497	        this.type = 'Light';
17498	        /**
17499			 * The light's color.
17500			 *
17501			 * @type {Color}
17502			 */ this.color = new Color(color);
17503	        /**
17504			 * The light's intensity.
17505			 *
17506			 * @type {number}
17507			 * @default 1
17508			 */ this.intensity = intensity;
17509	    }
17510	}
17511	const _projScreenMatrix$1 = /*@__PURE__*/ new Matrix4();
17512	const _lightPositionWorld$1 = /*@__PURE__*/ new Vector3();
17513	const _lookTarget$1 = /*@__PURE__*/ new Vector3();
17514	/**
17515	 * Abstract base class for light shadow classes. These classes
17516	 * represent the shadow configuration for different ligth types.
17517	 *
17518	 * @abstract
17519	 */ class LightShadow {
17520	    /**
17521		 * Used internally by the renderer to get the number of viewports that need
17522		 * to be rendered for this shadow.
17523		 *
17524		 * @return {number} The viewport count.
17525		 */ getViewportCount() {
17526	        return this._viewportCount;
17527	    }
17528	    /**
17529		 * Gets the shadow cameras frustum. Used internally by the renderer to cull objects.
17530		 *
17531		 * @return {Frustum} The shadow camera frustum.
17532		 */ getFrustum() {
17533	        return this._frustum;
17534	    }
17535	    /**
17536		 * Update the matrices for the camera and shadow, used internally by the renderer.
17537		 *
17538		 * @param {Light} light - The light for which the shadow is being rendered.
17539		 */ updateMatrices(light) {
17540	        const shadowCamera = this.camera;
17541	        const shadowMatrix = this.matrix;
17542	        _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld);
17543	        shadowCamera.position.copy(_lightPositionWorld$1);
17544	        _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld);
17545	        shadowCamera.lookAt(_lookTarget$1);
17546	        shadowCamera.updateMatrixWorld();
17547	        _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse);
17548	        this._frustum.setFromProjectionMatrix(_projScreenMatrix$1);
17549	        shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
17550	        shadowMatrix.multiply(_projScreenMatrix$1);
17551	    }
17552	    /**
17553		 * Returns a viewport definition for the given viewport index.
17554		 *
17555		 * @param {number} viewportIndex - The viewport index.
17556		 * @return {Vector4} The viewport.
17557		 */ getViewport(viewportIndex) {
17558	        return this._viewports[viewportIndex];
17559	    }
17560	    /**
17561		 * Returns the frame extends.
17562		 *
17563		 * @return {Vector2} The frame extends.
17564		 */ getFrameExtents() {
17565	        return this._frameExtents;
17566	    }
17567	    /**
17568		 * Frees the GPU-related resources allocated by this instance. Call this
17569		 * method whenever this instance is no longer used in your app.
17570		 */ dispose() {
17571	        if (this.map) {
17572	            this.map.dispose();
17573	        }
17574	        if (this.mapPass) {
17575	            this.mapPass.dispose();
17576	        }
17577	    }
17578	    /**
17579		 * Copies the values of the given light shadow instance to this instance.
17580		 *
17581		 * @param {LightShadow} source - The light shadow to copy.
17582		 * @return {LightShadow} A reference to this light shadow instance.
17583		 */ copy(source) {
17584	        this.camera = source.camera.clone();
17585	        this.intensity = source.intensity;
17586	        this.bias = source.bias;
17587	        this.radius = source.radius;
17588	        this.mapSize.copy(source.mapSize);
17589	        return this;
17590	    }
17591	    /**
17592		 * Returns a new light shadow instance with copied values from this instance.
17593		 *
17594		 * @return {LightShadow} A clone of this instance.
17595		 */ clone() {
17596	        return new this.constructor().copy(this);
17597	    }
17598	    /**
17599		 * Serializes the light shadow into JSON.
17600		 *
17601		 * @return {Object} A JSON object representing the serialized light shadow.
17602		 * @see {@link ObjectLoader#parse}
17603		 */ toJSON() {
17604	        const object = {};
17605	        if (this.intensity !== 1) object.intensity = this.intensity;
17606	        if (this.bias !== 0) object.bias = this.bias;
17607	        if (this.normalBias !== 0) object.normalBias = this.normalBias;
17608	        if (this.radius !== 1) object.radius = this.radius;
17609	        if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray();
17610	        object.camera = this.camera.toJSON(false).object;
17611	        delete object.camera.matrix;
17612	        return object;
17613	    }
17614	    /**
17615		 * Constructs a new light shadow.
17616		 *
17617		 * @param {Camera} camera - The light's view of the world.
17618		 */ constructor(camera){
17619	        /**
17620			 * The light's view of the world.
17621			 *
17622			 * @type {Camera}
17623			 */ this.camera = camera;
17624	        /**
17625			 * The intensity of the shadow. The default is `1`.
17626			 * Valid values are in the range `[0, 1]`.
17627			 *
17628			 * @type {number}
17629			 * @default 1
17630			 */ this.intensity = 1;
17631	        /**
17632			 * Shadow map bias, how much to add or subtract from the normalized depth
17633			 * when deciding whether a surface is in shadow.
17634			 *
17635			 * The default is `0`. Very tiny adjustments here (in the order of `0.0001`)
17636			 * may help reduce artifacts in shadows.
17637			 *
17638			 * @type {number}
17639			 * @default 0
17640			 */ this.bias = 0;
17641	        /**
17642			 * Defines how much the position used to query the shadow map is offset along
17643			 * the object normal. The default is `0`. Increasing this value can be used to
17644			 * reduce shadow acne especially in large scenes where light shines onto
17645			 * geometry at a shallow angle. The cost is that shadows may appear distorted.
17646			 *
17647			 * @type {number}
17648			 * @default 0
17649			 */ this.normalBias = 0;
17650	        /**
17651			 * Setting this to values greater than 1 will blur the edges of the shadow.
17652			 * High values will cause unwanted banding effects in the shadows - a greater
17653			 * map size will allow for a higher value to be used here before these effects
17654			 * become visible.
17655			 *
17656			 * The property has no effect when the shadow map type is `PCFSoftShadowMap` and
17657			 * and it is recommended to increase softness by decreasing the shadow map size instead.
17658			 *
17659			 * The property has no effect when the shadow map type is `BasicShadowMap`.
17660			 *
17661			 * @type {number}
17662			 * @default 1
17663			 */ this.radius = 1;
17664	        /**
17665			 * The amount of samples to use when blurring a VSM shadow map.
17666			 *
17667			 * @type {number}
17668			 * @default 8
17669			 */ this.blurSamples = 8;
17670	        /**
17671			 * Defines the width and height of the shadow map. Higher values give better quality
17672			 * shadows at the cost of computation time. Values must be powers of two.
17673			 *
17674			 * @type {Vector2}
17675			 * @default (512,512)
17676			 */ this.mapSize = new Vector2(512, 512);
17677	        /**
17678			 * The depth map generated using the internal camera; a location beyond a
17679			 * pixel's depth is in shadow. Computed internally during rendering.
17680			 *
17681			 * @type {?RenderTarget}
17682			 * @default null
17683			 */ this.map = null;
17684	        /**
17685			 * The distribution map generated using the internal camera; an occlusion is
17686			 * calculated based on the distribution of depths. Computed internally during
17687			 * rendering.
17688			 *
17689			 * @type {?RenderTarget}
17690			 * @default null
17691			 */ this.mapPass = null;
17692	        /**
17693			 * Model to shadow camera space, to compute location and depth in shadow map.
17694			 * This is computed internally during rendering.
17695			 *
17696			 * @type {Matrix4}
17697			 */ this.matrix = new Matrix4();
17698	        /**
17699			 * Enables automatic updates of the light's shadow. If you do not require dynamic
17700			 * lighting / shadows, you may set this to `false`.
17701			 *
17702			 * @type {boolean}
17703			 * @default true
17704			 */ this.autoUpdate = true;
17705	        /**
17706			 * When set to `true`, shadow maps will be updated in the next `render` call.
17707			 * If you have set {@link LightShadow#autoUpdate} to `false`, you will need to
17708			 * set this property to `true` and then make a render call to update the light's shadow.
17709			 *
17710			 * @type {boolean}
17711			 * @default false
17712			 */ this.needsUpdate = false;
17713	        this._frustum = new Frustum();
17714	        this._frameExtents = new Vector2(1, 1);
17715	        this._viewportCount = 1;
17716	        this._viewports = [
17717	            new Vector4(0, 0, 1, 1)
17718	        ];
17719	    }
17720	}
17721	/**
17722	 * Represents the shadow configuration of directional lights.
17723	 *
17724	 * @augments LightShadow
17725	 */ class SpotLightShadow extends LightShadow {
17726	    updateMatrices(light) {
17727	        const camera = this.camera;
17728	        const fov = RAD2DEG * 2 * light.angle * this.focus;
17729	        const aspect = this.mapSize.width / this.mapSize.height;
17730	        const far = light.distance || camera.far;
17731	        if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) {
17732	            camera.fov = fov;
17733	            camera.aspect = aspect;
17734	            camera.far = far;
17735	            camera.updateProjectionMatrix();
17736	        }
17737	        super.updateMatrices(light);
17738	    }
17739	    copy(source) {
17740	        super.copy(source);
17741	        this.focus = source.focus;
17742	        return this;
17743	    }
17744	    /**
17745		 * Constructs a new spot light shadow.
17746		 */ constructor(){
17747	        super(new PerspectiveCamera(50, 1, 0.5, 500));
17748	        /**
17749			 * This flag can be used for type testing.
17750			 *
17751			 * @type {boolean}
17752			 * @readonly
17753			 * @default true
17754			 */ this.isSpotLightShadow = true;
17755	        /**
17756			 * Used to focus the shadow camera. The camera's field of view is set as a
17757			 * percentage of the spotlight's field-of-view. Range is `[0, 1]`.
17758			 *
17759			 * @type {number}
17760			 * @default 1
17761			 */ this.focus = 1;
17762	    }
17763	}
17764	/**
17765	 * This light gets emitted from a single point in one direction, along a cone
17766	 * that increases in size the further from the light it gets.
17767	 *
17768	 * This light can cast shadows - see the {@link SpotLightShadow} for details.
17769	 *
17770	 * ```js
17771	 * // white spotlight shining from the side, modulated by a texture
17772	 * const spotLight = new THREE.SpotLight( 0xffffff );
17773	 * spotLight.position.set( 100, 1000, 100 );
17774	 * spotLight.map = new THREE.TextureLoader().load( url );
17775	 *
17776	 * spotLight.castShadow = true;
17777	 * spotLight.shadow.mapSize.width = 1024;
17778	 * spotLight.shadow.mapSize.height = 1024;
17779	 * spotLight.shadow.camera.near = 500;
17780	 * spotLight.shadow.camera.far = 4000;
17781	 * spotLight.shadow.camera.fov = 30;s
17782	 * ```
17783	 *
17784	 * @augments Light
17785	 */ class SpotLight extends Light {
17786	    /**
17787		 * The light's power. Power is the luminous power of the light measured in lumens (lm).
17788		 *  Changing the power will also change the light's intensity.
17789		 *
17790		 * @type {number}
17791		 */ get power() {
17792	        // compute the light's luminous power (in lumens) from its intensity (in candela)
17793	        // by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd)
17794	        return this.intensity * Math.PI;
17795	    }
17796	    set power(power) {
17797	        // set the light's intensity (in candela) from the desired luminous power (in lumens)
17798	        this.intensity = power / Math.PI;
17799	    }
17800	    dispose() {
17801	        this.shadow.dispose();
17802	    }
17803	    copy(source, recursive) {
17804	        super.copy(source, recursive);
17805	        this.distance = source.distance;
17806	        this.angle = source.angle;
17807	        this.penumbra = source.penumbra;
17808	        this.decay = source.decay;
17809	        this.target = source.target.clone();
17810	        this.shadow = source.shadow.clone();
17811	        return this;
17812	    }
17813	    /**
17814		 * Constructs a new spot light.
17815		 *
17816		 * @param {(number|Color|string)} [color=0xffffff] - The light's color.
17817		 * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
17818		 * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
17819		 * @param {number} [angle=Math.PI/3] - Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`.
17820		 * @param {number} [penumbra=0] - Percent of the spotlight cone that is attenuated due to penumbra. Value range is `[0,1]`.
17821		 * @param {number} [decay=2] - The amount the light dims along the distance of the light.
17822		 */ constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 2){
17823	        super(color, intensity);
17824	        /**
17825			 * This flag can be used for type testing.
17826			 *
17827			 * @type {boolean}
17828			 * @readonly
17829			 * @default true
17830			 */ this.isSpotLight = true;
17831	        this.type = 'SpotLight';
17832	        this.position.copy(Object3D.DEFAULT_UP);
17833	        this.updateMatrix();
17834	        /**
17835			 * The spot light points from its position to the
17836			 * target's position.
17837			 *
17838			 * For the target's position to be changed to anything other
17839			 * than the default, it must be added to the scene.
17840			 *
17841			 * It is also possible to set the target to be another 3D object
17842			 * in the scene. The light will now track the target object.
17843			 *
17844			 * @type {Object3D}
17845			 */ this.target = new Object3D();
17846	        /**
17847			 * Maximum range of the light. `0` means no limit.
17848			 *
17849			 * @type {number}
17850			 * @default 0
17851			 */ this.distance = distance;
17852	        /**
17853			 * Maximum angle of light dispersion from its direction whose upper bound is `Math.PI/2`.
17854			 *
17855			 * @type {number}
17856			 * @default Math.PI/3
17857			 */ this.angle = angle;
17858	        /**
17859			 * Percent of the spotlight cone that is attenuated due to penumbra.
17860			 * Value range is `[0,1]`.
17861			 *
17862			 * @type {number}
17863			 * @default 0
17864			 */ this.penumbra = penumbra;
17865	        /**
17866			 * The amount the light dims along the distance of the light. In context of
17867			 * physically-correct rendering the default value should not be changed.
17868			 *
17869			 * @type {number}
17870			 * @default 2
17871			 */ this.decay = decay;
17872	        /**
17873			 * A texture used to modulate the color of the light. The spot light
17874			 * color is mixed with the RGB value of this texture, with a ratio
17875			 * corresponding to its alpha value. The cookie-like masking effect is
17876			 * reproduced using pixel values (0, 0, 0, 1-cookie_value).
17877			 *
17878			 * *Warning*: This property is disabled if {@link Object3D#castShadow} is set to `false`.
17879			 *
17880			 * @type {?Texture}
17881			 * @default null
17882			 */ this.map = null;
17883	        /**
17884			 * This property holds the light's shadow configuration.
17885			 *
17886			 * @type {SpotLightShadow}
17887			 */ this.shadow = new SpotLightShadow();
17888	    }
17889	}
17890	const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
17891	const _lightPositionWorld = /*@__PURE__*/ new Vector3();
17892	const _lookTarget = /*@__PURE__*/ new Vector3();
17893	/**
17894	 * Represents the shadow configuration of point lights.
17895	 *
17896	 * @augments LightShadow
17897	 */ class PointLightShadow extends LightShadow {
17898	    /**
17899		 * Update the matrices for the camera and shadow, used internally by the renderer.
17900		 *
17901		 * @param {Light} light - The light for which the shadow is being rendered.
17902		 * @param {number} [viewportIndex=0] - The viewport index.
17903		 */ updateMatrices(light, viewportIndex = 0) {
17904	        const camera = this.camera;
17905	        const shadowMatrix = this.matrix;
17906	        const far = light.distance || camera.far;
17907	        if (far !== camera.far) {
17908	            camera.far = far;
17909	            camera.updateProjectionMatrix();
17910	        }
17911	        _lightPositionWorld.setFromMatrixPosition(light.matrixWorld);
17912	        camera.position.copy(_lightPositionWorld);
17913	        _lookTarget.copy(camera.position);
17914	        _lookTarget.add(this._cubeDirections[viewportIndex]);
17915	        camera.up.copy(this._cubeUps[viewportIndex]);
17916	        camera.lookAt(_lookTarget);
17917	        camera.updateMatrixWorld();
17918	        shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z);
17919	        _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
17920	        this._frustum.setFromProjectionMatrix(_projScreenMatrix);
17921	    }
17922	    /**
17923		 * Constructs a new point light shadow.
17924		 */ constructor(){
17925	        super(new PerspectiveCamera(90, 1, 0.5, 500));
17926	        /**
17927			 * This flag can be used for type testing.
17928			 *
17929			 * @type {boolean}
17930			 * @readonly
17931			 * @default true
17932			 */ this.isPointLightShadow = true;
17933	        this._frameExtents = new Vector2(4, 2);
17934	        this._viewportCount = 6;
17935	        this._viewports = [
17936	            // These viewports map a cube-map onto a 2D texture with the
17937	            // following orientation:
17938	            //
17939	            //  xzXZ
17940	            //   y Y
17941	            //
17942	            // X - Positive x direction
17943	            // x - Negative x direction
17944	            // Y - Positive y direction
17945	            // y - Negative y direction
17946	            // Z - Positive z direction
17947	            // z - Negative z direction
17948	            // positive X
17949	            new Vector4(2, 1, 1, 1),
17950	            // negative X
17951	            new Vector4(0, 1, 1, 1),
17952	            // positive Z
17953	            new Vector4(3, 1, 1, 1),
17954	            // negative Z
17955	            new Vector4(1, 1, 1, 1),
17956	            // positive Y
17957	            new Vector4(3, 0, 1, 1),
17958	            // negative Y
17959	            new Vector4(1, 0, 1, 1)
17960	        ];
17961	        this._cubeDirections = [
17962	            new Vector3(1, 0, 0),
17963	            new Vector3(-1, 0, 0),
17964	            new Vector3(0, 0, 1),
17965	            new Vector3(0, 0, -1),
17966	            new Vector3(0, 1, 0),
17967	            new Vector3(0, -1, 0)
17968	        ];
17969	        this._cubeUps = [
17970	            new Vector3(0, 1, 0),
17971	            new Vector3(0, 1, 0),
17972	            new Vector3(0, 1, 0),
17973	            new Vector3(0, 1, 0),
17974	            new Vector3(0, 0, 1),
17975	            new Vector3(0, 0, -1)
17976	        ];
17977	    }
17978	}
17979	/**
17980	 * A light that gets emitted from a single point in all directions. A common
17981	 * use case for this is to replicate the light emitted from a bare
17982	 * lightbulb.
17983	 *
17984	 * This light can cast shadows - see the {@link PointLightShadow} for details.
17985	 *
17986	 * ```js
17987	 * const light = new THREE.PointLight( 0xff0000, 1, 100 );
17988	 * light.position.set( 50, 50, 50 );
17989	 * scene.add( light );
17990	 * ```
17991	 *
17992	 * @augments Light
17993	 */ class PointLight extends Light {
17994	    /**
17995		 * The light's power. Power is the luminous power of the light measured in lumens (lm).
17996		 * Changing the power will also change the light's intensity.
17997		 *
17998		 * @type {number}
17999		 */ get power() {
18000	        // compute the light's luminous power (in lumens) from its intensity (in candela)
18001	        // for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd)
18002	        return this.intensity * 4 * Math.PI;
18003	    }
18004	    set power(power) {
18005	        // set the light's intensity (in candela) from the desired luminous power (in lumens)
18006	        this.intensity = power / (4 * Math.PI);
18007	    }
18008	    dispose() {
18009	        this.shadow.dispose();
18010	    }
18011	    copy(source, recursive) {
18012	        super.copy(source, recursive);
18013	        this.distance = source.distance;
18014	        this.decay = source.decay;
18015	        this.shadow = source.shadow.clone();
18016	        return this;
18017	    }
18018	    /**
18019		 * Constructs a new point light.
18020		 *
18021		 * @param {(number|Color|string)} [color=0xffffff] - The light's color.
18022		 * @param {number} [intensity=1] - The light's strength/intensity measured in candela (cd).
18023		 * @param {number} [distance=0] - Maximum range of the light. `0` means no limit.
18024		 * @param {number} [decay=2] - The amount the light dims along the distance of the light.
18025		 */ constructor(color, intensity, distance = 0, decay = 2){
18026	        super(color, intensity);
18027	        /**
18028			 * This flag can be used for type testing.
18029			 *
18030			 * @type {boolean}
18031			 * @readonly
18032			 * @default true
18033			 */ this.isPointLight = true;
18034	        this.type = 'PointLight';
18035	        /**
18036			 * When distance is zero, light will attenuate according to inverse-square
18037			 * law to infinite distance. When distance is non-zero, light will attenuate
18038			 * according to inverse-square law until near the distance cutoff, where it
18039			 * will then attenuate quickly and smoothly to 0. Inherently, cutoffs are not
18040			 * physically correct.
18041			 *
18042			 * @type {number}
18043			 * @default 0
18044			 */ this.distance = distance;
18045	        /**
18046			 * The amount the light dims along the distance of the light. In context of
18047			 * physically-correct rendering the default value should not be changed.
18048			 *
18049			 * @type {number}
18050			 * @default 2
18051			 */ this.decay = decay;
18052	        /**
18053			 * This property holds the light's shadow configuration.
18054			 *
18055			 * @type {PointLightShadow}
18056			 */ this.shadow = new PointLightShadow();
18057	    }
18058	}
18059	/**
18060	 * Camera that uses [orthographic projection]{@link https://en.wikipedia.org/wiki/Orthographic_projection}.
18061	 *
18062	 * In this projection mode, an object's size in the rendered image stays
18063	 * constant regardless of its distance from the camera. This can be useful
18064	 * for rendering 2D scenes and UI elements, amongst other things.
18065	 *
18066	 * ```js
18067	 * const camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, 1, 1000 );
18068	 * scene.add( camera );
18069	 * ```
18070	 *
18071	 * @augments Camera
18072	 */ class OrthographicCamera extends Camera {
18073	    copy(source, recursive) {
18074	        super.copy(source, recursive);
18075	        this.left = source.left;
18076	        this.right = source.right;
18077	        this.top = source.top;
18078	        this.bottom = source.bottom;
18079	        this.near = source.near;
18080	        this.far = source.far;
18081	        this.zoom = source.zoom;
18082	        this.view = source.view === null ? null : Object.assign({}, source.view);
18083	        return this;
18084	    }
18085	    /**
18086		 * Sets an offset in a larger frustum. This is useful for multi-window or
18087		 * multi-monitor/multi-machine setups.
18088		 *
18089		 * @param {number} fullWidth - The full width of multiview setup.
18090		 * @param {number} fullHeight - The full height of multiview setup.
18091		 * @param {number} x - The horizontal offset of the subcamera.
18092		 * @param {number} y - The vertical offset of the subcamera.
18093		 * @param {number} width - The width of subcamera.
18094		 * @param {number} height - The height of subcamera.
18095		 * @see {@link PerspectiveCamera#setViewOffset}
18096		 */ setViewOffset(fullWidth, fullHeight, x, y, width, height) {
18097	        if (this.view === null) {
18098	            this.view = {
18099	                enabled: true,
18100	                fullWidth: 1,
18101	                fullHeight: 1,
18102	                offsetX: 0,
18103	                offsetY: 0,
18104	                width: 1,
18105	                height: 1
18106	            };
18107	        }
18108	        this.view.enabled = true;
18109	        this.view.fullWidth = fullWidth;
18110	        this.view.fullHeight = fullHeight;
18111	        this.view.offsetX = x;
18112	        this.view.offsetY = y;
18113	        this.view.width = width;
18114	        this.view.height = height;
18115	        this.updateProjectionMatrix();
18116	    }
18117	    /**
18118		 * Removes the view offset from the projection matrix.
18119		 */ clearViewOffset() {
18120	        if (this.view !== null) {
18121	            this.view.enabled = false;
18122	        }
18123	        this.updateProjectionMatrix();
18124	    }
18125	    /**
18126		 * Updates the camera's projection matrix. Must be called after any change of
18127		 * camera properties.
18128		 */ updateProjectionMatrix() {
18129	        const dx = (this.right - this.left) / (2 * this.zoom);
18130	        const dy = (this.top - this.bottom) / (2 * this.zoom);
18131	        const cx = (this.right + this.left) / 2;
18132	        const cy = (this.top + this.bottom) / 2;
18133	        let left = cx - dx;
18134	        let right = cx + dx;
18135	        let top = cy + dy;
18136	        let bottom = cy - dy;
18137	        if (this.view !== null && this.view.enabled) {
18138	            const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom;
18139	            const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
18140	            left += scaleW * this.view.offsetX;
18141	            right = left + scaleW * this.view.width;
18142	            top -= scaleH * this.view.offsetY;
18143	            bottom = top - scaleH * this.view.height;
18144	        }
18145	        this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far, this.coordinateSystem);
18146	        this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
18147	    }
18148	    toJSON(meta) {
18149	        const data = super.toJSON(meta);
18150	        data.object.zoom = this.zoom;
18151	        data.object.left = this.left;
18152	        data.object.right = this.right;
18153	        data.object.top = this.top;
18154	        data.object.bottom = this.bottom;
18155	        data.object.near = this.near;
18156	        data.object.far = this.far;
18157	        if (this.view !== null) data.object.view = Object.assign({}, this.view);
18158	        return data;
18159	    }
18160	    /**
18161		 * Constructs a new orthographic camera.
18162		 *
18163		 * @param {number} [left=-1] - The left plane of the camera's frustum.
18164		 * @param {number} [right=1] - The right plane of the camera's frustum.
18165		 * @param {number} [top=1] - The top plane of the camera's frustum.
18166		 * @param {number} [bottom=-1] - The bottom plane of the camera's frustum.
18167		 * @param {number} [near=0.1] - The camera's near plane.
18168		 * @param {number} [far=2000] - The camera's far plane.
18169		 */ constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000){
18170	        super();
18171	        /**
18172			 * This flag can be used for type testing.
18173			 *
18174			 * @type {boolean}
18175			 * @readonly
18176			 * @default true
18177			 */ this.isOrthographicCamera = true;
vendor: 33,662 bytes, lines 18178-19038
18178	        this.type = 'OrthographicCamera';
18179	        /**
18180			 * The zoom factor of the camera.
18181			 *
18182			 * @type {number}
18183			 * @default 1
18184			 */ this.zoom = 1;
18185	        /**
18186			 * Represents the frustum window specification. This property should not be edited
18187			 * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}.
18188			 *
18189			 * @type {?Object}
18190			 * @default null
18191			 */ this.view = null;
18192	        /**
18193			 * The left plane of the camera's frustum.
18194			 *
18195			 * @type {number}
18196			 * @default -1
18197			 */ this.left = left;
18198	        /**
18199			 * The right plane of the camera's frustum.
18200			 *
18201			 * @type {number}
18202			 * @default 1
18203			 */ this.right = right;
18204	        /**
18205			 * The top plane of the camera's frustum.
18206			 *
18207			 * @type {number}
18208			 * @default 1
18209			 */ this.top = top;
18210	        /**
18211			 * The bottom plane of the camera's frustum.
18212			 *
18213			 * @type {number}
18214			 * @default -1
18215			 */ this.bottom = bottom;
18216	        /**
18217			 * The camera's near plane. The valid range is greater than `0`
18218			 * and less than the current value of {@link OrthographicCamera#far}.
18219			 *
18220			 * Note that, unlike for the {@link PerspectiveCamera}, `0` is a
18221			 * valid value for an orthographic camera's near plane.
18222			 *
18223			 * @type {number}
18224			 * @default 0.1
18225			 */ this.near = near;
18226	        /**
18227			 * The camera's far plane. Must be greater than the
18228			 * current value of {@link OrthographicCamera#near}.
18229			 *
18230			 * @type {number}
18231			 * @default 2000
18232			 */ this.far = far;
18233	        this.updateProjectionMatrix();
18234	    }
18235	}
18236	/**
18237	 * Represents the shadow configuration of directional lights.
18238	 *
18239	 * @augments LightShadow
18240	 */ class DirectionalLightShadow extends LightShadow {
18241	    /**
18242		 * Constructs a new directional light shadow.
18243		 */ constructor(){
18244	        super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500));
18245	        /**
18246			 * This flag can be used for type testing.
18247			 *
18248			 * @type {boolean}
18249			 * @readonly
18250			 * @default true
18251			 */ this.isDirectionalLightShadow = true;
18252	    }
18253	}
18254	/**
18255	 * A light that gets emitted in a specific direction. This light will behave
18256	 * as though it is infinitely far away and the rays produced from it are all
18257	 * parallel. The common use case for this is to simulate daylight; the sun is
18258	 * far enough away that its position can be considered to be infinite, and
18259	 * all light rays coming from it are parallel.
18260	 *
18261	 * A common point of confusion for directional lights is that setting the
18262	 * rotation has no effect. This is because three.js's DirectionalLight is the
18263	 * equivalent to what is often called a 'Target Direct Light' in other
18264	 * applications.
18265	 *
18266	 * This means that its direction is calculated as pointing from the light's
18267	 * {@link Object3D#position} to the {@link DirectionalLight#target} position
18268	 * (as opposed to a 'Free Direct Light' that just has a rotation
18269	 * component).
18270	 *
18271	 * This light can cast shadows - see the {@link DirectionalLightShadow} for details.
18272	 *
18273	 * ```js
18274	 * // White directional light at half intensity shining from the top.
18275	 * const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
18276	 * scene.add( directionalLight );
18277	 * ```
18278	 *
18279	 * @augments Light
18280	 */ class DirectionalLight extends Light {
18281	    dispose() {
18282	        this.shadow.dispose();
18283	    }
18284	    copy(source) {
18285	        super.copy(source);
18286	        this.target = source.target.clone();
18287	        this.shadow = source.shadow.clone();
18288	        return this;
18289	    }
18290	    /**
18291		 * Constructs a new directional light.
18292		 *
18293		 * @param {(number|Color|string)} [color=0xffffff] - The light's color.
18294		 * @param {number} [intensity=1] - The light's strength/intensity.
18295		 */ constructor(color, intensity){
18296	        super(color, intensity);
18297	        /**
18298			 * This flag can be used for type testing.
18299			 *
18300			 * @type {boolean}
18301			 * @readonly
18302			 * @default true
18303			 */ this.isDirectionalLight = true;
18304	        this.type = 'DirectionalLight';
18305	        this.position.copy(Object3D.DEFAULT_UP);
18306	        this.updateMatrix();
18307	        /**
18308			 * The directional light points from its position to the
18309			 * target's position.
18310			 *
18311			 * For the target's position to be changed to anything other
18312			 * than the default, it must be added to the scene.
18313			 *
18314			 * It is also possible to set the target to be another 3D object
18315			 * in the scene. The light will now track the target object.
18316			 *
18317			 * @type {Object3D}
18318			 */ this.target = new Object3D();
18319	        /**
18320			 * This property holds the light's shadow configuration.
18321			 *
18322			 * @type {DirectionalLightShadow}
18323			 */ this.shadow = new DirectionalLightShadow();
18324	    }
18325	}
18326	/**
18327	 * Represents a third-order spherical harmonics (SH). Light probes use this class
18328	 * to encode lighting information.
18329	 *
18330	 * - Primary reference: {@link https://graphics.stanford.edu/papers/envmap/envmap.pdf}
18331	 * - Secondary reference: {@link https://www.ppsloan.org/publications/StupidSH36.pdf}
18332	 */ class SphericalHarmonics3 {
18333	    /**
18334		 * Sets the given SH coefficients to this instance by copying
18335		 * the values.
18336		 *
18337		 * @param {Array<Vector3>} coefficients - The SH coefficients.
18338		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18339		 */ set(coefficients) {
18340	        for(let i = 0; i < 9; i++){
18341	            this.coefficients[i].copy(coefficients[i]);
18342	        }
18343	        return this;
18344	    }
18345	    /**
18346		 * Sets all SH coefficients to `0`.
18347		 *
18348		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18349		 */ zero() {
18350	        for(let i = 0; i < 9; i++){
18351	            this.coefficients[i].set(0, 0, 0);
18352	        }
18353	        return this;
18354	    }
18355	    /**
18356		 * Returns the radiance in the direction of the given normal.
18357		 *
18358		 * @param {Vector3} normal - The normal vector (assumed to be unit length)
18359		 * @param {Vector3} target - The target vector that is used to store the method's result.
18360		 * @return {Vector3} The radiance.
18361		 */ getAt(normal, target) {
18362	        // normal is assumed to be unit length
18363	        const x = normal.x, y = normal.y, z = normal.z;
18364	        const coeff = this.coefficients;
18365	        // band 0
18366	        target.copy(coeff[0]).multiplyScalar(0.282095);
18367	        // band 1
18368	        target.addScaledVector(coeff[1], 0.488603 * y);
18369	        target.addScaledVector(coeff[2], 0.488603 * z);
18370	        target.addScaledVector(coeff[3], 0.488603 * x);
18371	        // band 2
18372	        target.addScaledVector(coeff[4], 1.092548 * (x * y));
18373	        target.addScaledVector(coeff[5], 1.092548 * (y * z));
18374	        target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0));
18375	        target.addScaledVector(coeff[7], 1.092548 * (x * z));
18376	        target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y));
18377	        return target;
18378	    }
18379	    /**
18380		 * Returns the irradiance (radiance convolved with cosine lobe) in the
18381		 * direction of the given normal.
18382		 *
18383		 * @param {Vector3} normal - The normal vector (assumed to be unit length)
18384		 * @param {Vector3} target - The target vector that is used to store the method's result.
18385		 * @return {Vector3} The irradiance.
18386		 */ getIrradianceAt(normal, target) {
18387	        // normal is assumed to be unit length
18388	        const x = normal.x, y = normal.y, z = normal.z;
18389	        const coeff = this.coefficients;
18390	        // band 0
18391	        target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095
18392	        // band 1
18393	        target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603
18394	        target.addScaledVector(coeff[2], 2.0 * 0.511664 * z);
18395	        target.addScaledVector(coeff[3], 2.0 * 0.511664 * x);
18396	        // band 2
18397	        target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548
18398	        target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z);
18399	        target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( π / 4 ) * 0.315392 * 3
18400	        target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z);
18401	        target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( π / 4 ) * 0.546274
18402	        return target;
18403	    }
18404	    /**
18405		 * Adds the given SH to this instance.
18406		 *
18407		 * @param {SphericalHarmonics3} sh - The SH to add.
18408		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18409		 */ add(sh) {
18410	        for(let i = 0; i < 9; i++){
18411	            this.coefficients[i].add(sh.coefficients[i]);
18412	        }
18413	        return this;
18414	    }
18415	    /**
18416		 * A convenience method for performing {@link SphericalHarmonics3#add} and
18417		 * {@link SphericalHarmonics3#scale} at once.
18418		 *
18419		 * @param {SphericalHarmonics3} sh - The SH to add.
18420		 * @param {number} s - The scale factor.
18421		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18422		 */ addScaledSH(sh, s) {
18423	        for(let i = 0; i < 9; i++){
18424	            this.coefficients[i].addScaledVector(sh.coefficients[i], s);
18425	        }
18426	        return this;
18427	    }
18428	    /**
18429		 * Scales this SH by the given scale factor.
18430		 *
18431		 * @param {number} s - The scale factor.
18432		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18433		 */ scale(s) {
18434	        for(let i = 0; i < 9; i++){
18435	            this.coefficients[i].multiplyScalar(s);
18436	        }
18437	        return this;
18438	    }
18439	    /**
18440		 * Linear interpolates between the given SH and this instance by the given
18441		 * alpha factor.
18442		 *
18443		 * @param {SphericalHarmonics3} sh - The SH to interpolate with.
18444		 * @param {number} alpha - The alpha factor.
18445		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18446		 */ lerp(sh, alpha) {
18447	        for(let i = 0; i < 9; i++){
18448	            this.coefficients[i].lerp(sh.coefficients[i], alpha);
18449	        }
18450	        return this;
18451	    }
18452	    /**
18453		 * Returns `true` if this spherical harmonics is equal with the given one.
18454		 *
18455		 * @param {SphericalHarmonics3} sh - The spherical harmonics to test for equality.
18456		 * @return {boolean} Whether this spherical harmonics is equal with the given one.
18457		 */ equals(sh) {
18458	        for(let i = 0; i < 9; i++){
18459	            if (!this.coefficients[i].equals(sh.coefficients[i])) {
18460	                return false;
18461	            }
18462	        }
18463	        return true;
18464	    }
18465	    /**
18466		 * Copies the values of the given spherical harmonics to this instance.
18467		 *
18468		 * @param {SphericalHarmonics3} sh - The spherical harmonics to copy.
18469		 * @return {SphericalHarmonics3} A reference to this spherical harmonics.
18470		 */ copy(sh) {
18471	        return this.set(sh.coefficients);
18472	    }
18473	    /**
18474		 * Returns a new spherical harmonics with copied values from this instance.
18475		 *
18476		 * @return {SphericalHarmonics3} A clone of this instance.
18477		 */ clone() {
18478	        return new this.constructor().copy(this);
18479	    }
18480	    /**
18481		 * Sets the SH coefficients of this instance from the given array.
18482		 *
18483		 * @param {Array<number>} array - An array holding the SH coefficients.
18484		 * @param {number} [offset=0] - The array offset where to start copying.
18485		 * @return {SphericalHarmonics3} A clone of this instance.
18486		 */ fromArray(array, offset = 0) {
18487	        const coefficients = this.coefficients;
18488	        for(let i = 0; i < 9; i++){
18489	            coefficients[i].fromArray(array, offset + i * 3);
18490	        }
18491	        return this;
18492	    }
18493	    /**
18494		 * Returns an array with the SH coefficients, or copies them into the provided
18495		 * array. The coefficients are represented as numbers.
18496		 *
18497		 * @param {Array<number>} [array=[]] - The target array.
18498		 * @param {number} [offset=0] - The array offset where to start copying.
18499		 * @return {Array<number>} An array with flat SH coefficients.
18500		 */ toArray(array = [], offset = 0) {
18501	        const coefficients = this.coefficients;
18502	        for(let i = 0; i < 9; i++){
18503	            coefficients[i].toArray(array, offset + i * 3);
18504	        }
18505	        return array;
18506	    }
18507	    /**
18508		 * Computes the SH basis for the given normal vector.
18509		 *
18510		 * @param {Vector3} normal - The normal.
18511		 * @param {Array<number>} shBasis - The target array holding the SH basis.
18512		 */ static getBasisAt(normal, shBasis) {
18513	        // normal is assumed to be unit length
18514	        const x = normal.x, y = normal.y, z = normal.z;
18515	        // band 0
18516	        shBasis[0] = 0.282095;
18517	        // band 1
18518	        shBasis[1] = 0.488603 * y;
18519	        shBasis[2] = 0.488603 * z;
18520	        shBasis[3] = 0.488603 * x;
18521	        // band 2
18522	        shBasis[4] = 1.092548 * x * y;
18523	        shBasis[5] = 1.092548 * y * z;
18524	        shBasis[6] = 0.315392 * (3 * z * z - 1);
18525	        shBasis[7] = 1.092548 * x * z;
18526	        shBasis[8] = 0.546274 * (x * x - y * y);
18527	    }
18528	    /**
18529		 * Constructs a new spherical harmonics.
18530		 */ constructor(){
18531	        /**
18532			 * This flag can be used for type testing.
18533			 *
18534			 * @type {boolean}
18535			 * @readonly
18536			 * @default true
18537			 */ this.isSphericalHarmonics3 = true;
18538	        /**
18539			 * An array holding the (9) SH coefficients.
18540			 *
18541			 * @type {Array<Vector3>}
18542			 */ this.coefficients = [];
18543	        for(let i = 0; i < 9; i++){
18544	            this.coefficients.push(new Vector3());
18545	        }
18546	    }
18547	}
18548	/**
18549	 * Light probes are an alternative way of adding light to a 3D scene. Unlike
18550	 * classical light sources (e.g. directional, point or spot lights), light
18551	 * probes do not emit light. Instead they store information about light
18552	 * passing through 3D space. During rendering, the light that hits a 3D
18553	 * object is approximated by using the data from the light probe.
18554	 *
18555	 * Light probes are usually created from (radiance) environment maps. The
18556	 * class {@link LightProbeGenerator} can be used to create light probes from
18557	 * cube textures or render targets. However, light estimation data could also
18558	 * be provided in other forms e.g. by WebXR. This enables the rendering of
18559	 * augmented reality content that reacts to real world lighting.
18560	 *
18561	 * The current probe implementation in three.js supports so-called diffuse
18562	 * light probes. This type of light probe is functionally equivalent to an
18563	 * irradiance environment map.
18564	 *
18565	 * @augments Light
18566	 */ class LightProbe extends Light {
18567	    copy(source) {
18568	        super.copy(source);
18569	        this.sh.copy(source.sh);
18570	        return this;
18571	    }
18572	    /**
18573		 * Deserializes the light prove from the given JSON.
18574		 *
18575		 * @param {Object} json - The JSON holding the serialized light probe.
18576		 * @return {LightProbe} A reference to this light probe.
18577		 */ fromJSON(json) {
18578	        this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();
18579	        this.sh.fromArray(json.sh);
18580	        return this;
18581	    }
18582	    toJSON(meta) {
18583	        const data = super.toJSON(meta);
18584	        data.object.sh = this.sh.toArray();
18585	        return data;
18586	    }
18587	    /**
18588		 * Constructs a new light probe.
18589		 *
18590		 * @param {SphericalHarmonics3} sh - The spherical harmonics which represents encoded lighting information.
18591		 * @param {number} [intensity=1] - The light's strength/intensity.
18592		 */ constructor(sh = new SphericalHarmonics3(), intensity = 1){
18593	        super(undefined, intensity);
18594	        /**
18595			 * This flag can be used for type testing.
18596			 *
18597			 * @type {boolean}
18598			 * @readonly
18599			 * @default true
18600			 */ this.isLightProbe = true;
18601	        /**
18602			 * A light probe uses spherical harmonics to encode lighting information.
18603			 *
18604			 * @type {SphericalHarmonics3}
18605			 */ this.sh = sh;
18606	    }
18607	}
18608	class LoaderUtils {
18609	    static decodeText(array) {
18610	        console.warn('THREE.LoaderUtils: decodeText() has been deprecated with r165 and will be removed with r175. Use TextDecoder instead.');
18611	        if (typeof TextDecoder !== 'undefined') {
18612	            return new TextDecoder().decode(array);
18613	        }
18614	        // Avoid the String.fromCharCode.apply(null, array) shortcut, which
18615	        // throws a "maximum call stack size exceeded" error for large arrays.
18616	        let s = '';
18617	        for(let i = 0, il = array.length; i < il; i++){
18618	            // Implicitly assumes little-endian.
18619	            s += String.fromCharCode(array[i]);
18620	        }
18621	        try {
18622	            // merges multi-byte utf-8 characters.
18623	            return decodeURIComponent(escape(s));
18624	        } catch (e) {
18625	            return s;
18626	        }
18627	    }
18628	    static extractUrlBase(url) {
18629	        const index = url.lastIndexOf('/');
18630	        if (index === -1) return './';
18631	        return url.slice(0, index + 1);
18632	    }
18633	    static resolveURL(url, path) {
18634	        // Invalid URL
18635	        if (typeof url !== 'string' || url === '') return '';
18636	        // Host Relative URL
18637	        if (/^https?:\/\//i.test(path) && /^\//.test(url)) {
18638	            path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1');
18639	        }
18640	        // Absolute URL http://,https://,//
18641	        if (/^(https?:)?\/\//i.test(url)) return url;
18642	        // Data URI
18643	        if (/^data:.*,.*$/i.test(url)) return url;
18644	        // Blob URL
18645	        if (/^blob:.*$/i.test(url)) return url;
18646	        // Relative URL
18647	        return path + url;
18648	    }
18649	}
18650	class ImageBitmapLoader extends Loader {
18651	    setOptions(options) {
18652	        this.options = options;
18653	        return this;
18654	    }
18655	    load(url, onLoad, onProgress, onError) {
18656	        if (url === undefined) url = '';
18657	        if (this.path !== undefined) url = this.path + url;
18658	        url = this.manager.resolveURL(url);
18659	        const scope = this;
18660	        const cached = Cache.get(url);
18661	        if (cached !== undefined) {
18662	            scope.manager.itemStart(url);
18663	            // If cached is a promise, wait for it to resolve
18664	            if (cached.then) {
18665	                cached.then((imageBitmap)=>{
18666	                    if (onLoad) onLoad(imageBitmap);
18667	                    scope.manager.itemEnd(url);
18668	                }).catch((e)=>{
18669	                    if (onError) onError(e);
18670	                });
18671	                return;
18672	            }
18673	            // If cached is not a promise (i.e., it's already an imageBitmap)
18674	            setTimeout(function() {
18675	                if (onLoad) onLoad(cached);
18676	                scope.manager.itemEnd(url);
18677	            }, 0);
18678	            return cached;
18679	        }
18680	        const fetchOptions = {};
18681	        fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include';
18682	        fetchOptions.headers = this.requestHeader;
18683	        const promise = fetch(url, fetchOptions).then(function(res) {
18684	            return res.blob();
18685	        }).then(function(blob) {
18686	            return createImageBitmap(blob, Object.assign(scope.options, {
18687	                colorSpaceConversion: 'none'
18688	            }));
18689	        }).then(function(imageBitmap) {
18690	            Cache.add(url, imageBitmap);
18691	            if (onLoad) onLoad(imageBitmap);
18692	            scope.manager.itemEnd(url);
18693	            return imageBitmap;
18694	        }).catch(function(e) {
18695	            if (onError) onError(e);
18696	            Cache.remove(url);
18697	            scope.manager.itemError(url);
18698	            scope.manager.itemEnd(url);
18699	        });
18700	        Cache.add(url, promise);
18701	        scope.manager.itemStart(url);
18702	    }
18703	    constructor(manager){
18704	        super(manager);
18705	        this.isImageBitmapLoader = true;
18706	        if (typeof createImageBitmap === 'undefined') {
18707	            console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.');
18708	        }
18709	        if (typeof fetch === 'undefined') {
18710	            console.warn('THREE.ImageBitmapLoader: fetch() not supported.');
18711	        }
18712	        this.options = {
18713	            premultiplyAlpha: 'none'
18714	        };
18715	    }
18716	}
18717	/**
18718	 * This type of camera can be used in order to efficiently render a scene with a
18719	 * predefined set of cameras. This is an important performance aspect for
18720	 * rendering VR scenes.
18721	 *
18722	 * An instance of `ArrayCamera` always has an array of sub cameras. It's mandatory
18723	 * to define for each sub camera the `viewport` property which determines the
18724	 * part of the viewport that is rendered with this camera.
18725	 *
18726	 * @augments PerspectiveCamera
18727	 */ class ArrayCamera extends PerspectiveCamera {
18728	    /**
18729		 * Constructs a new array camera.
18730		 *
18731		 * @param {Array<PerspectiveCamera>} [array=[]] - An array of perspective sub cameras.
18732		 */ constructor(array = []){
18733	        super();
18734	        /**
18735			 * This flag can be used for type testing.
18736			 *
18737			 * @type {boolean}
18738			 * @readonly
18739			 * @default true
18740			 */ this.isArrayCamera = true;
18741	        /**
18742			 * An array of perspective sub cameras.
18743			 *
18744			 * @type {Array<PerspectiveCamera>}
18745			 */ this.cameras = array;
18746	        this.index = 0;
18747	    }
18748	}
18749	class PropertyMixer {
18750	    // accumulate data in the 'incoming' region into 'accu<i>'
18751	    accumulate(accuIndex, weight) {
18752	        // note: happily accumulating nothing when weight = 0, the caller knows
18753	        // the weight and shouldn't have made the call in the first place
18754	        const buffer = this.buffer, stride = this.valueSize, offset = accuIndex * stride + stride;
18755	        let currentWeight = this.cumulativeWeight;
18756	        if (currentWeight === 0) {
18757	            // accuN := incoming * weight
18758	            for(let i = 0; i !== stride; ++i){
18759	                buffer[offset + i] = buffer[i];
18760	            }
18761	            currentWeight = weight;
18762	        } else {
18763	            // accuN := accuN + incoming * weight
18764	            currentWeight += weight;
18765	            const mix = weight / currentWeight;
18766	            this._mixBufferRegion(buffer, offset, 0, mix, stride);
18767	        }
18768	        this.cumulativeWeight = currentWeight;
18769	    }
18770	    // accumulate data in the 'incoming' region into 'add'
18771	    accumulateAdditive(weight) {
18772	        const buffer = this.buffer, stride = this.valueSize, offset = stride * this._addIndex;
18773	        if (this.cumulativeWeightAdditive === 0) {
18774	            // add = identity
18775	            this._setIdentity();
18776	        }
18777	        // add := add + incoming * weight
18778	        this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride);
18779	        this.cumulativeWeightAdditive += weight;
18780	    }
18781	    // apply the state of 'accu<i>' to the binding when accus differ
18782	    apply(accuIndex) {
18783	        const stride = this.valueSize, buffer = this.buffer, offset = accuIndex * stride + stride, weight = this.cumulativeWeight, weightAdditive = this.cumulativeWeightAdditive, binding = this.binding;
18784	        this.cumulativeWeight = 0;
18785	        this.cumulativeWeightAdditive = 0;
18786	        if (weight < 1) {
18787	            // accuN := accuN + original * ( 1 - cumulativeWeight )
18788	            const originalValueOffset = stride * this._origIndex;
18789	            this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride);
18790	        }
18791	        if (weightAdditive > 0) {
18792	            // accuN := accuN + additive accuN
18793	            this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride);
18794	        }
18795	        for(let i = stride, e = stride + stride; i !== e; ++i){
18796	            if (buffer[i] !== buffer[i + stride]) {
18797	                // value has changed -> update scene graph
18798	                binding.setValue(buffer, offset);
18799	                break;
18800	            }
18801	        }
18802	    }
18803	    // remember the state of the bound property and copy it to both accus
18804	    saveOriginalState() {
18805	        const binding = this.binding;
18806	        const buffer = this.buffer, stride = this.valueSize, originalValueOffset = stride * this._origIndex;
18807	        binding.getValue(buffer, originalValueOffset);
18808	        // accu[0..1] := orig -- initially detect changes against the original
18809	        for(let i = stride, e = originalValueOffset; i !== e; ++i){
18810	            buffer[i] = buffer[originalValueOffset + i % stride];
18811	        }
18812	        // Add to identity for additive
18813	        this._setIdentity();
18814	        this.cumulativeWeight = 0;
18815	        this.cumulativeWeightAdditive = 0;
18816	    }
18817	    // apply the state previously taken via 'saveOriginalState' to the binding
18818	    restoreOriginalState() {
18819	        const originalValueOffset = this.valueSize * 3;
18820	        this.binding.setValue(this.buffer, originalValueOffset);
18821	    }
18822	    _setAdditiveIdentityNumeric() {
18823	        const startIndex = this._addIndex * this.valueSize;
18824	        const endIndex = startIndex + this.valueSize;
18825	        for(let i = startIndex; i < endIndex; i++){
18826	            this.buffer[i] = 0;
18827	        }
18828	    }
18829	    _setAdditiveIdentityQuaternion() {
18830	        this._setAdditiveIdentityNumeric();
18831	        this.buffer[this._addIndex * this.valueSize + 3] = 1;
18832	    }
18833	    _setAdditiveIdentityOther() {
18834	        const startIndex = this._origIndex * this.valueSize;
18835	        const targetIndex = this._addIndex * this.valueSize;
18836	        for(let i = 0; i < this.valueSize; i++){
18837	            this.buffer[targetIndex + i] = this.buffer[startIndex + i];
18838	        }
18839	    }
18840	    // mix functions
18841	    _select(buffer, dstOffset, srcOffset, t, stride) {
18842	        if (t >= 0.5) {
18843	            for(let i = 0; i !== stride; ++i){
18844	                buffer[dstOffset + i] = buffer[srcOffset + i];
18845	            }
18846	        }
18847	    }
18848	    _slerp(buffer, dstOffset, srcOffset, t) {
18849	        Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t);
18850	    }
18851	    _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
18852	        const workOffset = this._workIndex * stride;
18853	        // Store result in intermediate buffer offset
18854	        Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset);
18855	        // Slerp to the intermediate result
18856	        Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t);
18857	    }
18858	    _lerp(buffer, dstOffset, srcOffset, t, stride) {
18859	        const s = 1 - t;
18860	        for(let i = 0; i !== stride; ++i){
18861	            const j = dstOffset + i;
18862	            buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t;
18863	        }
18864	    }
18865	    _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
18866	        for(let i = 0; i !== stride; ++i){
18867	            const j = dstOffset + i;
18868	            buffer[j] = buffer[j] + buffer[srcOffset + i] * t;
18869	        }
18870	    }
18871	    constructor(binding, typeName, valueSize){
18872	        this.binding = binding;
18873	        this.valueSize = valueSize;
18874	        let mixFunction, mixFunctionAdditive, setIdentity;
18875	        // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
18876	        //
18877	        // interpolators can use .buffer as their .result
18878	        // the data then goes to 'incoming'
18879	        //
18880	        // 'accu0' and 'accu1' are used frame-interleaved for
18881	        // the cumulative result and are compared to detect
18882	        // changes
18883	        //
18884	        // 'orig' stores the original state of the property
18885	        //
18886	        // 'add' is used for additive cumulative results
18887	        //
18888	        // 'work' is optional and is only present for quaternion types. It is used
18889	        // to store intermediate quaternion multiplication results
18890	        switch(typeName){
18891	            case 'quaternion':
18892	                mixFunction = this._slerp;
18893	                mixFunctionAdditive = this._slerpAdditive;
18894	                setIdentity = this._setAdditiveIdentityQuaternion;
18895	                this.buffer = new Float64Array(valueSize * 6);
18896	                this._workIndex = 5;
18897	                break;
18898	            case 'string':
18899	            case 'bool':
18900	                mixFunction = this._select;
18901	                // Use the regular mix function and for additive on these types,
18902	                // additive is not relevant for non-numeric types
18903	                mixFunctionAdditive = this._select;
18904	                setIdentity = this._setAdditiveIdentityOther;
18905	                this.buffer = new Array(valueSize * 5);
18906	                break;
18907	            default:
18908	                mixFunction = this._lerp;
18909	                mixFunctionAdditive = this._lerpAdditive;
18910	                setIdentity = this._setAdditiveIdentityNumeric;
18911	                this.buffer = new Float64Array(valueSize * 5);
18912	        }
18913	        this._mixBufferRegion = mixFunction;
18914	        this._mixBufferRegionAdditive = mixFunctionAdditive;
18915	        this._setIdentity = setIdentity;
18916	        this._origIndex = 3;
18917	        this._addIndex = 4;
18918	        this.cumulativeWeight = 0;
18919	        this.cumulativeWeightAdditive = 0;
18920	        this.useCount = 0;
18921	        this.referenceCount = 0;
18922	    }
18923	}
18924	// Characters [].:/ are reserved for track binding syntax.
18925	const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
18926	const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g');
18927	// Attempts to allow node names from any language. ES5's `\w` regexp matches
18928	// only latin characters, and the unicode \p{L} is not yet supported. So
18929	// instead, we exclude reserved characters and match everything else.
18930	const _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
18931	const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']';
18932	// Parent directories, delimited by '/' or ':'. Currently unused, but must
18933	// be matched to parse the rest of the track name.
18934	const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar);
18935	// Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
18936	const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot);
18937	// Object on target node, and accessor. May not contain reserved
18938	// characters. Accessor may contain any character except closing bracket.
18939	const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar);
18940	// Property and accessor. May not contain reserved characters. Accessor may
18941	// contain any non-bracket characters.
18942	const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar);
18943	const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$');
18944	const _supportedObjectNames = [
18945	    'material',
18946	    'materials',
18947	    'bones',
18948	    'map'
18949	];
18950	class Composite {
18951	    getValue(array, offset) {
18952	        this.bind(); // bind all binding
18953	        const firstValidIndex = this._targetGroup.nCachedObjects_, binding = this._bindings[firstValidIndex];
18954	        // and only call .getValue on the first
18955	        if (binding !== undefined) binding.getValue(array, offset);
18956	    }
18957	    setValue(array, offset) {
18958	        const bindings = this._bindings;
18959	        for(let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i){
18960	            bindings[i].setValue(array, offset);
18961	        }
18962	    }
18963	    bind() {
18964	        const bindings = this._bindings;
18965	        for(let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i){
18966	            bindings[i].bind();
18967	        }
18968	    }
18969	    unbind() {
18970	        const bindings = this._bindings;
18971	        for(let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i){
18972	            bindings[i].unbind();
18973	        }
18974	    }
18975	    constructor(targetGroup, path, optionalParsedPath){
18976	        const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path);
18977	        this._targetGroup = targetGroup;
18978	        this._bindings = targetGroup.subscribe_(path, parsedPath);
18979	    }
18980	}
18981	// Note: This class uses a State pattern on a per-method basis:
18982	// 'bind' sets 'this.getValue' / 'setValue' and shadows the
18983	// prototype version of these methods with one that represents
18984	// the bound state. When the property is not found, the methods
18985	// become no-ops.
18986	class PropertyBinding {
18987	    static create(root, path, parsedPath) {
18988	        if (!(root && root.isAnimationObjectGroup)) {
18989	            return new PropertyBinding(root, path, parsedPath);
18990	        } else {
18991	            return new PropertyBinding.Composite(root, path, parsedPath);
18992	        }
18993	    }
18994	    /**
18995		 * Replaces spaces with underscores and removes unsupported characters from
18996		 * node names, to ensure compatibility with parseTrackName().
18997		 *
18998		 * @param {string} name Node name to be sanitized.
18999		 * @return {string}
19000		 */ static sanitizeNodeName(name) {
19001	        return name.replace(/\s/g, '_').replace(_reservedRe, '');
19002	    }
19003	    static parseTrackName(trackName) {
19004	        const matches = _trackRe.exec(trackName);
19005	        if (matches === null) {
19006	            throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName);
19007	        }
19008	        const results = {
19009	            // directoryName: matches[ 1 ], // (tschw) currently unused
19010	            nodeName: matches[2],
19011	            objectName: matches[3],
19012	            objectIndex: matches[4],
19013	            propertyName: matches[5],
19014	            propertyIndex: matches[6]
19015	        };
19016	        const lastDot = results.nodeName && results.nodeName.lastIndexOf('.');
19017	        if (lastDot !== undefined && lastDot !== -1) {
19018	            const objectName = results.nodeName.substring(lastDot + 1);
19019	            // Object names must be checked against an allowlist. Otherwise, there
19020	            // is no way to parse 'foo.bar.baz': 'baz' must be a property, but
19021	            // 'bar' could be the objectName, or part of a nodeName (which can
19022	            // include '.' characters).
19023	            if (_supportedObjectNames.indexOf(objectName) !== -1) {
19024	                results.nodeName = results.nodeName.substring(0, lastDot);
19025	                results.objectName = objectName;
19026	            }
19027	        }
19028	        if (results.propertyName === null || results.propertyName.length === 0) {
19029	            throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName);
19030	        }
19031	        return results;
19032	    }
19033	    static findNode(root, nodeName) {
19034	        if (nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) {
19035	            return root;
19036	        }
19037	        // search into skeleton bones.
19038	        if (root.skeleton) {
vendor: 5,406 bytes, lines 19039-19173
19039	            const bone = root.skeleton.getBoneByName(nodeName);
19040	            if (bone !== undefined) {
19041	                return bone;
19042	            }
19043	        }
19044	        // search into node subtree.
19045	        if (root.children) {
19046	            const searchNodeSubtree = function(children) {
19047	                for(let i = 0; i < children.length; i++){
19048	                    const childNode = children[i];
19049	                    if (childNode.name === nodeName || childNode.uuid === nodeName) {
19050	                        return childNode;
19051	                    }
19052	                    const result = searchNodeSubtree(childNode.children);
19053	                    if (result) return result;
19054	                }
19055	                return null;
19056	            };
19057	            const subTreeNode = searchNodeSubtree(root.children);
19058	            if (subTreeNode) {
19059	                return subTreeNode;
19060	            }
19061	        }
19062	        return null;
19063	    }
19064	    // these are used to "bind" a nonexistent property
19065	    _getValue_unavailable() {}
19066	    _setValue_unavailable() {}
19067	    // Getters
19068	    _getValue_direct(buffer, offset) {
19069	        buffer[offset] = this.targetObject[this.propertyName];
19070	    }
19071	    _getValue_array(buffer, offset) {
19072	        const source = this.resolvedProperty;
19073	        for(let i = 0, n = source.length; i !== n; ++i){
19074	            buffer[offset++] = source[i];
19075	        }
19076	    }
19077	    _getValue_arrayElement(buffer, offset) {
19078	        buffer[offset] = this.resolvedProperty[this.propertyIndex];
19079	    }
19080	    _getValue_toArray(buffer, offset) {
19081	        this.resolvedProperty.toArray(buffer, offset);
19082	    }
19083	    // Direct
19084	    _setValue_direct(buffer, offset) {
19085	        this.targetObject[this.propertyName] = buffer[offset];
19086	    }
19087	    _setValue_direct_setNeedsUpdate(buffer, offset) {
19088	        this.targetObject[this.propertyName] = buffer[offset];
19089	        this.targetObject.needsUpdate = true;
19090	    }
19091	    _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) {
19092	        this.targetObject[this.propertyName] = buffer[offset];
19093	        this.targetObject.matrixWorldNeedsUpdate = true;
19094	    }
19095	    // EntireArray
19096	    _setValue_array(buffer, offset) {
19097	        const dest = this.resolvedProperty;
19098	        for(let i = 0, n = dest.length; i !== n; ++i){
19099	            dest[i] = buffer[offset++];
19100	        }
19101	    }
19102	    _setValue_array_setNeedsUpdate(buffer, offset) {
19103	        const dest = this.resolvedProperty;
19104	        for(let i = 0, n = dest.length; i !== n; ++i){
19105	            dest[i] = buffer[offset++];
19106	        }
19107	        this.targetObject.needsUpdate = true;
19108	    }
19109	    _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) {
19110	        const dest = this.resolvedProperty;
19111	        for(let i = 0, n = dest.length; i !== n; ++i){
19112	            dest[i] = buffer[offset++];
19113	        }
19114	        this.targetObject.matrixWorldNeedsUpdate = true;
19115	    }
19116	    // ArrayElement
19117	    _setValue_arrayElement(buffer, offset) {
19118	        this.resolvedProperty[this.propertyIndex] = buffer[offset];
19119	    }
19120	    _setValue_arrayElement_setNeedsUpdate(buffer, offset) {
19121	        this.resolvedProperty[this.propertyIndex] = buffer[offset];
19122	        this.targetObject.needsUpdate = true;
19123	    }
19124	    _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) {
19125	        this.resolvedProperty[this.propertyIndex] = buffer[offset];
19126	        this.targetObject.matrixWorldNeedsUpdate = true;
19127	    }
19128	    // HasToFromArray
19129	    _setValue_fromArray(buffer, offset) {
19130	        this.resolvedProperty.fromArray(buffer, offset);
19131	    }
19132	    _setValue_fromArray_setNeedsUpdate(buffer, offset) {
19133	        this.resolvedProperty.fromArray(buffer, offset);
19134	        this.targetObject.needsUpdate = true;
19135	    }
19136	    _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) {
19137	        this.resolvedProperty.fromArray(buffer, offset);
19138	        this.targetObject.matrixWorldNeedsUpdate = true;
19139	    }
19140	    _getValue_unbound(targetArray, offset) {
19141	        this.bind();
19142	        this.getValue(targetArray, offset);
19143	    }
19144	    _setValue_unbound(sourceArray, offset) {
19145	        this.bind();
19146	        this.setValue(sourceArray, offset);
19147	    }
19148	    // create getter / setter pair for a property in the scene graph
19149	    bind() {
19150	        let targetObject = this.node;
19151	        const parsedPath = this.parsedPath;
19152	        const objectName = parsedPath.objectName;
19153	        const propertyName = parsedPath.propertyName;
19154	        let propertyIndex = parsedPath.propertyIndex;
19155	        if (!targetObject) {
19156	            targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName);
19157	            this.node = targetObject;
19158	        }
19159	        // set fail state so we can just 'return' on error
19160	        this.getValue = this._getValue_unavailable;
19161	        this.setValue = this._setValue_unavailable;
19162	        // ensure there is a value node
19163	        if (!targetObject) {
19164	            console.warn('THREE.PropertyBinding: No target node found for track: ' + this.path + '.');
19165	            return;
19166	        }
19167	        if (objectName) {
19168	            let objectIndex = parsedPath.objectIndex;
19169	            // special cases were we need to reach deeper into the hierarchy to get the face materials....
19170	            switch(objectName){
19171	                case 'materials':
19172	                    if (!targetObject.material) {
19173	                        console.error('THREE.PropertyBinding: Can not bind to material as no
vendor: 23,355 bytes, lines 19173-19726
19173de does not have a material.', this);
19174	                        return;
19175	                    }
19176	                    if (!targetObject.material.materials) {
19177	                        console.error('THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this);
19178	                        return;
19179	                    }
19180	                    targetObject = targetObject.material.materials;
19181	                    break;
19182	                case 'bones':
19183	                    if (!targetObject.skeleton) {
19184	                        console.error('THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this);
19185	                        return;
19186	                    }
19187	                    // potential future optimization: skip this if propertyIndex is already an integer
19188	                    // and convert the integer string to a true integer.
19189	                    targetObject = targetObject.skeleton.bones;
19190	                    // support resolving morphTarget names into indices.
19191	                    for(let i = 0; i < targetObject.length; i++){
19192	                        if (targetObject[i].name === objectIndex) {
19193	                            objectIndex = i;
19194	                            break;
19195	                        }
19196	                    }
19197	                    break;
19198	                case 'map':
19199	                    if ('map' in targetObject) {
19200	                        targetObject = targetObject.map;
19201	                        break;
19202	                    }
19203	                    if (!targetObject.material) {
19204	                        console.error('THREE.PropertyBinding: Can not bind to material as node does not have a material.', this);
19205	                        return;
19206	                    }
19207	                    if (!targetObject.material.map) {
19208	                        console.error('THREE.PropertyBinding: Can not bind to material.map as node.material does not have a map.', this);
19209	                        return;
19210	                    }
19211	                    targetObject = targetObject.material.map;
19212	                    break;
19213	                default:
19214	                    if (targetObject[objectName] === undefined) {
19215	                        console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this);
19216	                        return;
19217	                    }
19218	                    targetObject = targetObject[objectName];
19219	            }
19220	            if (objectIndex !== undefined) {
19221	                if (targetObject[objectIndex] === undefined) {
19222	                    console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject);
19223	                    return;
19224	                }
19225	                targetObject = targetObject[objectIndex];
19226	            }
19227	        }
19228	        // resolve property
19229	        const nodeProperty = targetObject[propertyName];
19230	        if (nodeProperty === undefined) {
19231	            const nodeName = parsedPath.nodeName;
19232	            console.error('THREE.PropertyBinding: Trying to update property for track: ' + nodeName + '.' + propertyName + ' but it wasn\'t found.', targetObject);
19233	            return;
19234	        }
19235	        // determine versioning scheme
19236	        let versioning = this.Versioning.None;
19237	        this.targetObject = targetObject;
19238	        if (targetObject.isMaterial === true) {
19239	            versioning = this.Versioning.NeedsUpdate;
19240	        } else if (targetObject.isObject3D === true) {
19241	            versioning = this.Versioning.MatrixWorldNeedsUpdate;
19242	        }
19243	        // determine how the property gets bound
19244	        let bindingType = this.BindingType.Direct;
19245	        if (propertyIndex !== undefined) {
19246	            // access a sub element of the property array (only primitives are supported right now)
19247	            if (propertyName === 'morphTargetInfluences') {
19248	                // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
19249	                // support resolving morphTarget names into indices.
19250	                if (!targetObject.geometry) {
19251	                    console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this);
19252	                    return;
19253	                }
19254	                if (!targetObject.geometry.morphAttributes) {
19255	                    console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this);
19256	                    return;
19257	                }
19258	                if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) {
19259	                    propertyIndex = targetObject.morphTargetDictionary[propertyIndex];
19260	                }
19261	            }
19262	            bindingType = this.BindingType.ArrayElement;
19263	            this.resolvedProperty = nodeProperty;
19264	            this.propertyIndex = propertyIndex;
19265	        } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) {
19266	            // must use copy for Object3D.Euler/Quaternion
19267	            bindingType = this.BindingType.HasFromToArray;
19268	            this.resolvedProperty = nodeProperty;
19269	        } else if (Array.isArray(nodeProperty)) {
19270	            bindingType = this.BindingType.EntireArray;
19271	            this.resolvedProperty = nodeProperty;
19272	        } else {
19273	            this.propertyName = propertyName;
19274	        }
19275	        // select getter / setter
19276	        this.getValue = this.GetterByBindingType[bindingType];
19277	        this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning];
19278	    }
19279	    unbind() {
19280	        this.node = null;
19281	        // back to the prototype version of getValue / setValue
19282	        // note: avoiding to mutate the shape of 'this' via 'delete'
19283	        this.getValue = this._getValue_unbound;
19284	        this.setValue = this._setValue_unbound;
19285	    }
19286	    constructor(rootNode, path, parsedPath){
19287	        this.path = path;
19288	        this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path);
19289	        this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName);
19290	        this.rootNode = rootNode;
19291	        // initial state of these methods that calls 'bind'
19292	        this.getValue = this._getValue_unbound;
19293	        this.setValue = this._setValue_unbound;
19294	    }
19295	}
19296	PropertyBinding.Composite = Composite;
19297	PropertyBinding.prototype.BindingType = {
19298	    Direct: 0,
19299	    EntireArray: 1,
19300	    ArrayElement: 2,
19301	    HasFromToArray: 3
19302	};
19303	PropertyBinding.prototype.Versioning = {
19304	    None: 0,
19305	    NeedsUpdate: 1,
19306	    MatrixWorldNeedsUpdate: 2
19307	};
19308	PropertyBinding.prototype.GetterByBindingType = [
19309	    PropertyBinding.prototype._getValue_direct,
19310	    PropertyBinding.prototype._getValue_array,
19311	    PropertyBinding.prototype._getValue_arrayElement,
19312	    PropertyBinding.prototype._getValue_toArray
19313	];
19314	PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [
19315	    [
19316	        // Direct
19317	        PropertyBinding.prototype._setValue_direct,
19318	        PropertyBinding.prototype._setValue_direct_setNeedsUpdate,
19319	        PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate
19320	    ],
19321	    [
19322	        // EntireArray
19323	        PropertyBinding.prototype._setValue_array,
19324	        PropertyBinding.prototype._setValue_array_setNeedsUpdate,
19325	        PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate
19326	    ],
19327	    [
19328	        // ArrayElement
19329	        PropertyBinding.prototype._setValue_arrayElement,
19330	        PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate,
19331	        PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate
19332	    ],
19333	    [
19334	        // HasToFromArray
19335	        PropertyBinding.prototype._setValue_fromArray,
19336	        PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate,
19337	        PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate
19338	    ]
19339	];
19340	class AnimationAction {
19341	    // State & Scheduling
19342	    play() {
19343	        this._mixer._activateAction(this);
19344	        return this;
19345	    }
19346	    stop() {
19347	        this._mixer._deactivateAction(this);
19348	        return this.reset();
19349	    }
19350	    reset() {
19351	        this.paused = false;
19352	        this.enabled = true;
19353	        this.time = 0; // restart clip
19354	        this._loopCount = -1; // forget previous loops
19355	        this._startTime = null; // forget scheduling
19356	        return this.stopFading().stopWarping();
19357	    }
19358	    isRunning() {
19359	        return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this);
19360	    }
19361	    // return true when play has been called
19362	    isScheduled() {
19363	        return this._mixer._isActiveAction(this);
19364	    }
19365	    startAt(time) {
19366	        this._startTime = time;
19367	        return this;
19368	    }
19369	    setLoop(mode, repetitions) {
19370	        this.loop = mode;
19371	        this.repetitions = repetitions;
19372	        return this;
19373	    }
19374	    // Weight
19375	    // set the weight stopping any scheduled fading
19376	    // although .enabled = false yields an effective weight of zero, this
19377	    // method does *not* change .enabled, because it would be confusing
19378	    setEffectiveWeight(weight) {
19379	        this.weight = weight;
19380	        // note: same logic as when updated at runtime
19381	        this._effectiveWeight = this.enabled ? weight : 0;
19382	        return this.stopFading();
19383	    }
19384	    // return the weight considering fading and .enabled
19385	    getEffectiveWeight() {
19386	        return this._effectiveWeight;
19387	    }
19388	    fadeIn(duration) {
19389	        return this._scheduleFading(duration, 0, 1);
19390	    }
19391	    fadeOut(duration) {
19392	        return this._scheduleFading(duration, 1, 0);
19393	    }
19394	    crossFadeFrom(fadeOutAction, duration, warp) {
19395	        fadeOutAction.fadeOut(duration);
19396	        this.fadeIn(duration);
19397	        if (warp) {
19398	            const fadeInDuration = this._clip.duration, fadeOutDuration = fadeOutAction._clip.duration, startEndRatio = fadeOutDuration / fadeInDuration, endStartRatio = fadeInDuration / fadeOutDuration;
19399	            fadeOutAction.warp(1.0, startEndRatio, duration);
19400	            this.warp(endStartRatio, 1.0, duration);
19401	        }
19402	        return this;
19403	    }
19404	    crossFadeTo(fadeInAction, duration, warp) {
19405	        return fadeInAction.crossFadeFrom(this, duration, warp);
19406	    }
19407	    stopFading() {
19408	        const weightInterpolant = this._weightInterpolant;
19409	        if (weightInterpolant !== null) {
19410	            this._weightInterpolant = null;
19411	            this._mixer._takeBackControlInterpolant(weightInterpolant);
19412	        }
19413	        return this;
19414	    }
19415	    // Time Scale Control
19416	    // set the time scale stopping any scheduled warping
19417	    // although .paused = true yields an effective time scale of zero, this
19418	    // method does *not* change .paused, because it would be confusing
19419	    setEffectiveTimeScale(timeScale) {
19420	        this.timeScale = timeScale;
19421	        this._effectiveTimeScale = this.paused ? 0 : timeScale;
19422	        return this.stopWarping();
19423	    }
19424	    // return the time scale considering warping and .paused
19425	    getEffectiveTimeScale() {
19426	        return this._effectiveTimeScale;
19427	    }
19428	    setDuration(duration) {
19429	        this.timeScale = this._clip.duration / duration;
19430	        return this.stopWarping();
19431	    }
19432	    syncWith(action) {
19433	        this.time = action.time;
19434	        this.timeScale = action.timeScale;
19435	        return this.stopWarping();
19436	    }
19437	    halt(duration) {
19438	        return this.warp(this._effectiveTimeScale, 0, duration);
19439	    }
19440	    warp(startTimeScale, endTimeScale, duration) {
19441	        const mixer = this._mixer, now = mixer.time, timeScale = this.timeScale;
19442	        let interpolant = this._timeScaleInterpolant;
19443	        if (interpolant === null) {
19444	            interpolant = mixer._lendControlInterpolant();
19445	            this._timeScaleInterpolant = interpolant;
19446	        }
19447	        const times = interpolant.parameterPositions, values = interpolant.sampleValues;
19448	        times[0] = now;
19449	        times[1] = now + duration;
19450	        values[0] = startTimeScale / timeScale;
19451	        values[1] = endTimeScale / timeScale;
19452	        return this;
19453	    }
19454	    stopWarping() {
19455	        const timeScaleInterpolant = this._timeScaleInterpolant;
19456	        if (timeScaleInterpolant !== null) {
19457	            this._timeScaleInterpolant = null;
19458	            this._mixer._takeBackControlInterpolant(timeScaleInterpolant);
19459	        }
19460	        return this;
19461	    }
19462	    // Object Accessors
19463	    getMixer() {
19464	        return this._mixer;
19465	    }
19466	    getClip() {
19467	        return this._clip;
19468	    }
19469	    getRoot() {
19470	        return this._localRoot || this._mixer._root;
19471	    }
19472	    // Interna
19473	    _update(time, deltaTime, timeDirection, accuIndex) {
19474	        // called by the mixer
19475	        if (!this.enabled) {
19476	            // call ._updateWeight() to update ._effectiveWeight
19477	            this._updateWeight(time);
19478	            return;
19479	        }
19480	        const startTime = this._startTime;
19481	        if (startTime !== null) {
19482	            // check for scheduled start of action
19483	            const timeRunning = (time - startTime) * timeDirection;
19484	            if (timeRunning < 0 || timeDirection === 0) {
19485	                deltaTime = 0;
19486	            } else {
19487	                this._startTime = null; // unschedule
19488	                deltaTime = timeDirection * timeRunning;
19489	            }
19490	        }
19491	        // apply time scale and advance time
19492	        deltaTime *= this._updateTimeScale(time);
19493	        const clipTime = this._updateTime(deltaTime);
19494	        // note: _updateTime may disable the action resulting in
19495	        // an effective weight of 0
19496	        const weight = this._updateWeight(time);
19497	        if (weight > 0) {
19498	            const interpolants = this._interpolants;
19499	            const propertyMixers = this._propertyBindings;
19500	            switch(this.blendMode){
19501	                case AdditiveAnimationBlendMode:
19502	                    for(let j = 0, m = interpolants.length; j !== m; ++j){
19503	                        interpolants[j].evaluate(clipTime);
19504	                        propertyMixers[j].accumulateAdditive(weight);
19505	                    }
19506	                    break;
19507	                case NormalAnimationBlendMode:
19508	                default:
19509	                    for(let j = 0, m = interpolants.length; j !== m; ++j){
19510	                        interpolants[j].evaluate(clipTime);
19511	                        propertyMixers[j].accumulate(accuIndex, weight);
19512	                    }
19513	            }
19514	        }
19515	    }
19516	    _updateWeight(time) {
19517	        let weight = 0;
19518	        if (this.enabled) {
19519	            weight = this.weight;
19520	            const interpolant = this._weightInterpolant;
19521	            if (interpolant !== null) {
19522	                const interpolantValue = interpolant.evaluate(time)[0];
19523	                weight *= interpolantValue;
19524	                if (time > interpolant.parameterPositions[1]) {
19525	                    this.stopFading();
19526	                    if (interpolantValue === 0) {
19527	                        // faded out, disable
19528	                        this.enabled = false;
19529	                    }
19530	                }
19531	            }
19532	        }
19533	        this._effectiveWeight = weight;
19534	        return weight;
19535	    }
19536	    _updateTimeScale(time) {
19537	        let timeScale = 0;
19538	        if (!this.paused) {
19539	            timeScale = this.timeScale;
19540	            const interpolant = this._timeScaleInterpolant;
19541	            if (interpolant !== null) {
19542	                const interpolantValue = interpolant.evaluate(time)[0];
19543	                timeScale *= interpolantValue;
19544	                if (time > interpolant.parameterPositions[1]) {
19545	                    this.stopWarping();
19546	                    if (timeScale === 0) {
19547	                        // motion has halted, pause
19548	                        this.paused = true;
19549	                    } else {
19550	                        // warp done - apply final time scale
19551	                        this.timeScale = timeScale;
19552	                    }
19553	                }
19554	            }
19555	        }
19556	        this._effectiveTimeScale = timeScale;
19557	        return timeScale;
19558	    }
19559	    _updateTime(deltaTime) {
19560	        const duration = this._clip.duration;
19561	        const loop = this.loop;
19562	        let time = this.time + deltaTime;
19563	        let loopCount = this._loopCount;
19564	        const pingPong = loop === LoopPingPong;
19565	        if (deltaTime === 0) {
19566	            if (loopCount === -1) return time;
19567	            return pingPong && (loopCount & 1) === 1 ? duration - time : time;
19568	        }
19569	        if (loop === LoopOnce) {
19570	            if (loopCount === -1) {
19571	                // just started
19572	                this._loopCount = 0;
19573	                this._setEndings(true, true, false);
19574	            }
19575	            handle_stop: {
19576	                if (time >= duration) {
19577	                    time = duration;
19578	                } else if (time < 0) {
19579	                    time = 0;
19580	                } else {
19581	                    this.time = time;
19582	                    break handle_stop;
19583	                }
19584	                if (this.clampWhenFinished) this.paused = true;
19585	                else this.enabled = false;
19586	                this.time = time;
19587	                this._mixer.dispatchEvent({
19588	                    type: 'finished',
19589	                    action: this,
19590	                    direction: deltaTime < 0 ? -1 : 1
19591	                });
19592	            }
19593	        } else {
19594	            if (loopCount === -1) {
19595	                // just started
19596	                if (deltaTime >= 0) {
19597	                    loopCount = 0;
19598	                    this._setEndings(true, this.repetitions === 0, pingPong);
19599	                } else {
19600	                    // when looping in reverse direction, the initial
19601	                    // transition through zero counts as a repetition,
19602	                    // so leave loopCount at -1
19603	                    this._setEndings(this.repetitions === 0, true, pingPong);
19604	                }
19605	            }
19606	            if (time >= duration || time < 0) {
19607	                // wrap around
19608	                const loopDelta = Math.floor(time / duration); // signed
19609	                time -= duration * loopDelta;
19610	                loopCount += Math.abs(loopDelta);
19611	                const pending = this.repetitions - loopCount;
19612	                if (pending <= 0) {
19613	                    // have to stop (switch state, clamp time, fire event)
19614	                    if (this.clampWhenFinished) this.paused = true;
19615	                    else this.enabled = false;
19616	                    time = deltaTime > 0 ? duration : 0;
19617	                    this.time = time;
19618	                    this._mixer.dispatchEvent({
19619	                        type: 'finished',
19620	                        action: this,
19621	                        direction: deltaTime > 0 ? 1 : -1
19622	                    });
19623	                } else {
19624	                    // keep running
19625	                    if (pending === 1) {
19626	                        // entering the last round
19627	                        const atStart = deltaTime < 0;
19628	                        this._setEndings(atStart, !atStart, pingPong);
19629	                    } else {
19630	                        this._setEndings(false, false, pingPong);
19631	                    }
19632	                    this._loopCount = loopCount;
19633	                    this.time = time;
19634	                    this._mixer.dispatchEvent({
19635	                        type: 'loop',
19636	                        action: this,
19637	                        loopDelta: loopDelta
19638	                    });
19639	                }
19640	            } else {
19641	                this.time = time;
19642	            }
19643	            if (pingPong && (loopCount & 1) === 1) {
19644	                // invert time for the "pong round"
19645	                return duration - time;
19646	            }
19647	        }
19648	        return time;
19649	    }
19650	    _setEndings(atStart, atEnd, pingPong) {
19651	        const settings = this._interpolantSettings;
19652	        if (pingPong) {
19653	            settings.endingStart = ZeroSlopeEnding;
19654	            settings.endingEnd = ZeroSlopeEnding;
19655	        } else {
19656	            // assuming for LoopOnce atStart == atEnd == true
19657	            if (atStart) {
19658	                settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
19659	            } else {
19660	                settings.endingStart = WrapAroundEnding;
19661	            }
19662	            if (atEnd) {
19663	                settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
19664	            } else {
19665	                settings.endingEnd = WrapAroundEnding;
19666	            }
19667	        }
19668	    }
19669	    _scheduleFading(duration, weightNow, weightThen) {
19670	        const mixer = this._mixer, now = mixer.time;
19671	        let interpolant = this._weightInterpolant;
19672	        if (interpolant === null) {
19673	            interpolant = mixer._lendControlInterpolant();
19674	            this._weightInterpolant = interpolant;
19675	        }
19676	        const times = interpolant.parameterPositions, values = interpolant.sampleValues;
19677	        times[0] = now;
19678	        values[0] = weightNow;
19679	        times[1] = now + duration;
19680	        values[1] = weightThen;
19681	        return this;
19682	    }
19683	    constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode){
19684	        this._mixer = mixer;
19685	        this._clip = clip;
19686	        this._localRoot = localRoot;
19687	        this.blendMode = blendMode;
19688	        const tracks = clip.tracks, nTracks = tracks.length, interpolants = new Array(nTracks);
19689	        const interpolantSettings = {
19690	            endingStart: ZeroCurvatureEnding,
19691	            endingEnd: ZeroCurvatureEnding
19692	        };
19693	        for(let i = 0; i !== nTracks; ++i){
19694	            const interpolant = tracks[i].createInterpolant(null);
19695	            interpolants[i] = interpolant;
19696	            interpolant.settings = interpolantSettings;
19697	        }
19698	        this._interpolantSettings = interpolantSettings;
19699	        this._interpolants = interpolants; // bound by the mixer
19700	        // inside: PropertyMixer (managed by the mixer)
19701	        this._propertyBindings = new Array(nTracks);
19702	        this._cacheIndex = null; // for the memory manager
19703	        this._byClipCacheIndex = null; // for the memory manager
19704	        this._timeScaleInterpolant = null;
19705	        this._weightInterpolant = null;
19706	        this.loop = LoopRepeat;
19707	        this._loopCount = -1;
19708	        // global mixer time when the action is to be started
19709	        // it's set back to 'null' upon start of the action
19710	        this._startTime = null;
19711	        // scaled local time of the action
19712	        // gets clamped or wrapped to 0..clip.duration according to loop
19713	        this.time = 0;
19714	        this.timeScale = 1;
19715	        this._effectiveTimeScale = 1;
19716	        this.weight = 1;
19717	        this._effectiveWeight = 1;
19718	        this.repetitions = Infinity; // no. of repetitions when looping
19719	        this.paused = false; // true -> zero effective time scale
19720	        this.enabled = true; // false -> zero effective weight
19721	        this.clampWhenFinished = false; // keep feeding the last frame?
19722	        this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate
19723	        this.zeroSlopeAtEnd = true; // clips for start, loop and end
19724	    }
19725	}
19726	const _controlInterpolantsResultBuffer = new Float32Array(1);
vendor: 14,413 bytes, lines 19727-20022
19727	class AnimationMixer extends EventDispatcher {
19728	    _bindAction(action, prototypeAction) {
19729	        const root = action._localRoot || this._root, tracks = action._clip.tracks, nTracks = tracks.length, bindings = action._propertyBindings, interpolants = action._interpolants, rootUuid = root.uuid, bindingsByRoot = this._bindingsByRootAndName;
19730	        let bindingsByName = bindingsByRoot[rootUuid];
19731	        if (bindingsByName === undefined) {
19732	            bindingsByName = {};
19733	            bindingsByRoot[rootUuid] = bindingsByName;
19734	        }
19735	        for(let i = 0; i !== nTracks; ++i){
19736	            const track = tracks[i], trackName = track.name;
19737	            let binding = bindingsByName[trackName];
19738	            if (binding !== undefined) {
19739	                ++binding.referenceCount;
19740	                bindings[i] = binding;
19741	            } else {
19742	                binding = bindings[i];
19743	                if (binding !== undefined) {
19744	                    // existing binding, make sure the cache knows
19745	                    if (binding._cacheIndex === null) {
19746	                        ++binding.referenceCount;
19747	                        this._addInactiveBinding(binding, rootUuid, trackName);
19748	                    }
19749	                    continue;
19750	                }
19751	                const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath;
19752	                binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize());
19753	                ++binding.referenceCount;
19754	                this._addInactiveBinding(binding, rootUuid, trackName);
19755	                bindings[i] = binding;
19756	            }
19757	            interpolants[i].resultBuffer = binding.buffer;
19758	        }
19759	    }
19760	    _activateAction(action) {
19761	        if (!this._isActiveAction(action)) {
19762	            if (action._cacheIndex === null) {
19763	                // this action has been forgotten by the cache, but the user
19764	                // appears to be still using it -> rebind
19765	                const rootUuid = (action._localRoot || this._root).uuid, clipUuid = action._clip.uuid, actionsForClip = this._actionsByClip[clipUuid];
19766	                this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]);
19767	                this._addInactiveAction(action, clipUuid, rootUuid);
19768	            }
19769	            const bindings = action._propertyBindings;
19770	            // increment reference counts / sort out state
19771	            for(let i = 0, n = bindings.length; i !== n; ++i){
19772	                const binding = bindings[i];
19773	                if (binding.useCount++ === 0) {
19774	                    this._lendBinding(binding);
19775	                    binding.saveOriginalState();
19776	                }
19777	            }
19778	            this._lendAction(action);
19779	        }
19780	    }
19781	    _deactivateAction(action) {
19782	        if (this._isActiveAction(action)) {
19783	            const bindings = action._propertyBindings;
19784	            // decrement reference counts / sort out state
19785	            for(let i = 0, n = bindings.length; i !== n; ++i){
19786	                const binding = bindings[i];
19787	                if (--binding.useCount === 0) {
19788	                    binding.restoreOriginalState();
19789	                    this._takeBackBinding(binding);
19790	                }
19791	            }
19792	            this._takeBackAction(action);
19793	        }
19794	    }
19795	    // Memory manager
19796	    _initMemoryManager() {
19797	        this._actions = []; // 'nActiveActions' followed by inactive ones
19798	        this._nActiveActions = 0;
19799	        this._actionsByClip = {};
19800	        // inside:
19801	        // {
19802	        // 	knownActions: Array< AnimationAction > - used as prototypes
19803	        // 	actionByRoot: AnimationAction - lookup
19804	        // }
19805	        this._bindings = []; // 'nActiveBindings' followed by inactive ones
19806	        this._nActiveBindings = 0;
19807	        this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
19808	        this._controlInterpolants = []; // same game as above
19809	        this._nActiveControlInterpolants = 0;
19810	        const scope = this;
19811	        this.stats = {
19812	            actions: {
19813	                get total () {
19814	                    return scope._actions.length;
19815	                },
19816	                get inUse () {
19817	                    return scope._nActiveActions;
19818	                }
19819	            },
19820	            bindings: {
19821	                get total () {
19822	                    return scope._bindings.length;
19823	                },
19824	                get inUse () {
19825	                    return scope._nActiveBindings;
19826	                }
19827	            },
19828	            controlInterpolants: {
19829	                get total () {
19830	                    return scope._controlInterpolants.length;
19831	                },
19832	                get inUse () {
19833	                    return scope._nActiveControlInterpolants;
19834	                }
19835	            }
19836	        };
19837	    }
19838	    // Memory management for AnimationAction objects
19839	    _isActiveAction(action) {
19840	        const index = action._cacheIndex;
19841	        return index !== null && index < this._nActiveActions;
19842	    }
19843	    _addInactiveAction(action, clipUuid, rootUuid) {
19844	        const actions = this._actions, actionsByClip = this._actionsByClip;
19845	        let actionsForClip = actionsByClip[clipUuid];
19846	        if (actionsForClip === undefined) {
19847	            actionsForClip = {
19848	                knownActions: [
19849	                    action
19850	                ],
19851	                actionByRoot: {}
19852	            };
19853	            action._byClipCacheIndex = 0;
19854	            actionsByClip[clipUuid] = actionsForClip;
19855	        } else {
19856	            const knownActions = actionsForClip.knownActions;
19857	            action._byClipCacheIndex = knownActions.length;
19858	            knownActions.push(action);
19859	        }
19860	        action._cacheIndex = actions.length;
19861	        actions.push(action);
19862	        actionsForClip.actionByRoot[rootUuid] = action;
19863	    }
19864	    _removeInactiveAction(action) {
19865	        const actions = this._actions, lastInactiveAction = actions[actions.length - 1], cacheIndex = action._cacheIndex;
19866	        lastInactiveAction._cacheIndex = cacheIndex;
19867	        actions[cacheIndex] = lastInactiveAction;
19868	        actions.pop();
19869	        action._cacheIndex = null;
19870	        const clipUuid = action._clip.uuid, actionsByClip = this._actionsByClip, actionsForClip = actionsByClip[clipUuid], knownActionsForClip = actionsForClip.knownActions, lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1], byClipCacheIndex = action._byClipCacheIndex;
19871	        lastKnownAction._byClipCacheIndex = byClipCacheIndex;
19872	        knownActionsForClip[byClipCacheIndex] = lastKnownAction;
19873	        knownActionsForClip.pop();
19874	        action._byClipCacheIndex = null;
19875	        const actionByRoot = actionsForClip.actionByRoot, rootUuid = (action._localRoot || this._root).uuid;
19876	        delete actionByRoot[rootUuid];
19877	        if (knownActionsForClip.length === 0) {
19878	            delete actionsByClip[clipUuid];
19879	        }
19880	        this._removeInactiveBindingsForAction(action);
19881	    }
19882	    _removeInactiveBindingsForAction(action) {
19883	        const bindings = action._propertyBindings;
19884	        for(let i = 0, n = bindings.length; i !== n; ++i){
19885	            const binding = bindings[i];
19886	            if (--binding.referenceCount === 0) {
19887	                this._removeInactiveBinding(binding);
19888	            }
19889	        }
19890	    }
19891	    _lendAction(action) {
19892	        // [ active actions |  inactive actions  ]
19893	        // [  active actions >| inactive actions ]
19894	        //                 s        a
19895	        //                  <-swap->
19896	        //                 a        s
19897	        const actions = this._actions, prevIndex = action._cacheIndex, lastActiveIndex = this._nActiveActions++, firstInactiveAction = actions[lastActiveIndex];
19898	        action._cacheIndex = lastActiveIndex;
19899	        actions[lastActiveIndex] = action;
19900	        firstInactiveAction._cacheIndex = prevIndex;
19901	        actions[prevIndex] = firstInactiveAction;
19902	    }
19903	    _takeBackAction(action) {
19904	        // [  active actions  | inactive actions ]
19905	        // [ active actions |< inactive actions  ]
19906	        //        a        s
19907	        //         <-swap->
19908	        //        s        a
19909	        const actions = this._actions, prevIndex = action._cacheIndex, firstInactiveIndex = --this._nActiveActions, lastActiveAction = actions[firstInactiveIndex];
19910	        action._cacheIndex = firstInactiveIndex;
19911	        actions[firstInactiveIndex] = action;
19912	        lastActiveAction._cacheIndex = prevIndex;
19913	        actions[prevIndex] = lastActiveAction;
19914	    }
19915	    // Memory management for PropertyMixer objects
19916	    _addInactiveBinding(binding, rootUuid, trackName) {
19917	        const bindingsByRoot = this._bindingsByRootAndName, bindings = this._bindings;
19918	        let bindingByName = bindingsByRoot[rootUuid];
19919	        if (bindingByName === undefined) {
19920	            bindingByName = {};
19921	            bindingsByRoot[rootUuid] = bindingByName;
19922	        }
19923	        bindingByName[trackName] = binding;
19924	        binding._cacheIndex = bindings.length;
19925	        bindings.push(binding);
19926	    }
19927	    _removeInactiveBinding(binding) {
19928	        const bindings = this._bindings, propBinding = binding.binding, rootUuid = propBinding.rootNode.uuid, trackName = propBinding.path, bindingsByRoot = this._bindingsByRootAndName, bindingByName = bindingsByRoot[rootUuid], lastInactiveBinding = bindings[bindings.length - 1], cacheIndex = binding._cacheIndex;
19929	        lastInactiveBinding._cacheIndex = cacheIndex;
19930	        bindings[cacheIndex] = lastInactiveBinding;
19931	        bindings.pop();
19932	        delete bindingByName[trackName];
19933	        if (Object.keys(bindingByName).length === 0) {
19934	            delete bindingsByRoot[rootUuid];
19935	        }
19936	    }
19937	    _lendBinding(binding) {
19938	        const bindings = this._bindings, prevIndex = binding._cacheIndex, lastActiveIndex = this._nActiveBindings++, firstInactiveBinding = bindings[lastActiveIndex];
19939	        binding._cacheIndex = lastActiveIndex;
19940	        bindings[lastActiveIndex] = binding;
19941	        firstInactiveBinding._cacheIndex = prevIndex;
19942	        bindings[prevIndex] = firstInactiveBinding;
19943	    }
19944	    _takeBackBinding(binding) {
19945	        const bindings = this._bindings, prevIndex = binding._cacheIndex, firstInactiveIndex = --this._nActiveBindings, lastActiveBinding = bindings[firstInactiveIndex];
19946	        binding._cacheIndex = firstInactiveIndex;
19947	        bindings[firstInactiveIndex] = binding;
19948	        lastActiveBinding._cacheIndex = prevIndex;
19949	        bindings[prevIndex] = lastActiveBinding;
19950	    }
19951	    // Memory management of Interpolants for weight and time scale
19952	    _lendControlInterpolant() {
19953	        const interpolants = this._controlInterpolants, lastActiveIndex = this._nActiveControlInterpolants++;
19954	        let interpolant = interpolants[lastActiveIndex];
19955	        if (interpolant === undefined) {
19956	            interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer);
19957	            interpolant.__cacheIndex = lastActiveIndex;
19958	            interpolants[lastActiveIndex] = interpolant;
19959	        }
19960	        return interpolant;
19961	    }
19962	    _takeBackControlInterpolant(interpolant) {
19963	        const interpolants = this._controlInterpolants, prevIndex = interpolant.__cacheIndex, firstInactiveIndex = --this._nActiveControlInterpolants, lastActiveInterpolant = interpolants[firstInactiveIndex];
19964	        interpolant.__cacheIndex = firstInactiveIndex;
19965	        interpolants[firstInactiveIndex] = interpolant;
19966	        lastActiveInterpolant.__cacheIndex = prevIndex;
19967	        interpolants[prevIndex] = lastActiveInterpolant;
19968	    }
19969	    // return an action for a clip optionally using a custom root target
19970	    // object (this method allocates a lot of dynamic memory in case a
19971	    // previously unknown clip/root combination is specified)
19972	    clipAction(clip, optionalRoot, blendMode) {
19973	        const root = optionalRoot || this._root, rootUuid = root.uuid;
19974	        let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip;
19975	        const clipUuid = clipObject !== null ? clipObject.uuid : clip;
19976	        const actionsForClip = this._actionsByClip[clipUuid];
19977	        let prototypeAction = null;
19978	        if (blendMode === undefined) {
19979	            if (clipObject !== null) {
19980	                blendMode = clipObject.blendMode;
19981	            } else {
19982	                blendMode = NormalAnimationBlendMode;
19983	            }
19984	        }
19985	        if (actionsForClip !== undefined) {
19986	            const existingAction = actionsForClip.actionByRoot[rootUuid];
19987	            if (existingAction !== undefined && existingAction.blendMode === blendMode) {
19988	                return existingAction;
19989	            }
19990	            // we know the clip, so we don't have to parse all
19991	            // the bindings again but can just copy
19992	            prototypeAction = actionsForClip.knownActions[0];
19993	            // also, take the clip from the prototype action
19994	            if (clipObject === null) clipObject = prototypeAction._clip;
19995	        }
19996	        // clip must be known when specified via string
19997	        if (clipObject === null) return null;
19998	        // allocate all resources required to run it
19999	        const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode);
20000	        this._bindAction(newAction, prototypeAction);
20001	        // and make the action known to the memory manager
20002	        this._addInactiveAction(newAction, clipUuid, rootUuid);
20003	        return newAction;
20004	    }
20005	    // get an existing action
20006	    existingAction(clip, optionalRoot) {
20007	        const root = optionalRoot || this._root, rootUuid = root.uuid, clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip, clipUuid = clipObject ? clipObject.uuid : clip, actionsForClip = this._actionsByClip[clipUuid];
20008	        if (actionsForClip !== undefined) {
20009	            return actionsForClip.actionByRoot[rootUuid] || null;
20010	        }
20011	        return null;
20012	    }
20013	    // deactivates all previously scheduled actions
20014	    stopAllAction() {
20015	        const actions = this._actions, nActions = this._nActiveActions;
20016	        for(let i = nActions - 1; i >= 0; --i){
20017	            actions[i].stop();
20018	        }
20019	        return this;
20020	    }
20021	    // advance the time and update apply the animation
20022	    update(deltaTime) {
vendor: 9,594 bytes, lines 20023-20263
20023	        deltaTime *= this.timeScale;
20024	        const actions = this._actions, nActions = this._nActiveActions, time = this.time += deltaTime, timeDirection = Math.sign(deltaTime), accuIndex = this._accuIndex ^= 1;
20025	        // run active actions
20026	        for(let i = 0; i !== nActions; ++i){
20027	            const action = actions[i];
20028	            action._update(time, deltaTime, timeDirection, accuIndex);
20029	        }
20030	        // update scene graph
20031	        const bindings = this._bindings, nBindings = this._nActiveBindings;
20032	        for(let i = 0; i !== nBindings; ++i){
20033	            bindings[i].apply(accuIndex);
20034	        }
20035	        return this;
20036	    }
20037	    // Allows you to seek to a specific time in an animation.
20038	    setTime(timeInSeconds) {
20039	        this.time = 0; // Zero out time attribute for AnimationMixer object;
20040	        for(let i = 0; i < this._actions.length; i++){
20041	            this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects.
20042	        }
20043	        return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object.
20044	    }
20045	    // return this mixer's root target object
20046	    getRoot() {
20047	        return this._root;
20048	    }
20049	    // free all resources specific to a particular clip
20050	    uncacheClip(clip) {
20051	        const actions = this._actions, clipUuid = clip.uuid, actionsByClip = this._actionsByClip, actionsForClip = actionsByClip[clipUuid];
20052	        if (actionsForClip !== undefined) {
20053	            // note: just calling _removeInactiveAction would mess up the
20054	            // iteration state and also require updating the state we can
20055	            // just throw away
20056	            const actionsToRemove = actionsForClip.knownActions;
20057	            for(let i = 0, n = actionsToRemove.length; i !== n; ++i){
20058	                const action = actionsToRemove[i];
20059	                this._deactivateAction(action);
20060	                const cacheIndex = action._cacheIndex, lastInactiveAction = actions[actions.length - 1];
20061	                action._cacheIndex = null;
20062	                action._byClipCacheIndex = null;
20063	                lastInactiveAction._cacheIndex = cacheIndex;
20064	                actions[cacheIndex] = lastInactiveAction;
20065	                actions.pop();
20066	                this._removeInactiveBindingsForAction(action);
20067	            }
20068	            delete actionsByClip[clipUuid];
20069	        }
20070	    }
20071	    // free all resources specific to a particular root target object
20072	    uncacheRoot(root) {
20073	        const rootUuid = root.uuid, actionsByClip = this._actionsByClip;
20074	        for(const clipUuid in actionsByClip){
20075	            const actionByRoot = actionsByClip[clipUuid].actionByRoot, action = actionByRoot[rootUuid];
20076	            if (action !== undefined) {
20077	                this._deactivateAction(action);
20078	                this._removeInactiveAction(action);
20079	            }
20080	        }
20081	        const bindingsByRoot = this._bindingsByRootAndName, bindingByName = bindingsByRoot[rootUuid];
20082	        if (bindingByName !== undefined) {
20083	            for(const trackName in bindingByName){
20084	                const binding = bindingByName[trackName];
20085	                binding.restoreOriginalState();
20086	                this._removeInactiveBinding(binding);
20087	            }
20088	        }
20089	    }
20090	    // remove a targeted clip from the cache
20091	    uncacheAction(clip, optionalRoot) {
20092	        const action = this.existingAction(clip, optionalRoot);
20093	        if (action !== null) {
20094	            this._deactivateAction(action);
20095	            this._removeInactiveAction(action);
20096	        }
20097	    }
20098	    constructor(root){
20099	        super();
20100	        this._root = root;
20101	        this._initMemoryManager();
20102	        this._accuIndex = 0;
20103	        this.time = 0;
20104	        this.timeScale = 1.0;
20105	    }
20106	}
20107	const _matrix = /*@__PURE__*/ new Matrix4();
20108	class Raycaster {
20109	    set(origin, direction) {
20110	        // direction is assumed to be normalized (for accurate distance calculations)
20111	        this.ray.set(origin, direction);
20112	    }
20113	    setFromCamera(coords, camera) {
20114	        if (camera.isPerspectiveCamera) {
20115	            this.ray.origin.setFromMatrixPosition(camera.matrixWorld);
20116	            this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize();
20117	            this.camera = camera;
20118	        } else if (camera.isOrthographicCamera) {
20119	            this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); // set origin in plane of camera
20120	            this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld);
20121	            this.camera = camera;
20122	        } else {
20123	            console.error('THREE.Raycaster: Unsupported camera type: ' + camera.type);
20124	        }
20125	    }
20126	    setFromXRController(controller) {
20127	        _matrix.identity().extractRotation(controller.matrixWorld);
20128	        this.ray.origin.setFromMatrixPosition(controller.matrixWorld);
20129	        this.ray.direction.set(0, 0, -1).applyMatrix4(_matrix);
20130	        return this;
20131	    }
20132	    intersectObject(object, recursive = true, intersects = []) {
20133	        intersect(object, this, intersects, recursive);
20134	        intersects.sort(ascSort);
20135	        return intersects;
20136	    }
20137	    intersectObjects(objects, recursive = true, intersects = []) {
20138	        for(let i = 0, l = objects.length; i < l; i++){
20139	            intersect(objects[i], this, intersects, recursive);
20140	        }
20141	        intersects.sort(ascSort);
20142	        return intersects;
20143	    }
20144	    constructor(origin, direction, near = 0, far = Infinity){
20145	        this.ray = new Ray(origin, direction);
20146	        // direction is assumed to be normalized (for accurate distance calculations)
20147	        this.near = near;
20148	        this.far = far;
20149	        this.camera = null;
20150	        this.layers = new Layers();
20151	        this.params = {
20152	            Mesh: {},
20153	            Line: {
20154	                threshold: 1
20155	            },
20156	            LOD: {},
20157	            Points: {
20158	                threshold: 1
20159	            },
20160	            Sprite: {}
20161	        };
20162	    }
20163	}
20164	function ascSort(a, b) {
20165	    return a.distance - b.distance;
20166	}
20167	function intersect(object, raycaster, intersects, recursive) {
20168	    let propagate = true;
20169	    if (object.layers.test(raycaster.layers)) {
20170	        const result = object.raycast(raycaster, intersects);
20171	        if (result === false) propagate = false;
20172	    }
20173	    if (propagate === true && recursive === true) {
20174	        const children = object.children;
20175	        for(let i = 0, l = children.length; i < l; i++){
20176	            intersect(children[i], raycaster, intersects, true);
20177	        }
20178	    }
20179	}
20180	/**
20181	 * This class can be used to represent points in 3D space as
20182	 * [Spherical coordinates]{@link https://en.wikipedia.org/wiki/Spherical_coordinate_system}.
20183	 */ class Spherical {
20184	    /**
20185		 * Sets the spherical components by copying the given values.
20186		 *
20187		 * @param {number} radius - The radius.
20188		 * @param {number} phi - The polar angle.
20189		 * @param {number} theta - The azimuthal angle.
20190		 * @return {Spherical} A reference to this spherical.
20191		 */ set(radius, phi, theta) {
20192	        this.radius = radius;
20193	        this.phi = phi;
20194	        this.theta = theta;
20195	        return this;
20196	    }
20197	    /**
20198		 * Copies the values of the given spherical to this instance.
20199		 *
20200		 * @param {Spherical} other - The spherical to copy.
20201		 * @return {Spherical} A reference to this spherical.
20202		 */ copy(other) {
20203	        this.radius = other.radius;
20204	        this.phi = other.phi;
20205	        this.theta = other.theta;
20206	        return this;
20207	    }
20208	    /**
20209		 * Restricts the polar angle [page:.phi phi] to be between `0.000001` and pi -
20210		 * `0.000001`.
20211		 *
20212		 * @return {Spherical} A reference to this spherical.
20213		 */ makeSafe() {
20214	        const EPS = 0.000001;
20215	        this.phi = clamp$1(this.phi, EPS, Math.PI - EPS);
20216	        return this;
20217	    }
20218	    /**
20219		 * Sets the spherical components from the given vector which is assumed to hold
20220		 * Cartesian coordinates.
20221		 *
20222		 * @param {Vector3} v - The vector to set.
20223		 * @return {Spherical} A reference to this spherical.
20224		 */ setFromVector3(v) {
20225	        return this.setFromCartesianCoords(v.x, v.y, v.z);
20226	    }
20227	    /**
20228		 * Sets the spherical components from the given Cartesian coordinates.
20229		 *
20230		 * @param {number} x - The x value.
20231		 * @param {number} y - The x value.
20232		 * @param {number} z - The x value.
20233		 * @return {Spherical} A reference to this spherical.
20234		 */ setFromCartesianCoords(x, y, z) {
20235	        this.radius = Math.sqrt(x * x + y * y + z * z);
20236	        if (this.radius === 0) {
20237	            this.theta = 0;
20238	            this.phi = 0;
20239	        } else {
20240	            this.theta = Math.atan2(x, z);
20241	            this.phi = Math.acos(clamp$1(y / this.radius, -1, 1));
20242	        }
20243	        return this;
20244	    }
20245	    /**
20246		 * Returns a new spherical with copied values from this instance.
20247		 *
20248		 * @return {Spherical} A clone of this instance.
20249		 */ clone() {
20250	        return new this.constructor().copy(this);
20251	    }
20252	    /**
20253		 * Constructs a new spherical.
20254		 *
20255		 * @param {number} [radius=1] - The radius, or the Euclidean distance (straight-line distance) from the point to the origin.
20256		 * @param {number} [phi=0] - The polar angle in radians from the y (up) axis.
20257		 * @param {number} [theta=0] - The equator/azimuthal angle in radians around the y (up) axis.
20258		 */ constructor(radius = 1, phi = 0, theta = 0){
20259	        /**
20260			 * The radius, or the Euclidean distance (straight-line distance) from the point to the origin.
20261			 *
20262			 * @type {number}
20263			 * @default 1
vendor: 5,283 bytes, lines 20264-20366
20264			 */ this.radius = radius;
20265	        /**
20266			 * The polar angle in radians from the y (up) axis.
20267			 *
20268			 * @type {number}
20269			 * @default 0
20270			 */ this.phi = phi;
20271	        /**
20272			 * The equator/azimuthal angle in radians around the y (up) axis.
20273			 *
20274			 * @type {number}
20275			 * @default 0
20276			 */ this.theta = theta;
20277	    }
20278	}
20279	/**
20280	 * Determines how many bytes must be used to represent the texture.
20281	 *
20282	 * @param {number} width - The width of the texture.
20283	 * @param {number} height - The height of the texture.
20284	 * @param {number} format - The texture's format.
20285	 * @param {number} type - The texture's type.
20286	 * @return {number} The byte length.
20287	 */ function getByteLength(width, height, format, type) {
20288	    const typeByteLength = getTextureTypeByteLength(type);
20289	    switch(format){
20290	        // https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml
20291	        case AlphaFormat:
20292	            return width * height;
20293	        case LuminanceFormat:
20294	            return width * height;
20295	        case LuminanceAlphaFormat:
20296	            return width * height * 2;
20297	        case RedFormat:
20298	            return width * height / typeByteLength.components * typeByteLength.byteLength;
20299	        case RedIntegerFormat:
20300	            return width * height / typeByteLength.components * typeByteLength.byteLength;
20301	        case RGFormat:
20302	            return width * height * 2 / typeByteLength.components * typeByteLength.byteLength;
20303	        case RGIntegerFormat:
20304	            return width * height * 2 / typeByteLength.components * typeByteLength.byteLength;
20305	        case RGBFormat:
20306	            return width * height * 3 / typeByteLength.components * typeByteLength.byteLength;
20307	        case RGBAFormat:
20308	            return width * height * 4 / typeByteLength.components * typeByteLength.byteLength;
20309	        case RGBAIntegerFormat:
20310	            return width * height * 4 / typeByteLength.components * typeByteLength.byteLength;
20311	        // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_s3tc_srgb/
20312	        case RGB_S3TC_DXT1_Format:
20313	        case RGBA_S3TC_DXT1_Format:
20314	            return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8;
20315	        case RGBA_S3TC_DXT3_Format:
20316	        case RGBA_S3TC_DXT5_Format:
20317	            return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16;
20318	        // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_pvrtc/
20319	        case RGB_PVRTC_2BPPV1_Format:
20320	        case RGBA_PVRTC_2BPPV1_Format:
20321	            return Math.max(width, 16) * Math.max(height, 8) / 4;
20322	        case RGB_PVRTC_4BPPV1_Format:
20323	        case RGBA_PVRTC_4BPPV1_Format:
20324	            return Math.max(width, 8) * Math.max(height, 8) / 2;
20325	        // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_etc/
20326	        case RGB_ETC1_Format:
20327	        case RGB_ETC2_Format:
20328	            return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8;
20329	        case RGBA_ETC2_EAC_Format:
20330	            return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16;
20331	        // https://registry.khronos.org/webgl/extensions/WEBGL_compressed_texture_astc/
20332	        case RGBA_ASTC_4x4_Format:
20333	            return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16;
20334	        case RGBA_ASTC_5x4_Format:
20335	            return Math.floor((width + 4) / 5) * Math.floor((height + 3) / 4) * 16;
20336	        case RGBA_ASTC_5x5_Format:
20337	            return Math.floor((width + 4) / 5) * Math.floor((height + 4) / 5) * 16;
20338	        case RGBA_ASTC_6x5_Format:
20339	            return Math.floor((width + 5) / 6) * Math.floor((height + 4) / 5) * 16;
20340	        case RGBA_ASTC_6x6_Format:
20341	            return Math.floor((width + 5) / 6) * Math.floor((height + 5) / 6) * 16;
20342	        case RGBA_ASTC_8x5_Format:
20343	            return Math.floor((width + 7) / 8) * Math.floor((height + 4) / 5) * 16;
20344	        case RGBA_ASTC_8x6_Format:
20345	            return Math.floor((width + 7) / 8) * Math.floor((height + 5) / 6) * 16;
20346	        case RGBA_ASTC_8x8_Format:
20347	            return Math.floor((width + 7) / 8) * Math.floor((height + 7) / 8) * 16;
20348	        case RGBA_ASTC_10x5_Format:
20349	            return Math.floor((width + 9) / 10) * Math.floor((height + 4) / 5) * 16;
20350	        case RGBA_ASTC_10x6_Format:
20351	            return Math.floor((width + 9) / 10) * Math.floor((height + 5) / 6) * 16;
20352	        case RGBA_ASTC_10x8_Format:
20353	            return Math.floor((width + 9) / 10) * Math.floor((height + 7) / 8) * 16;
20354	        case RGBA_ASTC_10x10_Format:
20355	            return Math.floor((width + 9) / 10) * Math.floor((height + 9) / 10) * 16;
20356	        case RGBA_ASTC_12x10_Format:
20357	            return Math.floor((width + 11) / 12) * Math.floor((height + 9) / 10) * 16;
20358	        case RGBA_ASTC_12x12_Format:
20359	            return Math.floor((width + 11) / 12) * Math.floor((height + 11) / 12) * 16;
20360	        // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_bptc/
20361	        case RGBA_BPTC_Format:
20362	        case RGB_BPTC_SIGNED_Format:
20363	        case RGB_BPTC_UNSIGNED_Format:
20364	            return Math.ceil(width / 4) * Math.ceil(height / 4) * 16;
20365	        // https://registry.khronos.org/webgl/extensions/EXT_texture_compression_rgtc/
20366	        case RED_RGTC1_Format:
vendor: 9,723 bytes, lines 20367-20586
20367	        case SIGNED_RED_RGTC1_Format:
20368	            return Math.ceil(width / 4) * Math.ceil(height / 4) * 8;
20369	        case RED_GREEN_RGTC2_Format:
20370	        case SIGNED_RED_GREEN_RGTC2_Format:
20371	            return Math.ceil(width / 4) * Math.ceil(height / 4) * 16;
20372	    }
20373	    throw new Error(`Unable to determine texture byte length for ${format} format.`);
20374	}
20375	function getTextureTypeByteLength(type) {
20376	    switch(type){
20377	        case UnsignedByteType:
20378	        case ByteType:
20379	            return {
20380	                byteLength: 1,
20381	                components: 1
20382	            };
20383	        case UnsignedShortType:
20384	        case ShortType:
20385	        case HalfFloatType:
20386	            return {
20387	                byteLength: 2,
20388	                components: 1
20389	            };
20390	        case UnsignedShort4444Type:
20391	        case UnsignedShort5551Type:
20392	            return {
20393	                byteLength: 2,
20394	                components: 4
20395	            };
20396	        case UnsignedIntType:
20397	        case IntType:
20398	        case FloatType:
20399	            return {
20400	                byteLength: 4,
20401	                components: 1
20402	            };
20403	        case UnsignedInt5999Type:
20404	            return {
20405	                byteLength: 4,
20406	                components: 3
20407	            };
20408	    }
20409	    throw new Error(`Unknown texture type ${type}.`);
20410	}
20411	if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
20412	    __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', {
20413	        detail: {
20414	            revision: REVISION
20415	        }
20416	    }));
20417	}
20418	if (typeof window !== 'undefined') {
20419	    if (window.__THREE__) {
20420	        console.warn('WARNING: Multiple instances of Three.js being imported.');
20421	    } else {
20422	        window.__THREE__ = REVISION;
20423	    }
20424	}
20425
20426	function WebGLAnimation() {
20427	    let context = null;
20428	    let isAnimating = false;
20429	    let animationLoop = null;
20430	    let requestId = null;
20431	    function onAnimationFrame(time, frame) {
20432	        animationLoop(time, frame);
20433	        requestId = context.requestAnimationFrame(onAnimationFrame);
20434	    }
20435	    return {
20436	        start: function() {
20437	            if (isAnimating === true) return;
20438	            if (animationLoop === null) return;
20439	            requestId = context.requestAnimationFrame(onAnimationFrame);
20440	            isAnimating = true;
20441	        },
20442	        stop: function() {
20443	            context.cancelAnimationFrame(requestId);
20444	            isAnimating = false;
20445	        },
20446	        setAnimationLoop: function(callback) {
20447	            animationLoop = callback;
20448	        },
20449	        setContext: function(value) {
20450	            context = value;
20451	        }
20452	    };
20453	}
20454	function WebGLAttributes(gl) {
20455	    const buffers = new WeakMap();
20456	    function createBuffer(attribute, bufferType) {
20457	        const array = attribute.array;
20458	        const usage = attribute.usage;
20459	        const size = array.byteLength;
20460	        const buffer = gl.createBuffer();
20461	        gl.bindBuffer(bufferType, buffer);
20462	        gl.bufferData(bufferType, array, usage);
20463	        attribute.onUploadCallback();
20464	        let type;
20465	        if (array instanceof Float32Array) {
20466	            type = gl.FLOAT;
20467	        } else if (array instanceof Uint16Array) {
20468	            if (attribute.isFloat16BufferAttribute) {
20469	                type = gl.HALF_FLOAT;
20470	            } else {
20471	                type = gl.UNSIGNED_SHORT;
20472	            }
20473	        } else if (array instanceof Int16Array) {
20474	            type = gl.SHORT;
20475	        } else if (array instanceof Uint32Array) {
20476	            type = gl.UNSIGNED_INT;
20477	        } else if (array instanceof Int32Array) {
20478	            type = gl.INT;
20479	        } else if (array instanceof Int8Array) {
20480	            type = gl.BYTE;
20481	        } else if (array instanceof Uint8Array) {
20482	            type = gl.UNSIGNED_BYTE;
20483	        } else if (array instanceof Uint8ClampedArray) {
20484	            type = gl.UNSIGNED_BYTE;
20485	        } else {
20486	            throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array);
20487	        }
20488	        return {
20489	            buffer: buffer,
20490	            type: type,
20491	            bytesPerElement: array.BYTES_PER_ELEMENT,
20492	            version: attribute.version,
20493	            size: size
20494	        };
20495	    }
20496	    function updateBuffer(buffer, attribute, bufferType) {
20497	        const array = attribute.array;
20498	        const updateRanges = attribute.updateRanges;
20499	        gl.bindBuffer(bufferType, buffer);
20500	        if (updateRanges.length === 0) {
20501	            // Not using update ranges
20502	            gl.bufferSubData(bufferType, 0, array);
20503	        } else {
20504	            // Before applying update ranges, we merge any adjacent / overlapping
20505	            // ranges to reduce load on `gl.bufferSubData`. Empirically, this has led
20506	            // to performance improvements for applications which make heavy use of
20507	            // update ranges. Likely due to GPU command overhead.
20508	            //
20509	            // Note that to reduce garbage collection between frames, we merge the
20510	            // update ranges in-place. This is safe because this method will clear the
20511	            // update ranges once updated.
20512	            updateRanges.sort((a, b)=>a.start - b.start);
20513	            // To merge the update ranges in-place, we work from left to right in the
20514	            // existing updateRanges array, merging ranges. This may result in a final
20515	            // array which is smaller than the original. This index tracks the last
20516	            // index representing a merged range, any data after this index can be
20517	            // trimmed once the merge algorithm is completed.
20518	            let mergeIndex = 0;
20519	            for(let i = 1; i < updateRanges.length; i++){
20520	                const previousRange = updateRanges[mergeIndex];
20521	                const range = updateRanges[i];
20522	                // We add one here to merge adjacent ranges. This is safe because ranges
20523	                // operate over positive integers.
20524	                if (range.start <= previousRange.start + previousRange.count + 1) {
20525	                    previousRange.count = Math.max(previousRange.count, range.start + range.count - previousRange.start);
20526	                } else {
20527	                    ++mergeIndex;
20528	                    updateRanges[mergeIndex] = range;
20529	                }
20530	            }
20531	            // Trim the array to only contain the merged ranges.
20532	            updateRanges.length = mergeIndex + 1;
20533	            for(let i = 0, l = updateRanges.length; i < l; i++){
20534	                const range = updateRanges[i];
20535	                gl.bufferSubData(bufferType, range.start * array.BYTES_PER_ELEMENT, array, range.start, range.count);
20536	            }
20537	            attribute.clearUpdateRanges();
20538	        }
20539	        attribute.onUploadCallback();
20540	    }
20541	    //
20542	    function get(attribute) {
20543	        if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
20544	        return buffers.get(attribute);
20545	    }
20546	    function remove(attribute) {
20547	        if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
20548	        const data = buffers.get(attribute);
20549	        if (data) {
20550	            gl.deleteBuffer(data.buffer);
20551	            buffers.delete(attribute);
20552	        }
20553	    }
20554	    function update(attribute, bufferType) {
20555	        if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
20556	        if (attribute.isGLBufferAttribute) {
20557	            const cached = buffers.get(attribute);
20558	            if (!cached || cached.version < attribute.version) {
20559	                buffers.set(attribute, {
20560	                    buffer: attribute.buffer,
20561	                    type: attribute.type,
20562	                    bytesPerElement: attribute.elementSize,
20563	                    version: attribute.version
20564	                });
20565	            }
20566	            return;
20567	        }
20568	        const data = buffers.get(attribute);
20569	        if (data === undefined) {
20570	            buffers.set(attribute, createBuffer(attribute, bufferType));
20571	        } else if (data.version < attribute.version) {
20572	            if (data.size !== attribute.array.byteLength) {
20573	                throw new Error('THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.');
20574	            }
20575	            updateBuffer(data.buffer, attribute, bufferType);
20576	            data.version = attribute.version;
20577	        }
20578	    }
20579	    return {
20580	        get: get,
20581	        remove: remove,
20582	        update: update
20583	    };
20584	}
20585	var alphahash_fragment = "#ifdef USE_ALPHAHASH\n\tif ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard;\n#endif";
20586	var alphahash_pars_fragment = "#ifdef USE_ALPHAHASH\n\tconst float ALPHA_HASH_SCALE = 0.05;\n\tfloat hash2D( vec2 value ) {\n\t\treturn fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) );\n\t}\n\tfloat hash3D( vec3 value ) {\n\t\treturn hash2D( vec2( hash2D( value.xy ), value.z ) );\n\t}\n\tfloat getAlphaHashThreshold( vec3 position ) {\n\t\tfloat maxDeriv = max(\n\t\t\tlength( dFdx( position.xyz ) ),\n\t\t\tlength( dFdy( position.xyz ) )\n\t\t);\n\t\tfloat pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv );\n\t\tvec2 pixScales = vec2(\n\t\t\texp2( floor( log2( pixScale ) ) ),\n\t\t\texp2( ceil( log2( pixScale ) ) )\n\t\t);\n\t\tvec2 alpha = vec2(\n\t\t\thash3D( floor( pixScales.x * position.xyz ) ),\n\t\t\thash3D( floor( pixScales.y * position.xyz ) )\n\t\t);\n\t\tfloat lerpFactor = fract( log2( pixScale ) );\n\t\tfloat x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y;\n\t\tfloat a = min( lerpFactor, 1.0 - lerpFactor );\n\t\tvec3 cases = vec3(\n\t\t\tx * x / ( 2.0 * a * ( 1.0 - a ) ),\n\t\t\t( x - 0.5 * a ) / ( 1.0 - a ),\n\t\t\t1.0 
20586- ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) )\n\t\t);\n\t\tfloat threshold = ( x < ( 1.0 - a ) )\n\t\t\t? ( ( x < a ) ? cases.x : cases.y )\n\t\t\t: cases.z;\n\t\treturn clamp( threshold , 1.0e-6, 1.0 );\n\t}\n#endif";
20587	var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g;\n#endif";
20588	var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
20589	var alphatest_fragment = "#ifdef USE_ALPHATEST\n\t#ifdef ALPHA_TO_COVERAGE\n\tdiffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a );\n\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\tif ( diffuseColor.a < alphaTest ) discard;\n\t#endif\n#endif";
20590	var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
20591	var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_CLEARCOAT ) \n\t\tclearcoatSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_SHEEN ) \n\t\tsheenSpecularIndirect *= ambientOcclusion;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometryNormal, geometryViewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif";
20592	var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
20593	var batching_pars_vertex = "#ifdef USE_BATCHING\n\t#if ! defined( GL_ANGLE_multi_draw )\n\t#define gl_DrawID _gl_DrawID\n\tuniform int _gl_DrawID;\n\t#endif\n\tuniform highp sampler2D batchingTexture;\n\tuniform highp usampler2D batchingIdTexture;\n\tmat4 getBatchingMatrix( const in float i ) {\n\t\tint size = textureSize( batchingTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n\tfloat getIndirectIndex( const in int i ) {\n\t\tint size = textureSize( batchingIdTexture, 0 ).x;\n\t\tint x = i % size;\n\t\tint y = i / size;\n\t\treturn float( texelFetch( batchingIdTexture, ivec2( x, y ), 0 ).r );\n\t}\n#endif\n#ifdef USE_BATCHING_COLOR\n\tuniform sampler2D batchingColorTexture;\n\tvec3 getBatchingColor( const in float i ) {\n\t\tint size = textureSize( batchingColorTexture, 0 ).x;\n\t\tint j = int( i );\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\treturn texelFetch( batchingColorTexture, ivec2( x, y ), 0 ).rgb;\n\t}\n#endif";
20594	var batching_vertex = "#ifdef USE_BATCHING\n\tmat4 batchingMatrix = getBatchingMatrix( getIndirectIndex( gl_DrawID ) );\n#endif";
20595	var begin_vertex = "vec3 transformed = vec3( position );\n#ifdef USE_ALPHAHASH\n\tvPosition = vec3( position );\n#endif";
20596	var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
20597	var bsdfs = "float G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n} // validated";
20598	var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660,  0.0556434,\n\t\t-1.5371385,  1.8760108, -0.2040259,\n\t\t-0.4985314,  0.0415560,  1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\treturn vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );
20598\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif";
20599	var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vBumpMapUv );\n\t\tvec2 dSTdy = dFdy( vBumpMapUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );\n\t\tvec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
20600	var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif";
20601	var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
20602	var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
20603	var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
20604	var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif";
20605	var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif";
20606	var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec3 vColor;\n#endif";
20607	var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvec3 batchingColor = getBatchingColor( getIndirectIndex( gl_DrawID ) );\n\tvColor.xyz *= batchingColor.xyz;\n#endif";
20608	var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated";
20609	var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
20610	var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );
20610\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
20611	var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
20612	var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif";
20613	var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
20614	var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
20615	var colorspace_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
20616	var colorspace_pars_fragment = "vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}";
20617	var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";
20618	var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
20619	var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
20620	var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
20621	var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t}
20621 else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
20622	var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif";
20623	var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif";
20624	var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
20625	var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif";
20626	var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}";
20627	var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
20628	var lights_lambert_fragment = "LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;";
20629	var lights_lambert_pars_fragment = "varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert";
20630	var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}
20630\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif";
20631	var envmap_physical_pars_fragment = "#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif";
20632	var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
20633	var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon";
20634	var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
20635	var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot
20635( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong";
20636	var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;
20636\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif";
20637	var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\tfloat dispersion
vendor: 15,196 bytes, line 20637
20637;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n    float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n    float x2 = x * x;\n    float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n    return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn saturate(v);\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColor;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3(    0, 1,    0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
20638	var lights_fragment_begin = "\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
20639	var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif";
20640	var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif";
20641	var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
20642	var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
20643	var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
20644	var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif";
20645	var map_fragment = "#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif";
20646	var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
20647	var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif";
20648	var map_particle_pars_fragment = "#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
20649	var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
20650	var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
20651	var morphinstance_vertex = "#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] =  texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif";
20652	var morphcolor_vertex = "#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif";
20653	var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif";
20654	var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif";
20655	var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif";
20656	var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;";
20657	var normal_fragment_maps = "#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );
20657\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif";
20658	var normal_pars_fragment = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
20659	var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
20660	var normal_vertex = "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif";
20661	var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif";
20662	var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif";
20663	var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif";
20664	var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif";
20665	var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif";
20666	var opaque_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );";
20667	var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 25
206675.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn depth * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * depth - far );\n}";
20668	var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
20669	var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
20670	var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
20671	var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif";
20672	var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
20673	var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
20674	var shadowmap_pars_fragment = "#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;
20674\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t  texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t  f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t  texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t  f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\t\n\t\tfloat lightToPositionLength = length( lightToPosition );\n\t\tif ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t\t) * ( 1.0 / 9.0 );\n\t\t\t#else\n\t\t\t\tshadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t\t#endif\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n#endif";
20675	var shadowmap_pars_vertex = "#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
20676	var shadowmap_vertex = "#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif";
20677	var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
20678	var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
20679	var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif";
20680	var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
20681	var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif";
20682	var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
20683	var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
20684	var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
20685	var tonemapping_pars_fragment = 
vendor: 3,668 bytes, line 20685
20685"#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3(  1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108,  1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605,  1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }"
20685;
20686	var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif";
20687	var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a *  a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif";
20688	var uv_pars_fragment = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;
20688\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif";
20689	var uv_pars_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif";
20690	var uv_vertex = "#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;
20690\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif";
20691	var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
20692	const vertex$h = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
20693	const fragment$h = "uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
20694	const vertex$g = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
20695	const fragment$g = "#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
20696	const vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
20697	const fragment$f = "uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
20698	const vertex$e = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#include <morphinstance_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
20699	const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}";
20700	const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <skinbase_vertex>\n\t#include <morphinstance_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
20701	const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <clipping_planes_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
20702	const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
20703	const fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n}";
20704	const vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
20705	const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
20706	const vertex$a = "#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
20707	const fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
20708	const vertex$9 = "#define LAMBERT\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
20709	const fragment$9 = "#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_lambert_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_lambert_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
20710	const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t
20710#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
20711	const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
20712	const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
20713	const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}";
20714	const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
20715	const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
20716	const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}";
20717	const fragment$5 = 
vendor: 4,251 bytes, line 20717
20717"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n\tuniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}"
vendor: 38,957 bytes, lines 20717-21711
20717;
20718	const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <batching_pars_vertex>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
20719	const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
20720	const vertex$3 = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\n#ifdef USE_POINTS_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include <color_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
20721	const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
20722	const vertex$2 = "#include <common>\n#include <batching_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <batching_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphinstance_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
20723	const fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <logdepthbuf_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\t#include <logdepthbuf_fragment>\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}";
20724	const vertex$1 = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix[ 3 ];\n\tvec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
20725	const fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <alphahash_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <opaque_fragment>\n\t#include <tonemapping_fragment>\n\t#include <colorspace_fragment>\n\t#include <fog_fragment>\n}";
20726	const ShaderChunk = {
20727	    alphahash_fragment: alphahash_fragment,
20728	    alphahash_pars_fragment: alphahash_pars_fragment,
20729	    alphamap_fragment: alphamap_fragment,
20730	    alphamap_pars_fragment: alphamap_pars_fragment,
20731	    alphatest_fragment: alphatest_fragment,
20732	    alphatest_pars_fragment: alphatest_pars_fragment,
20733	    aomap_fragment: aomap_fragment,
20734	    aomap_pars_fragment: aomap_pars_fragment,
20735	    batching_pars_vertex: batching_pars_vertex,
20736	    batching_vertex: batching_vertex,
20737	    begin_vertex: begin_vertex,
20738	    beginnormal_vertex: beginnormal_vertex,
20739	    bsdfs: bsdfs,
20740	    iridescence_fragment: iridescence_fragment,
20741	    bumpmap_pars_fragment: bumpmap_pars_fragment,
20742	    clipping_planes_fragment: clipping_planes_fragment,
20743	    clipping_planes_pars_fragment: clipping_planes_pars_fragment,
20744	    clipping_planes_pars_vertex: clipping_planes_pars_vertex,
20745	    clipping_planes_vertex: clipping_planes_vertex,
20746	    color_fragment: color_fragment,
20747	    color_pars_fragment: color_pars_fragment,
20748	    color_pars_vertex: color_pars_vertex,
20749	    color_vertex: color_vertex,
20750	    common: common,
20751	    cube_uv_reflection_fragment: cube_uv_reflection_fragment,
20752	    defaultnormal_vertex: defaultnormal_vertex,
20753	    displacementmap_pars_vertex: displacementmap_pars_vertex,
20754	    displacementmap_vertex: displacementmap_vertex,
20755	    emissivemap_fragment: emissivemap_fragment,
20756	    emissivemap_pars_fragment: emissivemap_pars_fragment,
20757	    colorspace_fragment: colorspace_fragment,
20758	    colorspace_pars_fragment: colorspace_pars_fragment,
20759	    envmap_fragment: envmap_fragment,
20760	    envmap_common_pars_fragment: envmap_common_pars_fragment,
20761	    envmap_pars_fragment: envmap_pars_fragment,
20762	    envmap_pars_vertex: envmap_pars_vertex,
20763	    envmap_physical_pars_fragment: envmap_physical_pars_fragment,
20764	    envmap_vertex: envmap_vertex,
20765	    fog_vertex: fog_vertex,
20766	    fog_pars_vertex: fog_pars_vertex,
20767	    fog_fragment: fog_fragment,
20768	    fog_pars_fragment: fog_pars_fragment,
20769	    gradientmap_pars_fragment: gradientmap_pars_fragment,
20770	    lightmap_pars_fragment: lightmap_pars_fragment,
20771	    lights_lambert_fragment: lights_lambert_fragment,
20772	    lights_lambert_pars_fragment: lights_lambert_pars_fragment,
20773	    lights_pars_begin: lights_pars_begin,
20774	    lights_toon_fragment: lights_toon_fragment,
20775	    lights_toon_pars_fragment: lights_toon_pars_fragment,
20776	    lights_phong_fragment: lights_phong_fragment,
20777	    lights_phong_pars_fragment: lights_phong_pars_fragment,
20778	    lights_physical_fragment: lights_physical_fragment,
20779	    lights_physical_pars_fragment: lights_physical_pars_fragment,
20780	    lights_fragment_begin: lights_fragment_begin,
20781	    lights_fragment_maps: lights_fragment_maps,
20782	    lights_fragment_end: lights_fragment_end,
20783	    logdepthbuf_fragment: logdepthbuf_fragment,
20784	    logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
20785	    logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
20786	    logdepthbuf_vertex: logdepthbuf_vertex,
20787	    map_fragment: map_fragment,
20788	    map_pars_fragment: map_pars_fragment,
20789	    map_particle_fragment: map_particle_fragment,
20790	    map_particle_pars_fragment: map_particle_pars_fragment,
20791	    metalnessmap_fragment: metalnessmap_fragment,
20792	    metalnessmap_pars_fragment: metalnessmap_pars_fragment,
20793	    morphinstance_vertex: morphinstance_vertex,
20794	    morphcolor_vertex: morphcolor_vertex,
20795	    morphnormal_vertex: morphnormal_vertex,
20796	    morphtarget_pars_vertex: morphtarget_pars_vertex,
20797	    morphtarget_vertex: morphtarget_vertex,
20798	    normal_fragment_begin: normal_fragment_begin,
20799	    normal_fragment_maps: normal_fragment_maps,
20800	    normal_pars_fragment: normal_pars_fragment,
20801	    normal_pars_vertex: normal_pars_vertex,
20802	    normal_vertex: normal_vertex,
20803	    normalmap_pars_fragment: normalmap_pars_fragment,
20804	    clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
20805	    clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
20806	    clearcoat_pars_fragment: clearcoat_pars_fragment,
20807	    iridescence_pars_fragment: iridescence_pars_fragment,
20808	    opaque_fragment: opaque_fragment,
20809	    packing: packing,
20810	    premultiplied_alpha_fragment: premultiplied_alpha_fragment,
20811	    project_vertex: project_vertex,
20812	    dithering_fragment: dithering_fragment,
20813	    dithering_pars_fragment: dithering_pars_fragment,
20814	    roughnessmap_fragment: roughnessmap_fragment,
20815	    roughnessmap_pars_fragment: roughnessmap_pars_fragment,
20816	    shadowmap_pars_fragment: shadowmap_pars_fragment,
20817	    shadowmap_pars_vertex: shadowmap_pars_vertex,
20818	    shadowmap_vertex: shadowmap_vertex,
20819	    shadowmask_pars_fragment: shadowmask_pars_fragment,
20820	    skinbase_vertex: skinbase_vertex,
20821	    skinning_pars_vertex: skinning_pars_vertex,
20822	    skinning_vertex: skinning_vertex,
20823	    skinnormal_vertex: skinnormal_vertex,
20824	    specularmap_fragment: specularmap_fragment,
20825	    specularmap_pars_fragment: specularmap_pars_fragment,
20826	    tonemapping_fragment: tonemapping_fragment,
20827	    tonemapping_pars_fragment: tonemapping_pars_fragment,
20828	    transmission_fragment: transmission_fragment,
20829	    transmission_pars_fragment: transmission_pars_fragment,
20830	    uv_pars_fragment: uv_pars_fragment,
20831	    uv_pars_vertex: uv_pars_vertex,
20832	    uv_vertex: uv_vertex,
20833	    worldpos_vertex: worldpos_vertex,
20834	    background_vert: vertex$h,
20835	    background_frag: fragment$h,
20836	    backgroundCube_vert: vertex$g,
20837	    backgroundCube_frag: fragment$g,
20838	    cube_vert: vertex$f,
20839	    cube_frag: fragment$f,
20840	    depth_vert: vertex$e,
20841	    depth_frag: fragment$e,
20842	    distanceRGBA_vert: vertex$d,
20843	    distanceRGBA_frag: fragment$d,
20844	    equirect_vert: vertex$c,
20845	    equirect_frag: fragment$c,
20846	    linedashed_vert: vertex$b,
20847	    linedashed_frag: fragment$b,
20848	    meshbasic_vert: vertex$a,
20849	    meshbasic_frag: fragment$a,
20850	    meshlambert_vert: vertex$9,
20851	    meshlambert_frag: fragment$9,
20852	    meshmatcap_vert: vertex$8,
20853	    meshmatcap_frag: fragment$8,
20854	    meshnormal_vert: vertex$7,
20855	    meshnormal_frag: fragment$7,
20856	    meshphong_vert: vertex$6,
20857	    meshphong_frag: fragment$6,
20858	    meshphysical_vert: vertex$5,
20859	    meshphysical_frag: fragment$5,
20860	    meshtoon_vert: vertex$4,
20861	    meshtoon_frag: fragment$4,
20862	    points_vert: vertex$3,
20863	    points_frag: fragment$3,
20864	    shadow_vert: vertex$2,
20865	    shadow_frag: fragment$2,
20866	    sprite_vert: vertex$1,
20867	    sprite_frag: fragment$1
20868	};
20869	/**
20870	 * Uniforms library for shared webgl shaders
20871	 */ const UniformsLib = {
20872	    common: {
20873	        diffuse: {
20874	            value: /*@__PURE__*/ new Color(0xffffff)
20875	        },
20876	        opacity: {
20877	            value: 1.0
20878	        },
20879	        map: {
20880	            value: null
20881	        },
20882	        mapTransform: {
20883	            value: /*@__PURE__*/ new Matrix3()
20884	        },
20885	        alphaMap: {
20886	            value: null
20887	        },
20888	        alphaMapTransform: {
20889	            value: /*@__PURE__*/ new Matrix3()
20890	        },
20891	        alphaTest: {
20892	            value: 0
20893	        }
20894	    },
20895	    specularmap: {
20896	        specularMap: {
20897	            value: null
20898	        },
20899	        specularMapTransform: {
20900	            value: /*@__PURE__*/ new Matrix3()
20901	        }
20902	    },
20903	    envmap: {
20904	        envMap: {
20905	            value: null
20906	        },
20907	        envMapRotation: {
20908	            value: /*@__PURE__*/ new Matrix3()
20909	        },
20910	        flipEnvMap: {
20911	            value: -1
20912	        },
20913	        reflectivity: {
20914	            value: 1.0
20915	        },
20916	        ior: {
20917	            value: 1.5
20918	        },
20919	        refractionRatio: {
20920	            value: 0.98
20921	        }
20922	    },
20923	    aomap: {
20924	        aoMap: {
20925	            value: null
20926	        },
20927	        aoMapIntensity: {
20928	            value: 1
20929	        },
20930	        aoMapTransform: {
20931	            value: /*@__PURE__*/ new Matrix3()
20932	        }
20933	    },
20934	    lightmap: {
20935	        lightMap: {
20936	            value: null
20937	        },
20938	        lightMapIntensity: {
20939	            value: 1
20940	        },
20941	        lightMapTransform: {
20942	            value: /*@__PURE__*/ new Matrix3()
20943	        }
20944	    },
20945	    bumpmap: {
20946	        bumpMap: {
20947	            value: null
20948	        },
20949	        bumpMapTransform: {
20950	            value: /*@__PURE__*/ new Matrix3()
20951	        },
20952	        bumpScale: {
20953	            value: 1
20954	        }
20955	    },
20956	    normalmap: {
20957	        normalMap: {
20958	            value: null
20959	        },
20960	        normalMapTransform: {
20961	            value: /*@__PURE__*/ new Matrix3()
20962	        },
20963	        normalScale: {
20964	            value: /*@__PURE__*/ new Vector2(1, 1)
20965	        }
20966	    },
20967	    displacementmap: {
20968	        displacementMap: {
20969	            value: null
20970	        },
20971	        displacementMapTransform: {
20972	            value: /*@__PURE__*/ new Matrix3()
20973	        },
20974	        displacementScale: {
20975	            value: 1
20976	        },
20977	        displacementBias: {
20978	            value: 0
20979	        }
20980	    },
20981	    emissivemap: {
20982	        emissiveMap: {
20983	            value: null
20984	        },
20985	        emissiveMapTransform: {
20986	            value: /*@__PURE__*/ new Matrix3()
20987	        }
20988	    },
20989	    metalnessmap: {
20990	        metalnessMap: {
20991	            value: null
20992	        },
20993	        metalnessMapTransform: {
20994	            value: /*@__PURE__*/ new Matrix3()
20995	        }
20996	    },
20997	    roughnessmap: {
20998	        roughnessMap: {
20999	            value: null
21000	        },
21001	        roughnessMapTransform: {
21002	            value: /*@__PURE__*/ new Matrix3()
21003	        }
21004	    },
21005	    gradientmap: {
21006	        gradientMap: {
21007	            value: null
21008	        }
21009	    },
21010	    fog: {
21011	        fogDensity: {
21012	            value: 0.00025
21013	        },
21014	        fogNear: {
21015	            value: 1
21016	        },
21017	        fogFar: {
21018	            value: 2000
21019	        },
21020	        fogColor: {
21021	            value: /*@__PURE__*/ new Color(0xffffff)
21022	        }
21023	    },
21024	    lights: {
21025	        ambientLightColor: {
21026	            value: []
21027	        },
21028	        lightProbe: {
21029	            value: []
21030	        },
21031	        directionalLights: {
21032	            value: [],
21033	            properties: {
21034	                direction: {},
21035	                color: {}
21036	            }
21037	        },
21038	        directionalLightShadows: {
21039	            value: [],
21040	            properties: {
21041	                shadowIntensity: 1,
21042	                shadowBias: {},
21043	                shadowNormalBias: {},
21044	                shadowRadius: {},
21045	                shadowMapSize: {}
21046	            }
21047	        },
21048	        directionalShadowMap: {
21049	            value: []
21050	        },
21051	        directionalShadowMatrix: {
21052	            value: []
21053	        },
21054	        spotLights: {
21055	            value: [],
21056	            properties: {
21057	                color: {},
21058	                position: {},
21059	                direction: {},
21060	                distance: {},
21061	                coneCos: {},
21062	                penumbraCos: {},
21063	                decay: {}
21064	            }
21065	        },
21066	        spotLightShadows: {
21067	            value: [],
21068	            properties: {
21069	                shadowIntensity: 1,
21070	                shadowBias: {},
21071	                shadowNormalBias: {},
21072	                shadowRadius: {},
21073	                shadowMapSize: {}
21074	            }
21075	        },
21076	        spotLightMap: {
21077	            value: []
21078	        },
21079	        spotShadowMap: {
21080	            value: []
21081	        },
21082	        spotLightMatrix: {
21083	            value: []
21084	        },
21085	        pointLights: {
21086	            value: [],
21087	            properties: {
21088	                color: {},
21089	                position: {},
21090	                decay: {},
21091	                distance: {}
21092	            }
21093	        },
21094	        pointLightShadows: {
21095	            value: [],
21096	            properties: {
21097	                shadowIntensity: 1,
21098	                shadowBias: {},
21099	                shadowNormalBias: {},
21100	                shadowRadius: {},
21101	                shadowMapSize: {},
21102	                shadowCameraNear: {},
21103	                shadowCameraFar: {}
21104	            }
21105	        },
21106	        pointShadowMap: {
21107	            value: []
21108	        },
21109	        pointShadowMatrix: {
21110	            value: []
21111	        },
21112	        hemisphereLights: {
21113	            value: [],
21114	            properties: {
21115	                direction: {},
21116	                skyColor: {},
21117	                groundColor: {}
21118	            }
21119	        },
21120	        // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
21121	        rectAreaLights: {
21122	            value: [],
21123	            properties: {
21124	                color: {},
21125	                position: {},
21126	                width: {},
21127	                height: {}
21128	            }
21129	        },
21130	        ltc_1: {
21131	            value: null
21132	        },
21133	        ltc_2: {
21134	            value: null
21135	        }
21136	    },
21137	    points: {
21138	        diffuse: {
21139	            value: /*@__PURE__*/ new Color(0xffffff)
21140	        },
21141	        opacity: {
21142	            value: 1.0
21143	        },
21144	        size: {
21145	            value: 1.0
21146	        },
21147	        scale: {
21148	            value: 1.0
21149	        },
21150	        map: {
21151	            value: null
21152	        },
21153	        alphaMap: {
21154	            value: null
21155	        },
21156	        alphaMapTransform: {
21157	            value: /*@__PURE__*/ new Matrix3()
21158	        },
21159	        alphaTest: {
21160	            value: 0
21161	        },
21162	        uvTransform: {
21163	            value: /*@__PURE__*/ new Matrix3()
21164	        }
21165	    },
21166	    sprite: {
21167	        diffuse: {
21168	            value: /*@__PURE__*/ new Color(0xffffff)
21169	        },
21170	        opacity: {
21171	            value: 1.0
21172	        },
21173	        center: {
21174	            value: /*@__PURE__*/ new Vector2(0.5, 0.5)
21175	        },
21176	        rotation: {
21177	            value: 0.0
21178	        },
21179	        map: {
21180	            value: null
21181	        },
21182	        mapTransform: {
21183	            value: /*@__PURE__*/ new Matrix3()
21184	        },
21185	        alphaMap: {
21186	            value: null
21187	        },
21188	        alphaMapTransform: {
21189	            value: /*@__PURE__*/ new Matrix3()
21190	        },
21191	        alphaTest: {
21192	            value: 0
21193	        }
21194	    }
21195	};
21196	const ShaderLib = {
21197	    basic: {
21198	        uniforms: /*@__PURE__*/ mergeUniforms([
21199	            UniformsLib.common,
21200	            UniformsLib.specularmap,
21201	            UniformsLib.envmap,
21202	            UniformsLib.aomap,
21203	            UniformsLib.lightmap,
21204	            UniformsLib.fog
21205	        ]),
21206	        vertexShader: ShaderChunk.meshbasic_vert,
21207	        fragmentShader: ShaderChunk.meshbasic_frag
21208	    },
21209	    lambert: {
21210	        uniforms: /*@__PURE__*/ mergeUniforms([
21211	            UniformsLib.common,
21212	            UniformsLib.specularmap,
21213	            UniformsLib.envmap,
21214	            UniformsLib.aomap,
21215	            UniformsLib.lightmap,
21216	            UniformsLib.emissivemap,
21217	            UniformsLib.bumpmap,
21218	            UniformsLib.normalmap,
21219	            UniformsLib.displacementmap,
21220	            UniformsLib.fog,
21221	            UniformsLib.lights,
21222	            {
21223	                emissive: {
21224	                    value: /*@__PURE__*/ new Color(0x000000)
21225	                }
21226	            }
21227	        ]),
21228	        vertexShader: ShaderChunk.meshlambert_vert,
21229	        fragmentShader: ShaderChunk.meshlambert_frag
21230	    },
21231	    phong: {
21232	        uniforms: /*@__PURE__*/ mergeUniforms([
21233	            UniformsLib.common,
21234	            UniformsLib.specularmap,
21235	            UniformsLib.envmap,
21236	            UniformsLib.aomap,
21237	            UniformsLib.lightmap,
21238	            UniformsLib.emissivemap,
21239	            UniformsLib.bumpmap,
21240	            UniformsLib.normalmap,
21241	            UniformsLib.displacementmap,
21242	            UniformsLib.fog,
21243	            UniformsLib.lights,
21244	            {
21245	                emissive: {
21246	                    value: /*@__PURE__*/ new Color(0x000000)
21247	                },
21248	                specular: {
21249	                    value: /*@__PURE__*/ new Color(0x111111)
21250	                },
21251	                shininess: {
21252	                    value: 30
21253	                }
21254	            }
21255	        ]),
21256	        vertexShader: ShaderChunk.meshphong_vert,
21257	        fragmentShader: ShaderChunk.meshphong_frag
21258	    },
21259	    standard: {
21260	        uniforms: /*@__PURE__*/ mergeUniforms([
21261	            UniformsLib.common,
21262	            UniformsLib.envmap,
21263	            UniformsLib.aomap,
21264	            UniformsLib.lightmap,
21265	            UniformsLib.emissivemap,
21266	            UniformsLib.bumpmap,
21267	            UniformsLib.normalmap,
21268	            UniformsLib.displacementmap,
21269	            UniformsLib.roughnessmap,
21270	            UniformsLib.metalnessmap,
21271	            UniformsLib.fog,
21272	            UniformsLib.lights,
21273	            {
21274	                emissive: {
21275	                    value: /*@__PURE__*/ new Color(0x000000)
21276	                },
21277	                roughness: {
21278	                    value: 1.0
21279	                },
21280	                metalness: {
21281	                    value: 0.0
21282	                },
21283	                envMapIntensity: {
21284	                    value: 1
21285	                }
21286	            }
21287	        ]),
21288	        vertexShader: ShaderChunk.meshphysical_vert,
21289	        fragmentShader: ShaderChunk.meshphysical_frag
21290	    },
21291	    toon: {
21292	        uniforms: /*@__PURE__*/ mergeUniforms([
21293	            UniformsLib.common,
21294	            UniformsLib.aomap,
21295	            UniformsLib.lightmap,
21296	            UniformsLib.emissivemap,
21297	            UniformsLib.bumpmap,
21298	            UniformsLib.normalmap,
21299	            UniformsLib.displacementmap,
21300	            UniformsLib.gradientmap,
21301	            UniformsLib.fog,
21302	            UniformsLib.lights,
21303	            {
21304	                emissive: {
21305	                    value: /*@__PURE__*/ new Color(0x000000)
21306	                }
21307	            }
21308	        ]),
21309	        vertexShader: ShaderChunk.meshtoon_vert,
21310	        fragmentShader: ShaderChunk.meshtoon_frag
21311	    },
21312	    matcap: {
21313	        uniforms: /*@__PURE__*/ mergeUniforms([
21314	            UniformsLib.common,
21315	            UniformsLib.bumpmap,
21316	            UniformsLib.normalmap,
21317	            UniformsLib.displacementmap,
21318	            UniformsLib.fog,
21319	            {
21320	                matcap: {
21321	                    value: null
21322	                }
21323	            }
21324	        ]),
21325	        vertexShader: ShaderChunk.meshmatcap_vert,
21326	        fragmentShader: ShaderChunk.meshmatcap_frag
21327	    },
21328	    points: {
21329	        uniforms: /*@__PURE__*/ mergeUniforms([
21330	            UniformsLib.points,
21331	            UniformsLib.fog
21332	        ]),
21333	        vertexShader: ShaderChunk.points_vert,
21334	        fragmentShader: ShaderChunk.points_frag
21335	    },
21336	    dashed: {
21337	        uniforms: /*@__PURE__*/ mergeUniforms([
21338	            UniformsLib.common,
21339	            UniformsLib.fog,
21340	            {
21341	                scale: {
21342	                    value: 1
21343	                },
21344	                dashSize: {
21345	                    value: 1
21346	                },
21347	                totalSize: {
21348	                    value: 2
21349	                }
21350	            }
21351	        ]),
21352	        vertexShader: ShaderChunk.linedashed_vert,
21353	        fragmentShader: ShaderChunk.linedashed_frag
21354	    },
21355	    depth: {
21356	        uniforms: /*@__PURE__*/ mergeUniforms([
21357	            UniformsLib.common,
21358	            UniformsLib.displacementmap
21359	        ]),
21360	        vertexShader: ShaderChunk.depth_vert,
21361	        fragmentShader: ShaderChunk.depth_frag
21362	    },
21363	    normal: {
21364	        uniforms: /*@__PURE__*/ mergeUniforms([
21365	            UniformsLib.common,
21366	            UniformsLib.bumpmap,
21367	            UniformsLib.normalmap,
21368	            UniformsLib.displacementmap,
21369	            {
21370	                opacity: {
21371	                    value: 1.0
21372	                }
21373	            }
21374	        ]),
21375	        vertexShader: ShaderChunk.meshnormal_vert,
21376	        fragmentShader: ShaderChunk.meshnormal_frag
21377	    },
21378	    sprite: {
21379	        uniforms: /*@__PURE__*/ mergeUniforms([
21380	            UniformsLib.sprite,
21381	            UniformsLib.fog
21382	        ]),
21383	        vertexShader: ShaderChunk.sprite_vert,
21384	        fragmentShader: ShaderChunk.sprite_frag
21385	    },
21386	    background: {
21387	        uniforms: {
21388	            uvTransform: {
21389	                value: /*@__PURE__*/ new Matrix3()
21390	            },
21391	            t2D: {
21392	                value: null
21393	            },
21394	            backgroundIntensity: {
21395	                value: 1
21396	            }
21397	        },
21398	        vertexShader: ShaderChunk.background_vert,
21399	        fragmentShader: ShaderChunk.background_frag
21400	    },
21401	    backgroundCube: {
21402	        uniforms: {
21403	            envMap: {
21404	                value: null
21405	            },
21406	            flipEnvMap: {
21407	                value: -1
21408	            },
21409	            backgroundBlurriness: {
21410	                value: 0
21411	            },
21412	            backgroundIntensity: {
21413	                value: 1
21414	            },
21415	            backgroundRotation: {
21416	                value: /*@__PURE__*/ new Matrix3()
21417	            }
21418	        },
21419	        vertexShader: ShaderChunk.backgroundCube_vert,
21420	        fragmentShader: ShaderChunk.backgroundCube_frag
21421	    },
21422	    cube: {
21423	        uniforms: {
21424	            tCube: {
21425	                value: null
21426	            },
21427	            tFlip: {
21428	                value: -1
21429	            },
21430	            opacity: {
21431	                value: 1.0
21432	            }
21433	        },
21434	        vertexShader: ShaderChunk.cube_vert,
21435	        fragmentShader: ShaderChunk.cube_frag
21436	    },
21437	    equirect: {
21438	        uniforms: {
21439	            tEquirect: {
21440	                value: null
21441	            }
21442	        },
21443	        vertexShader: ShaderChunk.equirect_vert,
21444	        fragmentShader: ShaderChunk.equirect_frag
21445	    },
21446	    distanceRGBA: {
21447	        uniforms: /*@__PURE__*/ mergeUniforms([
21448	            UniformsLib.common,
21449	            UniformsLib.displacementmap,
21450	            {
21451	                referencePosition: {
21452	                    value: /*@__PURE__*/ new Vector3()
21453	                },
21454	                nearDistance: {
21455	                    value: 1
21456	                },
21457	                farDistance: {
21458	                    value: 1000
21459	                }
21460	            }
21461	        ]),
21462	        vertexShader: ShaderChunk.distanceRGBA_vert,
21463	        fragmentShader: ShaderChunk.distanceRGBA_frag
21464	    },
21465	    shadow: {
21466	        uniforms: /*@__PURE__*/ mergeUniforms([
21467	            UniformsLib.lights,
21468	            UniformsLib.fog,
21469	            {
21470	                color: {
21471	                    value: /*@__PURE__*/ new Color(0x00000)
21472	                },
21473	                opacity: {
21474	                    value: 1.0
21475	                }
21476	            }
21477	        ]),
21478	        vertexShader: ShaderChunk.shadow_vert,
21479	        fragmentShader: ShaderChunk.shadow_frag
21480	    }
21481	};
21482	ShaderLib.physical = {
21483	    uniforms: /*@__PURE__*/ mergeUniforms([
21484	        ShaderLib.standard.uniforms,
21485	        {
21486	            clearcoat: {
21487	                value: 0
21488	            },
21489	            clearcoatMap: {
21490	                value: null
21491	            },
21492	            clearcoatMapTransform: {
21493	                value: /*@__PURE__*/ new Matrix3()
21494	            },
21495	            clearcoatNormalMap: {
21496	                value: null
21497	            },
21498	            clearcoatNormalMapTransform: {
21499	                value: /*@__PURE__*/ new Matrix3()
21500	            },
21501	            clearcoatNormalScale: {
21502	                value: /*@__PURE__*/ new Vector2(1, 1)
21503	            },
21504	            clearcoatRoughness: {
21505	                value: 0
21506	            },
21507	            clearcoatRoughnessMap: {
21508	                value: null
21509	            },
21510	            clearcoatRoughnessMapTransform: {
21511	                value: /*@__PURE__*/ new Matrix3()
21512	            },
21513	            dispersion: {
21514	                value: 0
21515	            },
21516	            iridescence: {
21517	                value: 0
21518	            },
21519	            iridescenceMap: {
21520	                value: null
21521	            },
21522	            iridescenceMapTransform: {
21523	                value: /*@__PURE__*/ new Matrix3()
21524	            },
21525	            iridescenceIOR: {
21526	                value: 1.3
21527	            },
21528	            iridescenceThicknessMinimum: {
21529	                value: 100
21530	            },
21531	            iridescenceThicknessMaximum: {
21532	                value: 400
21533	            },
21534	            iridescenceThicknessMap: {
21535	                value: null
21536	            },
21537	            iridescenceThicknessMapTransform: {
21538	                value: /*@__PURE__*/ new Matrix3()
21539	            },
21540	            sheen: {
21541	                value: 0
21542	            },
21543	            sheenColor: {
21544	                value: /*@__PURE__*/ new Color(0x000000)
21545	            },
21546	            sheenColorMap: {
21547	                value: null
21548	            },
21549	            sheenColorMapTransform: {
21550	                value: /*@__PURE__*/ new Matrix3()
21551	            },
21552	            sheenRoughness: {
21553	                value: 1
21554	            },
21555	            sheenRoughnessMap: {
21556	                value: null
21557	            },
21558	            sheenRoughnessMapTransform: {
21559	                value: /*@__PURE__*/ new Matrix3()
21560	            },
21561	            transmission: {
21562	                value: 0
21563	            },
21564	            transmissionMap: {
21565	                value: null
21566	            },
21567	            transmissionMapTransform: {
21568	                value: /*@__PURE__*/ new Matrix3()
21569	            },
21570	            transmissionSamplerSize: {
21571	                value: /*@__PURE__*/ new Vector2()
21572	            },
21573	            transmissionSamplerMap: {
21574	                value: null
21575	            },
21576	            thickness: {
21577	                value: 0
21578	            },
21579	            thicknessMap: {
21580	                value: null
21581	            },
21582	            thicknessMapTransform: {
21583	                value: /*@__PURE__*/ new Matrix3()
21584	            },
21585	            attenuationDistance: {
21586	                value: 0
21587	            },
21588	            attenuationColor: {
21589	                value: /*@__PURE__*/ new Color(0x000000)
21590	            },
21591	            specularColor: {
21592	                value: /*@__PURE__*/ new Color(1, 1, 1)
21593	            },
21594	            specularColorMap: {
21595	                value: null
21596	            },
21597	            specularColorMapTransform: {
21598	                value: /*@__PURE__*/ new Matrix3()
21599	            },
21600	            specularIntensity: {
21601	                value: 1
21602	            },
21603	            specularIntensityMap: {
21604	                value: null
21605	            },
21606	            specularIntensityMapTransform: {
21607	                value: /*@__PURE__*/ new Matrix3()
21608	            },
21609	            anisotropyVector: {
21610	                value: /*@__PURE__*/ new Vector2()
21611	            },
21612	            anisotropyMap: {
21613	                value: null
21614	            },
21615	            anisotropyMapTransform: {
21616	                value: /*@__PURE__*/ new Matrix3()
21617	            }
21618	        }
21619	    ]),
21620	    vertexShader: ShaderChunk.meshphysical_vert,
21621	    fragmentShader: ShaderChunk.meshphysical_frag
21622	};
21623	const _rgb = {
21624	    r: 0,
21625	    b: 0,
21626	    g: 0
21627	};
21628	const _e1$1 = /*@__PURE__*/ new Euler();
21629	const _m1$1 = /*@__PURE__*/ new Matrix4();
21630	function WebGLBackground(renderer, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha) {
21631	    const clearColor = new Color(0x000000);
21632	    let clearAlpha = alpha === true ? 0 : 1;
21633	    let planeMesh;
21634	    let boxMesh;
21635	    let currentBackground = null;
21636	    let currentBackgroundVersion = 0;
21637	    let currentTonemapping = null;
21638	    function getBackground(scene) {
21639	        let background = scene.isScene === true ? scene.background : null;
21640	        if (background && background.isTexture) {
21641	            const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background
21642	            background = (usePMREM ? cubeuvmaps : cubemaps).get(background);
21643	        }
21644	        return background;
21645	    }
21646	    function render(scene) {
21647	        let forceClear = false;
21648	        const background = getBackground(scene);
21649	        if (background === null) {
21650	            setClear(clearColor, clearAlpha);
21651	        } else if (background && background.isColor) {
21652	            setClear(background, 1);
21653	            forceClear = true;
21654	        }
21655	        const environmentBlendMode = renderer.xr.getEnvironmentBlendMode();
21656	        if (environmentBlendMode === 'additive') {
21657	            state.buffers.color.setClear(0, 0, 0, 1, premultipliedAlpha);
21658	        } else if (environmentBlendMode === 'alpha-blend') {
21659	            state.buffers.color.setClear(0, 0, 0, 0, premultipliedAlpha);
21660	        }
21661	        if (renderer.autoClear || forceClear) {
21662	            // buffers might not be writable which is required to ensure a correct clear
21663	            state.buffers.depth.setTest(true);
21664	            state.buffers.depth.setMask(true);
21665	            state.buffers.color.setMask(true);
21666	            renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil);
21667	        }
21668	    }
21669	    function addToRenderList(renderList, scene) {
21670	        const background = getBackground(scene);
21671	        if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) {
21672	            if (boxMesh === undefined) {
21673	                boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({
21674	                    name: 'BackgroundCubeMaterial',
21675	                    uniforms: cloneUniforms(ShaderLib.backgroundCube.uniforms),
21676	                    vertexShader: ShaderLib.backgroundCube.vertexShader,
21677	                    fragmentShader: ShaderLib.backgroundCube.fragmentShader,
21678	                    side: BackSide,
21679	                    depthTest: false,
21680	                    depthWrite: false,
21681	                    fog: false
21682	                }));
21683	                boxMesh.geometry.deleteAttribute('normal');
21684	                boxMesh.geometry.deleteAttribute('uv');
21685	                boxMesh.onBeforeRender = function(renderer, scene, camera) {
21686	                    this.matrixWorld.copyPosition(camera.matrixWorld);
21687	                };
21688	                // add "envMap" material property so the renderer can evaluate it like for built-in materials
21689	                Object.defineProperty(boxMesh.material, 'envMap', {
21690	                    get: function() {
21691	                        return this.uniforms.envMap.value;
21692	                    }
21693	                });
21694	                objects.update(boxMesh);
21695	            }
21696	            _e1$1.copy(scene.backgroundRotation);
21697	            // accommodate left-handed frame
21698	            _e1$1.x *= -1;
21699	            _e1$1.y *= -1;
21700	            _e1$1.z *= -1;
21701	            if (background.isCubeTexture && background.isRenderTargetTexture === false) {
21702	                // environment maps which are not cube render targets or PMREMs follow a different convention
21703	                _e1$1.y *= -1;
21704	                _e1$1.z *= -1;
21705	            }
21706	            boxMesh.material.uniforms.envMap.value = background;
21707	            boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1;
21708	            boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
21709	            boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
21710	            boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4(_m1$1.makeRotationFromEuler(_e1$1));
21711	            boxMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer;
vendor: 4,172 bytes, lines 21712-21802
21712	            if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
21713	                boxMesh.material.needsUpdate = true;
21714	                currentBackground = background;
21715	                currentBackgroundVersion = background.version;
21716	                currentTonemapping = renderer.toneMapping;
21717	            }
21718	            boxMesh.layers.enableAll();
21719	            // push to the pre-sorted opaque render list
21720	            renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null);
21721	        } else if (background && background.isTexture) {
21722	            if (planeMesh === undefined) {
21723	                planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({
21724	                    name: 'BackgroundMaterial',
21725	                    uniforms: cloneUniforms(ShaderLib.background.uniforms),
21726	                    vertexShader: ShaderLib.background.vertexShader,
21727	                    fragmentShader: ShaderLib.background.fragmentShader,
21728	                    side: FrontSide,
21729	                    depthTest: false,
21730	                    depthWrite: false,
21731	                    fog: false
21732	                }));
21733	                planeMesh.geometry.deleteAttribute('normal');
21734	                // add "map" material property so the renderer can evaluate it like for built-in materials
21735	                Object.defineProperty(planeMesh.material, 'map', {
21736	                    get: function() {
21737	                        return this.uniforms.t2D.value;
21738	                    }
21739	                });
21740	                objects.update(planeMesh);
21741	            }
21742	            planeMesh.material.uniforms.t2D.value = background;
21743	            planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
21744	            planeMesh.material.toneMapped = ColorManagement.getTransfer(background.colorSpace) !== SRGBTransfer;
21745	            if (background.matrixAutoUpdate === true) {
21746	                background.updateMatrix();
21747	            }
21748	            planeMesh.material.uniforms.uvTransform.value.copy(background.matrix);
21749	            if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
21750	                planeMesh.material.needsUpdate = true;
21751	                currentBackground = background;
21752	                currentBackgroundVersion = background.version;
21753	                currentTonemapping = renderer.toneMapping;
21754	            }
21755	            planeMesh.layers.enableAll();
21756	            // push to the pre-sorted opaque render list
21757	            renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null);
21758	        }
21759	    }
21760	    function setClear(color, alpha) {
21761	        color.getRGB(_rgb, getUnlitUniformColorSpace(renderer));
21762	        state.buffers.color.setClear(_rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha);
21763	    }
21764	    function dispose() {
21765	        if (boxMesh !== undefined) {
21766	            boxMesh.geometry.dispose();
21767	            boxMesh.material.dispose();
21768	            boxMesh = undefined;
21769	        }
21770	        if (planeMesh !== undefined) {
21771	            planeMesh.geometry.dispose();
21772	            planeMesh.material.dispose();
21773	            planeMesh = undefined;
21774	        }
21775	    }
21776	    return {
21777	        getClearColor: function() {
21778	            return clearColor;
21779	        },
21780	        setClearColor: function(color, alpha = 1) {
21781	            clearColor.set(color);
21782	            clearAlpha = alpha;
21783	            setClear(clearColor, clearAlpha);
21784	        },
21785	        getClearAlpha: function() {
21786	            return clearAlpha;
21787	        },
21788	        setClearAlpha: function(alpha) {
21789	            clearAlpha = alpha;
21790	            setClear(clearColor, clearAlpha);
21791	        },
21792	        render: render,
21793	        addToRenderList: addToRenderList,
21794	        dispose: dispose
21795	    };
21796	}
21797	function WebGLBindingStates(gl, attributes) {
21798	    const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
21799	    const bindingStates = {};
21800	    const defaultState = createBindingState(null);
21801	    let currentState = defaultState;
21802	    let forceUpdate = false;
vendor: 19,799 bytes, lines 21803-22220
21803	    function setup(object, material, program, geometry, index) {
21804	        let updateBuffers = false;
21805	        const state = getBindingState(geometry, program, material);
21806	        if (currentState !== state) {
21807	            currentState = state;
21808	            bindVertexArrayObject(currentState.object);
21809	        }
21810	        updateBuffers = needsUpdate(object, geometry, program, index);
21811	        if (updateBuffers) saveCache(object, geometry, program, index);
21812	        if (index !== null) {
21813	            attributes.update(index, gl.ELEMENT_ARRAY_BUFFER);
21814	        }
21815	        if (updateBuffers || forceUpdate) {
21816	            forceUpdate = false;
21817	            setupVertexAttributes(object, material, program, geometry);
21818	            if (index !== null) {
21819	                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer);
21820	            }
21821	        }
21822	    }
21823	    function createVertexArrayObject() {
21824	        return gl.createVertexArray();
21825	    }
21826	    function bindVertexArrayObject(vao) {
21827	        return gl.bindVertexArray(vao);
21828	    }
21829	    function deleteVertexArrayObject(vao) {
21830	        return gl.deleteVertexArray(vao);
21831	    }
21832	    function getBindingState(geometry, program, material) {
21833	        const wireframe = material.wireframe === true;
21834	        let programMap = bindingStates[geometry.id];
21835	        if (programMap === undefined) {
21836	            programMap = {};
21837	            bindingStates[geometry.id] = programMap;
21838	        }
21839	        let stateMap = programMap[program.id];
21840	        if (stateMap === undefined) {
21841	            stateMap = {};
21842	            programMap[program.id] = stateMap;
21843	        }
21844	        let state = stateMap[wireframe];
21845	        if (state === undefined) {
21846	            state = createBindingState(createVertexArrayObject());
21847	            stateMap[wireframe] = state;
21848	        }
21849	        return state;
21850	    }
21851	    function createBindingState(vao) {
21852	        const newAttributes = [];
21853	        const enabledAttributes = [];
21854	        const attributeDivisors = [];
21855	        for(let i = 0; i < maxVertexAttributes; i++){
21856	            newAttributes[i] = 0;
21857	            enabledAttributes[i] = 0;
21858	            attributeDivisors[i] = 0;
21859	        }
21860	        return {
21861	            // for backward compatibility on non-VAO support browser
21862	            geometry: null,
21863	            program: null,
21864	            wireframe: false,
21865	            newAttributes: newAttributes,
21866	            enabledAttributes: enabledAttributes,
21867	            attributeDivisors: attributeDivisors,
21868	            object: vao,
21869	            attributes: {},
21870	            index: null
21871	        };
21872	    }
21873	    function needsUpdate(object, geometry, program, index) {
21874	        const cachedAttributes = currentState.attributes;
21875	        const geometryAttributes = geometry.attributes;
21876	        let attributesNum = 0;
21877	        const programAttributes = program.getAttributes();
21878	        for(const name in programAttributes){
21879	            const programAttribute = programAttributes[name];
21880	            if (programAttribute.location >= 0) {
21881	                const cachedAttribute = cachedAttributes[name];
21882	                let geometryAttribute = geometryAttributes[name];
21883	                if (geometryAttribute === undefined) {
21884	                    if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix;
21885	                    if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor;
21886	                }
21887	                if (cachedAttribute === undefined) return true;
21888	                if (cachedAttribute.attribute !== geometryAttribute) return true;
21889	                if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true;
21890	                attributesNum++;
21891	            }
21892	        }
21893	        if (currentState.attributesNum !== attributesNum) return true;
21894	        if (currentState.index !== index) return true;
21895	        return false;
21896	    }
21897	    function saveCache(object, geometry, program, index) {
21898	        const cache = {};
21899	        const attributes = geometry.attributes;
21900	        let attributesNum = 0;
21901	        const programAttributes = program.getAttributes();
21902	        for(const name in programAttributes){
21903	            const programAttribute = programAttributes[name];
21904	            if (programAttribute.location >= 0) {
21905	                let attribute = attributes[name];
21906	                if (attribute === undefined) {
21907	                    if (name === 'instanceMatrix' && object.instanceMatrix) attribute = object.instanceMatrix;
21908	                    if (name === 'instanceColor' && object.instanceColor) attribute = object.instanceColor;
21909	                }
21910	                const data = {};
21911	                data.attribute = attribute;
21912	                if (attribute && attribute.data) {
21913	                    data.data = attribute.data;
21914	                }
21915	                cache[name] = data;
21916	                attributesNum++;
21917	            }
21918	        }
21919	        currentState.attributes = cache;
21920	        currentState.attributesNum = attributesNum;
21921	        currentState.index = index;
21922	    }
21923	    function initAttributes() {
21924	        const newAttributes = currentState.newAttributes;
21925	        for(let i = 0, il = newAttributes.length; i < il; i++){
21926	            newAttributes[i] = 0;
21927	        }
21928	    }
21929	    function enableAttribute(attribute) {
21930	        enableAttributeAndDivisor(attribute, 0);
21931	    }
21932	    function enableAttributeAndDivisor(attribute, meshPerAttribute) {
21933	        const newAttributes = currentState.newAttributes;
21934	        const enabledAttributes = currentState.enabledAttributes;
21935	        const attributeDivisors = currentState.attributeDivisors;
21936	        newAttributes[attribute] = 1;
21937	        if (enabledAttributes[attribute] === 0) {
21938	            gl.enableVertexAttribArray(attribute);
21939	            enabledAttributes[attribute] = 1;
21940	        }
21941	        if (attributeDivisors[attribute] !== meshPerAttribute) {
21942	            gl.vertexAttribDivisor(attribute, meshPerAttribute);
21943	            attributeDivisors[attribute] = meshPerAttribute;
21944	        }
21945	    }
21946	    function disableUnusedAttributes() {
21947	        const newAttributes = currentState.newAttributes;
21948	        const enabledAttributes = currentState.enabledAttributes;
21949	        for(let i = 0, il = enabledAttributes.length; i < il; i++){
21950	            if (enabledAttributes[i] !== newAttributes[i]) {
21951	                gl.disableVertexAttribArray(i);
21952	                enabledAttributes[i] = 0;
21953	            }
21954	        }
21955	    }
21956	    function vertexAttribPointer(index, size, type, normalized, stride, offset, integer) {
21957	        if (integer === true) {
21958	            gl.vertexAttribIPointer(index, size, type, stride, offset);
21959	        } else {
21960	            gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
21961	        }
21962	    }
21963	    function setupVertexAttributes(object, material, program, geometry) {
21964	        initAttributes();
21965	        const geometryAttributes = geometry.attributes;
21966	        const programAttributes = program.getAttributes();
21967	        const materialDefaultAttributeValues = material.defaultAttributeValues;
21968	        for(const name in programAttributes){
21969	            const programAttribute = programAttributes[name];
21970	            if (programAttribute.location >= 0) {
21971	                let geometryAttribute = geometryAttributes[name];
21972	                if (geometryAttribute === undefined) {
21973	                    if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix;
21974	                    if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor;
21975	                }
21976	                if (geometryAttribute !== undefined) {
21977	                    const normalized = geometryAttribute.normalized;
21978	                    const size = geometryAttribute.itemSize;
21979	                    const attribute = attributes.get(geometryAttribute);
21980	                    // TODO Attribute may not be available on context restore
21981	                    if (attribute === undefined) continue;
21982	                    const buffer = attribute.buffer;
21983	                    const type = attribute.type;
21984	                    const bytesPerElement = attribute.bytesPerElement;
21985	                    // check for integer attributes
21986	                    const integer = type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType;
21987	                    if (geometryAttribute.isInterleavedBufferAttribute) {
21988	                        const data = geometryAttribute.data;
21989	                        const stride = data.stride;
21990	                        const offset = geometryAttribute.offset;
21991	                        if (data.isInstancedInterleavedBuffer) {
21992	                            for(let i = 0; i < programAttribute.locationSize; i++){
21993	                                enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute);
21994	                            }
21995	                            if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
21996	                                geometry._maxInstanceCount = data.meshPerAttribute * data.count;
21997	                            }
21998	                        } else {
21999	                            for(let i = 0; i < programAttribute.locationSize; i++){
22000	                                enableAttribute(programAttribute.location + i);
22001	                            }
22002	                        }
22003	                        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
22004	                        for(let i = 0; i < programAttribute.locationSize; i++){
22005	                            vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement, integer);
22006	                        }
22007	                    } else {
22008	                        if (geometryAttribute.isInstancedBufferAttribute) {
22009	                            for(let i = 0; i < programAttribute.locationSize; i++){
22010	                                enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute);
22011	                            }
22012	                            if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
22013	                                geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
22014	                            }
22015	                        } else {
22016	                            for(let i = 0; i < programAttribute.locationSize; i++){
22017	                                enableAttribute(programAttribute.location + i);
22018	                            }
22019	                        }
22020	                        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
22021	                        for(let i = 0; i < programAttribute.locationSize; i++){
22022	                            vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement, integer);
22023	                        }
22024	                    }
22025	                } else if (materialDefaultAttributeValues !== undefined) {
22026	                    const value = materialDefaultAttributeValues[name];
22027	                    if (value !== undefined) {
22028	                        switch(value.length){
22029	                            case 2:
22030	                                gl.vertexAttrib2fv(programAttribute.location, value);
22031	                                break;
22032	                            case 3:
22033	                                gl.vertexAttrib3fv(programAttribute.location, value);
22034	                                break;
22035	                            case 4:
22036	                                gl.vertexAttrib4fv(programAttribute.location, value);
22037	                                break;
22038	                            default:
22039	                                gl.vertexAttrib1fv(programAttribute.location, value);
22040	                        }
22041	                    }
22042	                }
22043	            }
22044	        }
22045	        disableUnusedAttributes();
22046	    }
22047	    function dispose() {
22048	        reset();
22049	        for(const geometryId in bindingStates){
22050	            const programMap = bindingStates[geometryId];
22051	            for(const programId in programMap){
22052	                const stateMap = programMap[programId];
22053	                for(const wireframe in stateMap){
22054	                    deleteVertexArrayObject(stateMap[wireframe].object);
22055	                    delete stateMap[wireframe];
22056	                }
22057	                delete programMap[programId];
22058	            }
22059	            delete bindingStates[geometryId];
22060	        }
22061	    }
22062	    function releaseStatesOfGeometry(geometry) {
22063	        if (bindingStates[geometry.id] === undefined) return;
22064	        const programMap = bindingStates[geometry.id];
22065	        for(const programId in programMap){
22066	            const stateMap = programMap[programId];
22067	            for(const wireframe in stateMap){
22068	                deleteVertexArrayObject(stateMap[wireframe].object);
22069	                delete stateMap[wireframe];
22070	            }
22071	            delete programMap[programId];
22072	        }
22073	        delete bindingStates[geometry.id];
22074	    }
22075	    function releaseStatesOfProgram(program) {
22076	        for(const geometryId in bindingStates){
22077	            const programMap = bindingStates[geometryId];
22078	            if (programMap[program.id] === undefined) continue;
22079	            const stateMap = programMap[program.id];
22080	            for(const wireframe in stateMap){
22081	                deleteVertexArrayObject(stateMap[wireframe].object);
22082	                delete stateMap[wireframe];
22083	            }
22084	            delete programMap[program.id];
22085	        }
22086	    }
22087	    function reset() {
22088	        resetDefaultState();
22089	        forceUpdate = true;
22090	        if (currentState === defaultState) return;
22091	        currentState = defaultState;
22092	        bindVertexArrayObject(currentState.object);
22093	    }
22094	    // for backward-compatibility
22095	    function resetDefaultState() {
22096	        defaultState.geometry = null;
22097	        defaultState.program = null;
22098	        defaultState.wireframe = false;
22099	    }
22100	    return {
22101	        setup: setup,
22102	        reset: reset,
22103	        resetDefaultState: resetDefaultState,
22104	        dispose: dispose,
22105	        releaseStatesOfGeometry: releaseStatesOfGeometry,
22106	        releaseStatesOfProgram: releaseStatesOfProgram,
22107	        initAttributes: initAttributes,
22108	        enableAttribute: enableAttribute,
22109	        disableUnusedAttributes: disableUnusedAttributes
22110	    };
22111	}
22112	function WebGLBufferRenderer(gl, extensions, info) {
22113	    let mode;
22114	    function setMode(value) {
22115	        mode = value;
22116	    }
22117	    function render(start, count) {
22118	        gl.drawArrays(mode, start, count);
22119	        info.update(count, mode, 1);
22120	    }
22121	    function renderInstances(start, count, primcount) {
22122	        if (primcount === 0) return;
22123	        gl.drawArraysInstanced(mode, start, count, primcount);
22124	        info.update(count, mode, primcount);
22125	    }
22126	    function renderMultiDraw(starts, counts, drawCount) {
22127	        if (drawCount === 0) return;
22128	        const extension = extensions.get('WEBGL_multi_draw');
22129	        extension.multiDrawArraysWEBGL(mode, starts, 0, counts, 0, drawCount);
22130	        let elementCount = 0;
22131	        for(let i = 0; i < drawCount; i++){
22132	            elementCount += counts[i];
22133	        }
22134	        info.update(elementCount, mode, 1);
22135	    }
22136	    function renderMultiDrawInstances(starts, counts, drawCount, primcount) {
22137	        if (drawCount === 0) return;
22138	        const extension = extensions.get('WEBGL_multi_draw');
22139	        if (extension === null) {
22140	            for(let i = 0; i < starts.length; i++){
22141	                renderInstances(starts[i], counts[i], primcount[i]);
22142	            }
22143	        } else {
22144	            extension.multiDrawArraysInstancedWEBGL(mode, starts, 0, counts, 0, primcount, 0, drawCount);
22145	            let elementCount = 0;
22146	            for(let i = 0; i < drawCount; i++){
22147	                elementCount += counts[i] * primcount[i];
22148	            }
22149	            info.update(elementCount, mode, 1);
22150	        }
22151	    }
22152	    //
22153	    this.setMode = setMode;
22154	    this.render = render;
22155	    this.renderInstances = renderInstances;
22156	    this.renderMultiDraw = renderMultiDraw;
22157	    this.renderMultiDrawInstances = renderMultiDrawInstances;
22158	}
22159	function WebGLCapabilities(gl, extensions, parameters, utils) {
22160	    let maxAnisotropy;
22161	    function getMaxAnisotropy() {
22162	        if (maxAnisotropy !== undefined) return maxAnisotropy;
22163	        if (extensions.has('EXT_texture_filter_anisotropic') === true) {
22164	            const extension = extensions.get('EXT_texture_filter_anisotropic');
22165	            maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
22166	        } else {
22167	            maxAnisotropy = 0;
22168	        }
22169	        return maxAnisotropy;
22170	    }
22171	    function textureFormatReadable(textureFormat) {
22172	        if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT)) {
22173	            return false;
22174	        }
22175	        return true;
22176	    }
22177	    function textureTypeReadable(textureType) {
22178	        const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || extensions.has('EXT_color_buffer_float'));
22179	        if (textureType !== UnsignedByteType && utils.convert(textureType) !== gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513)
22180	        textureType !== FloatType && !halfFloatSupportedByExt) {
22181	            return false;
22182	        }
22183	        return true;
22184	    }
22185	    function getMaxPrecision(precision) {
22186	        if (precision === 'highp') {
22187	            if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
22188	                return 'highp';
22189	            }
22190	            precision = 'mediump';
22191	        }
22192	        if (precision === 'mediump') {
22193	            if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
22194	                return 'mediump';
22195	            }
22196	        }
22197	        return 'lowp';
22198	    }
22199	    let precision = parameters.precision !== undefined ? parameters.precision : 'highp';
22200	    const maxPrecision = getMaxPrecision(precision);
22201	    if (maxPrecision !== precision) {
22202	        console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.');
22203	        precision = maxPrecision;
22204	    }
22205	    const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
22206	    const reverseDepthBuffer = parameters.reverseDepthBuffer === true && extensions.has('EXT_clip_control');
22207	    const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
22208	    const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
22209	    const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
22210	    const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
22211	    const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
22212	    const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
22213	    const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS);
22214	    const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
22215	    const vertexTextures = maxVertexTextures > 0;
22216	    const maxSamples = gl.getParameter(gl.MAX_SAMPLES);
22217	    return {
22218	        isWebGL2: true,
22219	        getMaxAnisotropy: getMaxAnisotropy,
22220	        getMaxPrecision: getMaxPrecision,
vendor: 1,977 bytes, lines 22221-22267
22221	        textureFormatReadable: textureFormatReadable,
22222	        textureTypeReadable: textureTypeReadable,
22223	        precision: precision,
22224	        logarithmicDepthBuffer: logarithmicDepthBuffer,
22225	        reverseDepthBuffer: reverseDepthBuffer,
22226	        maxTextures: maxTextures,
22227	        maxVertexTextures: maxVertexTextures,
22228	        maxTextureSize: maxTextureSize,
22229	        maxCubemapSize: maxCubemapSize,
22230	        maxAttributes: maxAttributes,
22231	        maxVertexUniforms: maxVertexUniforms,
22232	        maxVaryings: maxVaryings,
22233	        maxFragmentUniforms: maxFragmentUniforms,
22234	        vertexTextures: vertexTextures,
22235	        maxSamples: maxSamples
22236	    };
22237	}
22238	function WebGLClipping(properties) {
22239	    const scope = this;
22240	    let globalState = null, numGlobalPlanes = 0, localClippingEnabled = false, renderingShadows = false;
22241	    const plane = new Plane(), viewNormalMatrix = new Matrix3(), uniform = {
22242	        value: null,
22243	        needsUpdate: false
22244	    };
22245	    this.uniform = uniform;
22246	    this.numPlanes = 0;
22247	    this.numIntersection = 0;
22248	    this.init = function(planes, enableLocalClipping) {
22249	        const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to
22250	        // run another frame in order to reset the state:
22251	        numGlobalPlanes !== 0 || localClippingEnabled;
22252	        localClippingEnabled = enableLocalClipping;
22253	        numGlobalPlanes = planes.length;
22254	        return enabled;
22255	    };
22256	    this.beginShadows = function() {
22257	        renderingShadows = true;
22258	        projectPlanes(null);
22259	    };
22260	    this.endShadows = function() {
22261	        renderingShadows = false;
22262	    };
22263	    this.setGlobalState = function(planes, camera) {
22264	        globalState = projectPlanes(planes, camera, 0);
22265	    };
22266	    this.setState = function(material, camera, useCache) {
22267	        const planes = material.clippingPlanes, clipIntersection = material.clipIntersection, clipShadows = material.clipSh
vendor: 4,466 bytes, lines 22267-22370
22267adows;
22268	        const materialProperties = properties.get(material);
22269	        if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) {
22270	            // there's no local clipping
22271	            if (renderingShadows) {
22272	                // there's no global clipping
22273	                projectPlanes(null);
22274	            } else {
22275	                resetGlobalState();
22276	            }
22277	        } else {
22278	            const nGlobal = renderingShadows ? 0 : numGlobalPlanes, lGlobal = nGlobal * 4;
22279	            let dstArray = materialProperties.clippingState || null;
22280	            uniform.value = dstArray; // ensure unique state
22281	            dstArray = projectPlanes(planes, camera, lGlobal, useCache);
22282	            for(let i = 0; i !== lGlobal; ++i){
22283	                dstArray[i] = globalState[i];
22284	            }
22285	            materialProperties.clippingState = dstArray;
22286	            this.numIntersection = clipIntersection ? this.numPlanes : 0;
22287	            this.numPlanes += nGlobal;
22288	        }
22289	    };
22290	    function resetGlobalState() {
22291	        if (uniform.value !== globalState) {
22292	            uniform.value = globalState;
22293	            uniform.needsUpdate = numGlobalPlanes > 0;
22294	        }
22295	        scope.numPlanes = numGlobalPlanes;
22296	        scope.numIntersection = 0;
22297	    }
22298	    function projectPlanes(planes, camera, dstOffset, skipTransform) {
22299	        const nPlanes = planes !== null ? planes.length : 0;
22300	        let dstArray = null;
22301	        if (nPlanes !== 0) {
22302	            dstArray = uniform.value;
22303	            if (skipTransform !== true || dstArray === null) {
22304	                const flatSize = dstOffset + nPlanes * 4, viewMatrix = camera.matrixWorldInverse;
22305	                viewNormalMatrix.getNormalMatrix(viewMatrix);
22306	                if (dstArray === null || dstArray.length < flatSize) {
22307	                    dstArray = new Float32Array(flatSize);
22308	                }
22309	                for(let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4){
22310	                    plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix);
22311	                    plane.normal.toArray(dstArray, i4);
22312	                    dstArray[i4 + 3] = plane.constant;
22313	                }
22314	            }
22315	            uniform.value = dstArray;
22316	            uniform.needsUpdate = true;
22317	        }
22318	        scope.numPlanes = nPlanes;
22319	        scope.numIntersection = 0;
22320	        return dstArray;
22321	    }
22322	}
22323	function WebGLCubeMaps(renderer) {
22324	    let cubemaps = new WeakMap();
22325	    function mapTextureMapping(texture, mapping) {
22326	        if (mapping === EquirectangularReflectionMapping) {
22327	            texture.mapping = CubeReflectionMapping;
22328	        } else if (mapping === EquirectangularRefractionMapping) {
22329	            texture.mapping = CubeRefractionMapping;
22330	        }
22331	        return texture;
22332	    }
22333	    function get(texture) {
22334	        if (texture && texture.isTexture) {
22335	            const mapping = texture.mapping;
22336	            if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) {
22337	                if (cubemaps.has(texture)) {
22338	                    const cubemap = cubemaps.get(texture).texture;
22339	                    return mapTextureMapping(cubemap, texture.mapping);
22340	                } else {
22341	                    const image = texture.image;
22342	                    if (image && image.height > 0) {
22343	                        const renderTarget = new WebGLCubeRenderTarget(image.height);
22344	                        renderTarget.fromEquirectangularTexture(renderer, texture);
22345	                        cubemaps.set(texture, renderTarget);
22346	                        texture.addEventListener('dispose', onTextureDispose);
22347	                        return mapTextureMapping(renderTarget.texture, texture.mapping);
22348	                    } else {
22349	                        // image not yet ready. try the conversion next frame
22350	                        return null;
22351	                    }
22352	                }
22353	            }
22354	        }
22355	        return texture;
22356	    }
22357	    function onTextureDispose(event) {
22358	        const texture = event.target;
22359	        texture.removeEventListener('dispose', onTextureDispose);
22360	        const cubemap = cubemaps.get(texture);
22361	        if (cubemap !== undefined) {
22362	            cubemaps.delete(texture);
22363	            cubemap.dispose();
22364	        }
22365	    }
22366	    function dispose() {
22367	        cubemaps = new WeakMap();
22368	    }
22369	    return {
22370	        get: get,
22371	        dispose: dispose
22372	    };
22373	}
22374	const LOD_MIN = 4;
22375	// The standard deviations (radians) associated with the extra mips. These are
22376	// chosen to approximate a Trowbridge-Reitz distribution function times the
22377	// geometric shadowing function. These sigma values squared must match the
22378	// variance #defines in cube_uv_reflection_fragment.glsl.js.
22379	const EXTRA_LOD_SIGMA = [
22380	    0.125,
22381	    0.215,
22382	    0.35,
22383	    0.446,
22384	    0.526,
22385	    0.582
22386	];
22387	// The maximum length of the blur for loop. Smaller sigmas will use fewer
22388	// samples and exit early, but not recompile the shader.
22389	const MAX_SAMPLES$1 = 20;
22390	const _flatCamera = /*@__PURE__*/ new OrthographicCamera();
22391	const _clearColor = /*@__PURE__*/ new Color();
22392	let _oldTarget = null;
22393	let _oldActiveCubeFace = 0;
22394	let _oldActiveMipmapLevel = 0;
22395	let _oldXrEnabled = false;
22396	// Golden Ratio
22397	const PHI = (1 + Math.sqrt(5)) / 2;
22398	const INV_PHI = 1 / PHI;
22399	// Vertices of a dodecahedron (except the opposites, which represent the
22400	// same axis), used as axis directions evenly spread on a sphere.
22401	const _axisDirections = [
22402	    /*@__PURE__*/ new Vector3(-PHI, INV_PHI, 0),
22403	    /*@__PURE__*/ new Vector3(PHI, INV_PHI, 0),
22404	    /*@__PURE__*/ new Vector3(-INV_PHI, 0, PHI),
22405	    /*@__PURE__*/ new Vector3(INV_PHI, 0, PHI),
22406	    /*@__PURE__*/ new Vector3(0, PHI, -INV_PHI),
22407	    /*@__PURE__*/ new Vector3(0, PHI, INV_PHI),
22408	    /*@__PURE__*/ new Vector3(-1, 1, -1),
22409	    /*@__PURE__*/ new Vector3(1, 1, -1),
22410	    /*@__PURE__*/ new Vector3(-1, 1, 1),
22411	    /*@__PURE__*/ new Vector3(1, 1, 1)
22412	];
22413	const _origin = /*@__PURE__*/ new Vector3();
22414	/**
22415	 * This class generates a Prefiltered, Mipmapped Radiance Environment Map
22416	 * (PMREM) from a cubeMap environment texture. This allows different levels of
22417	 * blur to be quickly accessed based on material roughness. It is packed into a
22418	 * special CubeUV format that allows us to perform custom interpolation so that
22419	 * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
22420	 * chain, it only goes down to the LOD_MIN level (above), and then creates extra
22421	 * even more filtered 'mips' at the same LOD_MIN resolution, associated with
22422	 * higher roughness levels. In this way we maintain resolution to smoothly
22423	 * interpolate diffuse lighting while limiting sampling computation.
22424	 *
22425	 * Paper: Fast, Accurate Image-Based Lighting
22426	 * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view
22427	*/ class PMREMGenerator {
22428	    /**
22429		 * Generates a PMREM from a supplied Scene, which can be faster than using an
22430		 * image if networking bandwidth is low. Optional sigma specifies a blur radius
22431		 * in radians to be applied to the scene before PMREM generation. Optional near
22432		 * and far planes ensure the scene is rendered in its entirety.
22433		 *
22434		 * @param {Scene} scene
22435		 * @param {number} sigma
22436		 * @param {number} near
22437		 * @param {number} far
22438		 * @param {Object} [options={}]
22439		 * @return {WebGLRenderTarget}
22440		 */ fromScene(scene, sigma = 0, near = 0.1, far = 100, options = {}) {
22441	        const { size = 256, position = _origin } = options;
22442	        _oldTarget = this._renderer.getRenderTarget();
22443	        _oldActiveCubeFace = this._renderer.getActiveCubeFace();
22444	        _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
22445	        _oldXrEnabled = this._renderer.xr.enabled;
22446	        this._renderer.xr.enabled = false;
22447	        this._setSize(size);
22448	        const cubeUVRenderTarget = this._allocateTargets();
22449	        cubeUVRenderTarget.depthBuffer = true;
22450	        this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget, position);
22451	        if (sigma > 0) {
22452	            this._blur(cubeUVRenderTarget, 0, 0, sigma);
22453	        }
22454	        this._applyPMREM(cubeUVRenderTarget);
22455	        this._cleanup(cubeUVRenderTarget);
22456	        return cubeUVRenderTarget;
22457	    }
22458	    /**
22459		 * Generates a PMREM from an equirectangular texture, which can be either LDR
22460		 * or HDR. The ideal input image size is 1k (1024 x 512),
22461		 * as this matches best with the 256 x 256 cubemap output.
22462		 * The smallest supported equirectangular image size is 64 x 32.
22463		 *
22464		 * @param {Texture} equirectangular
22465		 * @param {?WebGLRenderTarget} [renderTarget=null] - Optional render target.
22466		 * @return {WebGLRenderTarget}
22467		 */ fromEquirectangular(equirectangular, renderTarget = null) {
22468	        return this._fromTexture(equirectangular, renderTarget);
22469	    }
22470	    /**
22471		 * Generates a PMREM from an cubemap texture, which can be either LDR
22472		 * or HDR. The ideal input cube size is 256 x 256,
22473		 * as this matches best with the 256 x 256 cubemap output.
22474		 * The smallest supported cube size is 16 x 16.
22475		 *
22476		 * @param {Texture} cubemap
22477		 * @param {null} [renderTarget=null] - Optional render target.
22478		 * @return {WebGLRenderTarget}
22479		 */ fromCubemap(cubemap, renderTarget = null) {
22480	        return this._fromTexture(cubemap, renderTarget);
22481	    }
22482	    /**
22483		 * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
22484		 * your texture's network fetch for increased concurrency.
22485		 */ compileCubemapShader() {
22486	        if (this._cubemapMaterial === null) {
22487	            this._cubemapMaterial = _getCubemapMaterial();
22488	            this._compileMaterial(this._cubemapMaterial);
22489	        }
22490	    }
22491	    /**
22492		 * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
22493		 * your texture's network fetch for increased concurrency.
22494		 */ compileEquirectangularShader() {
22495	        if (this._equirectMaterial === null) {
22496	            this._equirectMaterial = _getEquirectMaterial();
22497	            this._compileMaterial(this._equirectMaterial);
22498	        }
22499	    }
22500	    /**
22501		 * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
22502		 * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
22503		 * one of them will cause any others to also become unusable.
22504		 */ dispose() {
22505	        this._dispose();
22506	        if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose();
22507	        if (this._equirectMaterial !== null) this._equirectMaterial.dispose();
22508	    }
22509	    // private interface
22510	    _setSize(cubeSize) {
22511	        this._lodMax = Math.floor(Math.log2(cubeSize));
22512	        this._cubeSize = Math.pow(2, this._lodMax);
22513	    }
22514	    _dispose() {
22515	        if (this._blurMaterial !== null) this._blurMaterial.dispose();
22516	        if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose();
22517	        for(let i = 0; i < this._lodPlanes.length; i++){
22518	            this._lodPlanes[i].dispose();
22519	        }
22520	    }
22521	    _cleanup(outputTarget) {
22522	        this._renderer.setRenderTarget(_oldTarget, _oldActiveCubeFace, _oldActiveMipmapLevel);
22523	        this._renderer.xr.enabled = _oldXrEnabled;
22524	        outputTarget.scissorTest = false;
vendor: 3,102 bytes, lines 22525-22598
22525	        _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height);
22526	    }
22527	    _fromTexture(texture, renderTarget) {
22528	        if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) {
22529	            this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width);
22530	        } else {
22531	            this._setSize(texture.image.width / 4);
22532	        }
22533	        _oldTarget = this._renderer.getRenderTarget();
22534	        _oldActiveCubeFace = this._renderer.getActiveCubeFace();
22535	        _oldActiveMipmapLevel = this._renderer.getActiveMipmapLevel();
22536	        _oldXrEnabled = this._renderer.xr.enabled;
22537	        this._renderer.xr.enabled = false;
22538	        const cubeUVRenderTarget = renderTarget || this._allocateTargets();
22539	        this._textureToCubeUV(texture, cubeUVRenderTarget);
22540	        this._applyPMREM(cubeUVRenderTarget);
22541	        this._cleanup(cubeUVRenderTarget);
22542	        return cubeUVRenderTarget;
22543	    }
22544	    _allocateTargets() {
22545	        const width = 3 * Math.max(this._cubeSize, 16 * 7);
22546	        const height = 4 * this._cubeSize;
22547	        const params = {
22548	            magFilter: LinearFilter,
22549	            minFilter: LinearFilter,
22550	            generateMipmaps: false,
22551	            type: HalfFloatType,
22552	            format: RGBAFormat,
22553	            colorSpace: LinearSRGBColorSpace,
22554	            depthBuffer: false
22555	        };
22556	        const cubeUVRenderTarget = _createRenderTarget(width, height, params);
22557	        if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width || this._pingPongRenderTarget.height !== height) {
22558	            if (this._pingPongRenderTarget !== null) {
22559	                this._dispose();
22560	            }
22561	            this._pingPongRenderTarget = _createRenderTarget(width, height, params);
22562	            const { _lodMax } = this;
22563	            ({ sizeLods: this._sizeLods, lodPlanes: this._lodPlanes, sigmas: this._sigmas } = _createPlanes(_lodMax));
22564	            this._blurMaterial = _getBlurShader(_lodMax, width, height);
22565	        }
22566	        return cubeUVRenderTarget;
22567	    }
22568	    _compileMaterial(material) {
22569	        const tmpMesh = new Mesh(this._lodPlanes[0], material);
22570	        this._renderer.compile(tmpMesh, _flatCamera);
22571	    }
22572	    _sceneToCubeUV(scene, near, far, cubeUVRenderTarget, position) {
22573	        const fov = 90;
22574	        const aspect = 1;
22575	        const cubeCamera = new PerspectiveCamera(fov, aspect, near, far);
22576	        const upSign = [
22577	            1,
22578	            -1,
22579	            1,
22580	            1,
22581	            1,
22582	            1
22583	        ];
22584	        const forwardSign = [
22585	            1,
22586	            1,
22587	            1,
22588	            -1,
22589	            -1,
22590	            -1
22591	        ];
22592	        const renderer = this._renderer;
22593	        const originalAutoClear = renderer.autoClear;
22594	        const toneMapping = renderer.toneMapping;
22595	        renderer.getClearColor(_clearColor);
22596	        renderer.toneMapping = NoToneMapping;
22597	        renderer.autoClear = false;
22598	        const backgroundMaterial = new MeshBasicMaterial({
22599	            name: 'PMREM.Background',
22600	            side: BackSide,
22601	            depthWrite: false,
22602	            depthTest: false
22603	        });
22604	        const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial);
22605	        let useSolidColor = false;
22606	        const background = scene.background;
22607	        if (background) {
22608	            if (background.isColor) {
22609	                backgroundMaterial.color.copy(background);
22610	                scene.background = null;
22611	                useSolidColor = true;
22612	            }
22613	        } else {
22614	            backgroundMaterial.color.copy(_clearColor);
22615	            useSolidColor = true;
22616	        }
22617	        for(let i = 0; i < 6; i++){
22618	            const col = i % 3;
22619	            if (col === 0) {
22620	                cubeCamera.up.set(0, upSign[i], 0);
22621	                cubeCamera.position.set(position.x, position.y, position.z);
22622	                cubeCamera.lookAt(position.x + forwardSign[i], position.y, position.z);
22623	            } else if (col === 1) {
22624	                cubeCamera.up.set(0, 0, upSign[i]);
22625	                cubeCamera.position.set(position.x, position.y, position.z);
22626	                cubeCamera.lookAt(position.x, position.y + forwardSign[i], position.z);
22627	            } else {
22628	                cubeCamera.up.set(0, upSign[i], 0);
22629	                cubeCamera.position.set(position.x, position.y, position.z);
22630	                cubeCamera.lookAt(position.x, position.y, position.z + forwardSign[i]);
22631	            }
22632	            const size = this._cubeSize;
22633	            _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size);
22634	            renderer.setRenderTarget(cubeUVRenderTarget);
22635	            if (useSolidColor) {
22636	                renderer.render(backgroundBox, cubeCamera);
22637	            }
22638	            renderer.render(scene, cubeCamera);
22639	        }
22640	        backgroundBox.geometry.dispose();
22641	        backgroundBox.material.dispose();
22642	        renderer.toneMapping = toneMapping;
22643	        renderer.autoClear = originalAutoClear;
22644	        scene.background = background;
22645	    }
22646	    _textureToCubeUV(texture, cubeUVRenderTarget) {
22647	        const renderer = this._renderer;
22648	        const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping;
22649	        if (isCubeTexture) {
22650	            if (this._cubemapMaterial === null) {
22651	                this._cubemapMaterial = _getCubemapMaterial();
22652	            }
22653	            this._cubemapMaterial.uniforms.flipEnvMap.value = texture.isRenderTargetTexture === false ? -1 : 1;
22654	        } else {
22655	            if (this._equirectMaterial === null) {
22656	                this._equirectMaterial = _getEquirectMaterial();
22657	            }
22658	        }
22659	        const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;
22660	        const mesh = new Mesh(this._lodPlanes[0], material);
22661	        const uniforms = material.uniforms;
22662	        uniforms['envMap'].value = texture;
22663	        const size = this._cubeSize;
22664	        _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size);
22665	        renderer.setRenderTarget(cubeUVRenderTarget);
22666	        renderer.render(mesh, _flatCamera);
22667	    }
22668	    _applyPMREM(cubeUVRenderTarget) {
22669	        const renderer = this._renderer;
22670	        const autoClear = renderer.autoClear;
22671	        renderer.autoClear = false;
22672	        const n = this._lodPlanes.length;
22673	        for(let i = 1; i < n; i++){
22674	            const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]);
22675	            const poleAxis = _axisDirections[(n - i - 1) % _axisDirections.length];
22676	            this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis);
22677	        }
22678	        renderer.autoClear = autoClear;
22679	    }
22680	    /**
22681		 * This is a two-pass Gaussian blur for a cubemap. Normally this is done
22682		 * vertically and horizontally, but this breaks down on a cube. Here we apply
22683		 * the blur latitudinally (around the poles), and then longitudinally (towards
22684		 * the poles) to approximate the orthogonally-separable blur. It is least
22685		 * accurate at the poles, but still does a decent job.
22686		 *
22687		 * @param {WebGLRenderTarget} cubeUVRenderTarget
22688		 * @param {number} lodIn
22689		 * @param {number} lodOut
22690		 * @param {number} sigma
22691		 * @param {Vector3} [poleAxis]
22692		 */ _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
22693	        const pingPongRenderTarget = this._pingPongRenderTarget;
22694	        this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis);
22695	        this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis);
22696	    }
22697	    _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) {
22698	        const renderer = this._renderer;
22699	        const blurMaterial = this._blurMaterial;
22700	        if (direction !== 'latitudinal' && direction !== 'longitudinal') {
22701	            console.error('blur direction must be either latitudinal or longitudinal!');
22702	        }
22703	        // Number of standard deviations at which to cut off the discrete approximation.
22704	        const STANDARD_DEVIATIONS = 3;
22705	        const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial);
22706	        const blurUniforms = blurMaterial.uniforms;
22707	        const pixels = this._sizeLods[lodIn] - 1;
vendor: 57,040 bytes, lines 22708-24364
22708	        const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES$1 - 1);
22709	        const sigmaPixels = sigmaRadians / radiansPerPixel;
22710	        const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES$1;
22711	        if (samples > MAX_SAMPLES$1) {
22712	            console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES$1}`);
22713	        }
22714	        const weights = [];
22715	        let sum = 0;
22716	        for(let i = 0; i < MAX_SAMPLES$1; ++i){
22717	            const x = i / sigmaPixels;
22718	            const weight = Math.exp(-x * x / 2);
22719	            weights.push(weight);
22720	            if (i === 0) {
22721	                sum += weight;
22722	            } else if (i < samples) {
22723	                sum += 2 * weight;
22724	            }
22725	        }
22726	        for(let i = 0; i < weights.length; i++){
22727	            weights[i] = weights[i] / sum;
22728	        }
22729	        blurUniforms['envMap'].value = targetIn.texture;
22730	        blurUniforms['samples'].value = samples;
22731	        blurUniforms['weights'].value = weights;
22732	        blurUniforms['latitudinal'].value = direction === 'latitudinal';
22733	        if (poleAxis) {
22734	            blurUniforms['poleAxis'].value = poleAxis;
22735	        }
22736	        const { _lodMax } = this;
22737	        blurUniforms['dTheta'].value = radiansPerPixel;
22738	        blurUniforms['mipInt'].value = _lodMax - lodIn;
22739	        const outputSize = this._sizeLods[lodOut];
22740	        const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0);
22741	        const y = 4 * (this._cubeSize - outputSize);
22742	        _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize);
22743	        renderer.setRenderTarget(targetOut);
22744	        renderer.render(blurMesh, _flatCamera);
22745	    }
22746	    constructor(renderer){
22747	        this._renderer = renderer;
22748	        this._pingPongRenderTarget = null;
22749	        this._lodMax = 0;
22750	        this._cubeSize = 0;
22751	        this._lodPlanes = [];
22752	        this._sizeLods = [];
22753	        this._sigmas = [];
22754	        this._blurMaterial = null;
22755	        this._cubemapMaterial = null;
22756	        this._equirectMaterial = null;
22757	        this._compileMaterial(this._blurMaterial);
22758	    }
22759	}
22760	function _createPlanes(lodMax) {
22761	    const lodPlanes = [];
22762	    const sizeLods = [];
22763	    const sigmas = [];
22764	    let lod = lodMax;
22765	    const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
22766	    for(let i = 0; i < totalLods; i++){
22767	        const sizeLod = Math.pow(2, lod);
22768	        sizeLods.push(sizeLod);
22769	        let sigma = 1.0 / sizeLod;
22770	        if (i > lodMax - LOD_MIN) {
22771	            sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1];
22772	        } else if (i === 0) {
22773	            sigma = 0;
22774	        }
22775	        sigmas.push(sigma);
22776	        const texelSize = 1.0 / (sizeLod - 2);
22777	        const min = -texelSize;
22778	        const max = 1 + texelSize;
22779	        const uv1 = [
22780	            min,
22781	            min,
22782	            max,
22783	            min,
22784	            max,
22785	            max,
22786	            min,
22787	            min,
22788	            max,
22789	            max,
22790	            min,
22791	            max
22792	        ];
22793	        const cubeFaces = 6;
22794	        const vertices = 6;
22795	        const positionSize = 3;
22796	        const uvSize = 2;
22797	        const faceIndexSize = 1;
22798	        const position = new Float32Array(positionSize * vertices * cubeFaces);
22799	        const uv = new Float32Array(uvSize * vertices * cubeFaces);
22800	        const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces);
22801	        for(let face = 0; face < cubeFaces; face++){
22802	            const x = face % 3 * 2 / 3 - 1;
22803	            const y = face > 2 ? 0 : -1;
22804	            const coordinates = [
22805	                x,
22806	                y,
22807	                0,
22808	                x + 2 / 3,
22809	                y,
22810	                0,
22811	                x + 2 / 3,
22812	                y + 1,
22813	                0,
22814	                x,
22815	                y,
22816	                0,
22817	                x + 2 / 3,
22818	                y + 1,
22819	                0,
22820	                x,
22821	                y + 1,
22822	                0
22823	            ];
22824	            position.set(coordinates, positionSize * vertices * face);
22825	            uv.set(uv1, uvSize * vertices * face);
22826	            const fill = [
22827	                face,
22828	                face,
22829	                face,
22830	                face,
22831	                face,
22832	                face
22833	            ];
22834	            faceIndex.set(fill, faceIndexSize * vertices * face);
22835	        }
22836	        const planes = new BufferGeometry();
22837	        planes.setAttribute('position', new BufferAttribute(position, positionSize));
22838	        planes.setAttribute('uv', new BufferAttribute(uv, uvSize));
22839	        planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize));
22840	        lodPlanes.push(planes);
22841	        if (lod > LOD_MIN) {
22842	            lod--;
22843	        }
22844	    }
22845	    return {
22846	        lodPlanes,
22847	        sizeLods,
22848	        sigmas
22849	    };
22850	}
22851	function _createRenderTarget(width, height, params) {
22852	    const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params);
22853	    cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
22854	    cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
22855	    cubeUVRenderTarget.scissorTest = true;
22856	    return cubeUVRenderTarget;
22857	}
22858	function _setViewport(target, x, y, width, height) {
22859	    target.viewport.set(x, y, width, height);
22860	    target.scissor.set(x, y, width, height);
22861	}
22862	function _getBlurShader(lodMax, width, height) {
22863	    const weights = new Float32Array(MAX_SAMPLES$1);
22864	    const poleAxis = new Vector3(0, 1, 0);
22865	    const shaderMaterial = new ShaderMaterial({
22866	        name: 'SphericalGaussianBlur',
22867	        defines: {
22868	            'n': MAX_SAMPLES$1,
22869	            'CUBEUV_TEXEL_WIDTH': 1.0 / width,
22870	            'CUBEUV_TEXEL_HEIGHT': 1.0 / height,
22871	            'CUBEUV_MAX_MIP': `${lodMax}.0`
22872	        },
22873	        uniforms: {
22874	            'envMap': {
22875	                value: null
22876	            },
22877	            'samples': {
22878	                value: 1
22879	            },
22880	            'weights': {
22881	                value: weights
22882	            },
22883	            'latitudinal': {
22884	                value: false
22885	            },
22886	            'dTheta': {
22887	                value: 0
22888	            },
22889	            'mipInt': {
22890	                value: 0
22891	            },
22892	            'poleAxis': {
22893	                value: poleAxis
22894	            }
22895	        },
22896	        vertexShader: _getCommonVertexShader(),
22897	        fragmentShader: /* glsl */ `
22898
22899			precision mediump float;
22900			precision mediump int;
22901
22902			varying vec3 vOutputDirection;
22903
22904			uniform sampler2D envMap;
22905			uniform int samples;
22906			uniform float weights[ n ];
22907			uniform bool latitudinal;
22908			uniform float dTheta;
22909			uniform float mipInt;
22910			uniform vec3 poleAxis;
22911
22912			#define ENVMAP_TYPE_CUBE_UV
22913			#include <cube_uv_reflection_fragment>
22914
22915			vec3 getSample( float theta, vec3 axis ) {
22916
22917				float cosTheta = cos( theta );
22918				// Rodrigues' axis-angle rotation
22919				vec3 sampleDirection = vOutputDirection * cosTheta
22920					+ cross( axis, vOutputDirection ) * sin( theta )
22921					+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
22922
22923				return bilinearCubeUV( envMap, sampleDirection, mipInt );
22924
22925			}
22926
22927			void main() {
22928
22929				vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
22930
22931				if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
22932
22933					axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
22934
22935				}
22936
22937				axis = normalize( axis );
22938
22939				gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
22940				gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
22941
22942				for ( int i = 1; i < n; i++ ) {
22943
22944					if ( i >= samples ) {
22945
22946						break;
22947
22948					}
22949
22950					float theta = dTheta * float( i );
22951					gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
22952					gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
22953
22954				}
22955
22956			}
22957		`,
22958	        blending: NoBlending,
22959	        depthTest: false,
22960	        depthWrite: false
22961	    });
22962	    return shaderMaterial;
22963	}
22964	function _getEquirectMaterial() {
22965	    return new ShaderMaterial({
22966	        name: 'EquirectangularToCubeUV',
22967	        uniforms: {
22968	            'envMap': {
22969	                value: null
22970	            }
22971	        },
22972	        vertexShader: _getCommonVertexShader(),
22973	        fragmentShader: /* glsl */ `
22974
22975			precision mediump float;
22976			precision mediump int;
22977
22978			varying vec3 vOutputDirection;
22979
22980			uniform sampler2D envMap;
22981
22982			#include <common>
22983
22984			void main() {
22985
22986				vec3 outputDirection = normalize( vOutputDirection );
22987				vec2 uv = equirectUv( outputDirection );
22988
22989				gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );
22990
22991			}
22992		`,
22993	        blending: NoBlending,
22994	        depthTest: false,
22995	        depthWrite: false
22996	    });
22997	}
22998	function _getCubemapMaterial() {
22999	    return new ShaderMaterial({
23000	        name: 'CubemapToCubeUV',
23001	        uniforms: {
23002	            'envMap': {
23003	                value: null
23004	            },
23005	            'flipEnvMap': {
23006	                value: -1
23007	            }
23008	        },
23009	        vertexShader: _getCommonVertexShader(),
23010	        fragmentShader: /* glsl */ `
23011
23012			precision mediump float;
23013			precision mediump int;
23014
23015			uniform float flipEnvMap;
23016
23017			varying vec3 vOutputDirection;
23018
23019			uniform samplerCube envMap;
23020
23021			void main() {
23022
23023				gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );
23024
23025			}
23026		`,
23027	        blending: NoBlending,
23028	        depthTest: false,
23029	        depthWrite: false
23030	    });
23031	}
23032	function _getCommonVertexShader() {
23033	    return /* glsl */ `
23034
23035		precision mediump float;
23036		precision mediump int;
23037
23038		attribute float faceIndex;
23039
23040		varying vec3 vOutputDirection;
23041
23042		// RH coordinate system; PMREM face-indexing convention
23043		vec3 getDirection( vec2 uv, float face ) {
23044
23045			uv = 2.0 * uv - 1.0;
23046
23047			vec3 direction = vec3( uv, 1.0 );
23048
23049			if ( face == 0.0 ) {
23050
23051				direction = direction.zyx; // ( 1, v, u ) pos x
23052
23053			} else if ( face == 1.0 ) {
23054
23055				direction = direction.xzy;
23056				direction.xz *= -1.0; // ( -u, 1, -v ) pos y
23057
23058			} else if ( face == 2.0 ) {
23059
23060				direction.x *= -1.0; // ( -u, v, 1 ) pos z
23061
23062			} else if ( face == 3.0 ) {
23063
23064				direction = direction.zyx;
23065				direction.xz *= -1.0; // ( -1, v, -u ) neg x
23066
23067			} else if ( face == 4.0 ) {
23068
23069				direction = direction.xzy;
23070				direction.xy *= -1.0; // ( -u, -1, v ) neg y
23071
23072			} else if ( face == 5.0 ) {
23073
23074				direction.z *= -1.0; // ( u, v, -1 ) neg z
23075
23076			}
23077
23078			return direction;
23079
23080		}
23081
23082		void main() {
23083
23084			vOutputDirection = getDirection( uv, faceIndex );
23085			gl_Position = vec4( position, 1.0 );
23086
23087		}
23088	`;
23089	}
23090	function WebGLCubeUVMaps(renderer) {
23091	    let cubeUVmaps = new WeakMap();
23092	    let pmremGenerator = null;
23093	    function get(texture) {
23094	        if (texture && texture.isTexture) {
23095	            const mapping = texture.mapping;
23096	            const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping;
23097	            const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping;
23098	            // equirect/cube map to cubeUV conversion
23099	            if (isEquirectMap || isCubeMap) {
23100	                let renderTarget = cubeUVmaps.get(texture);
23101	                const currentPMREMVersion = renderTarget !== undefined ? renderTarget.texture.pmremVersion : 0;
23102	                if (texture.isRenderTargetTexture && texture.pmremVersion !== currentPMREMVersion) {
23103	                    if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);
23104	                    renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture, renderTarget) : pmremGenerator.fromCubemap(texture, renderTarget);
23105	                    renderTarget.texture.pmremVersion = texture.pmremVersion;
23106	                    cubeUVmaps.set(texture, renderTarget);
23107	                    return renderTarget.texture;
23108	                } else {
23109	                    if (renderTarget !== undefined) {
23110	                        return renderTarget.texture;
23111	                    } else {
23112	                        const image = texture.image;
23113	                        if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) {
23114	                            if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);
23115	                            renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture);
23116	                            renderTarget.texture.pmremVersion = texture.pmremVersion;
23117	                            cubeUVmaps.set(texture, renderTarget);
23118	                            texture.addEventListener('dispose', onTextureDispose);
23119	                            return renderTarget.texture;
23120	                        } else {
23121	                            // image not yet ready. try the conversion next frame
23122	                            return null;
23123	                        }
23124	                    }
23125	                }
23126	            }
23127	        }
23128	        return texture;
23129	    }
23130	    function isCubeTextureComplete(image) {
23131	        let count = 0;
23132	        const length = 6;
23133	        for(let i = 0; i < length; i++){
23134	            if (image[i] !== undefined) count++;
23135	        }
23136	        return count === length;
23137	    }
23138	    function onTextureDispose(event) {
23139	        const texture = event.target;
23140	        texture.removeEventListener('dispose', onTextureDispose);
23141	        const cubemapUV = cubeUVmaps.get(texture);
23142	        if (cubemapUV !== undefined) {
23143	            cubeUVmaps.delete(texture);
23144	            cubemapUV.dispose();
23145	        }
23146	    }
23147	    function dispose() {
23148	        cubeUVmaps = new WeakMap();
23149	        if (pmremGenerator !== null) {
23150	            pmremGenerator.dispose();
23151	            pmremGenerator = null;
23152	        }
23153	    }
23154	    return {
23155	        get: get,
23156	        dispose: dispose
23157	    };
23158	}
23159	function WebGLExtensions(gl) {
23160	    const extensions = {};
23161	    function getExtension(name) {
23162	        if (extensions[name] !== undefined) {
23163	            return extensions[name];
23164	        }
23165	        let extension;
23166	        switch(name){
23167	            case 'WEBGL_depth_texture':
23168	                extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture');
23169	                break;
23170	            case 'EXT_texture_filter_anisotropic':
23171	                extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic');
23172	                break;
23173	            case 'WEBGL_compressed_texture_s3tc':
23174	                extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
23175	                break;
23176	            case 'WEBGL_compressed_texture_pvrtc':
23177	                extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
23178	                break;
23179	            default:
23180	                extension = gl.getExtension(name);
23181	        }
23182	        extensions[name] = extension;
23183	        return extension;
23184	    }
23185	    return {
23186	        has: function(name) {
23187	            return getExtension(name) !== null;
23188	        },
23189	        init: function() {
23190	            getExtension('EXT_color_buffer_float');
23191	            getExtension('WEBGL_clip_cull_distance');
23192	            getExtension('OES_texture_float_linear');
23193	            getExtension('EXT_color_buffer_half_float');
23194	            getExtension('WEBGL_multisampled_render_to_texture');
23195	            getExtension('WEBGL_render_shared_exponent');
23196	        },
23197	        get: function(name) {
23198	            const extension = getExtension(name);
23199	            if (extension === null) {
23200	                warnOnce('THREE.WebGLRenderer: ' + name + ' extension not supported.');
23201	            }
23202	            return extension;
23203	        }
23204	    };
23205	}
23206	function WebGLGeometries(gl, attributes, info, bindingStates) {
23207	    const geometries = {};
23208	    const wireframeAttributes = new WeakMap();
23209	    function onGeometryDispose(event) {
23210	        const geometry = event.target;
23211	        if (geometry.index !== null) {
23212	            attributes.remove(geometry.index);
23213	        }
23214	        for(const name in geometry.attributes){
23215	            attributes.remove(geometry.attributes[name]);
23216	        }
23217	        geometry.removeEventListener('dispose', onGeometryDispose);
23218	        delete geometries[geometry.id];
23219	        const attribute = wireframeAttributes.get(geometry);
23220	        if (attribute) {
23221	            attributes.remove(attribute);
23222	            wireframeAttributes.delete(geometry);
23223	        }
23224	        bindingStates.releaseStatesOfGeometry(geometry);
23225	        if (geometry.isInstancedBufferGeometry === true) {
23226	            delete geometry._maxInstanceCount;
23227	        }
23228	        //
23229	        info.memory.geometries--;
23230	    }
23231	    function get(object, geometry) {
23232	        if (geometries[geometry.id] === true) return geometry;
23233	        geometry.addEventListener('dispose', onGeometryDispose);
23234	        geometries[geometry.id] = true;
23235	        info.memory.geometries++;
23236	        return geometry;
23237	    }
23238	    function update(geometry) {
23239	        const geometryAttributes = geometry.attributes;
23240	        // Updating index buffer in VAO now. See WebGLBindingStates.
23241	        for(const name in geometryAttributes){
23242	            attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER);
23243	        }
23244	    }
23245	    function updateWireframeAttribute(geometry) {
23246	        const indices = [];
23247	        const geometryIndex = geometry.index;
23248	        const geometryPosition = geometry.attributes.position;
23249	        let version = 0;
23250	        if (geometryIndex !== null) {
23251	            const array = geometryIndex.array;
23252	            version = geometryIndex.version;
23253	            for(let i = 0, l = array.length; i < l; i += 3){
23254	                const a = array[i + 0];
23255	                const b = array[i + 1];
23256	                const c = array[i + 2];
23257	                indices.push(a, b, b, c, c, a);
23258	            }
23259	        } else if (geometryPosition !== undefined) {
23260	            const array = geometryPosition.array;
23261	            version = geometryPosition.version;
23262	            for(let i = 0, l = array.length / 3 - 1; i < l; i += 3){
23263	                const a = i + 0;
23264	                const b = i + 1;
23265	                const c = i + 2;
23266	                indices.push(a, b, b, c, c, a);
23267	            }
23268	        } else {
23269	            return;
23270	        }
23271	        const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1);
23272	        attribute.version = version;
23273	        // Updating index buffer in VAO now. See WebGLBindingStates
23274	        //
23275	        const previousAttribute = wireframeAttributes.get(geometry);
23276	        if (previousAttribute) attributes.remove(previousAttribute);
23277	        //
23278	        wireframeAttributes.set(geometry, attribute);
23279	    }
23280	    function getWireframeAttribute(geometry) {
23281	        const currentAttribute = wireframeAttributes.get(geometry);
23282	        if (currentAttribute) {
23283	            const geometryIndex = geometry.index;
23284	            if (geometryIndex !== null) {
23285	                // if the attribute is obsolete, create a new one
23286	                if (currentAttribute.version < geometryIndex.version) {
23287	                    updateWireframeAttribute(geometry);
23288	                }
23289	            }
23290	        } else {
23291	            updateWireframeAttribute(geometry);
23292	        }
23293	        return wireframeAttributes.get(geometry);
23294	    }
23295	    return {
23296	        get: get,
23297	        update: update,
23298	        getWireframeAttribute: getWireframeAttribute
23299	    };
23300	}
23301	function WebGLIndexedBufferRenderer(gl, extensions, info) {
23302	    let mode;
23303	    function setMode(value) {
23304	        mode = value;
23305	    }
23306	    let type, bytesPerElement;
23307	    function setIndex(value) {
23308	        type = value.type;
23309	        bytesPerElement = value.bytesPerElement;
23310	    }
23311	    function render(start, count) {
23312	        gl.drawElements(mode, count, type, start * bytesPerElement);
23313	        info.update(count, mode, 1);
23314	    }
23315	    function renderInstances(start, count, primcount) {
23316	        if (primcount === 0) return;
23317	        gl.drawElementsInstanced(mode, count, type, start * bytesPerElement, primcount);
23318	        info.update(count, mode, primcount);
23319	    }
23320	    function renderMultiDraw(starts, counts, drawCount) {
23321	        if (drawCount === 0) return;
23322	        const extension = extensions.get('WEBGL_multi_draw');
23323	        extension.multiDrawElementsWEBGL(mode, counts, 0, type, starts, 0, drawCount);
23324	        let elementCount = 0;
23325	        for(let i = 0; i < drawCount; i++){
23326	            elementCount += counts[i];
23327	        }
23328	        info.update(elementCount, mode, 1);
23329	    }
23330	    function renderMultiDrawInstances(starts, counts, drawCount, primcount) {
23331	        if (drawCount === 0) return;
23332	        const extension = extensions.get('WEBGL_multi_draw');
23333	        if (extension === null) {
23334	            for(let i = 0; i < starts.length; i++){
23335	                renderInstances(starts[i] / bytesPerElement, counts[i], primcount[i]);
23336	            }
23337	        } else {
23338	            extension.multiDrawElementsInstancedWEBGL(mode, counts, 0, type, starts, 0, primcount, 0, drawCount);
23339	            let elementCount = 0;
23340	            for(let i = 0; i < drawCount; i++){
23341	                elementCount += counts[i] * primcount[i];
23342	            }
23343	            info.update(elementCount, mode, 1);
23344	        }
23345	    }
23346	    //
23347	    this.setMode = setMode;
23348	    this.setIndex = setIndex;
23349	    this.render = render;
23350	    this.renderInstances = renderInstances;
23351	    this.renderMultiDraw = renderMultiDraw;
23352	    this.renderMultiDrawInstances = renderMultiDrawInstances;
23353	}
23354	function WebGLInfo(gl) {
23355	    const memory = {
23356	        geometries: 0,
23357	        textures: 0
23358	    };
23359	    const render = {
23360	        frame: 0,
23361	        calls: 0,
23362	        triangles: 0,
23363	        points: 0,
23364	        lines: 0
23365	    };
23366	    function update(count, mode, instanceCount) {
23367	        render.calls++;
23368	        switch(mode){
23369	            case gl.TRIANGLES:
23370	                render.triangles += instanceCount * (count / 3);
23371	                break;
23372	            case gl.LINES:
23373	                render.lines += instanceCount * (count / 2);
23374	                break;
23375	            case gl.LINE_STRIP:
23376	                render.lines += instanceCount * (count - 1);
23377	                break;
23378	            case gl.LINE_LOOP:
23379	                render.lines += instanceCount * count;
23380	                break;
23381	            case gl.POINTS:
23382	                render.points += instanceCount * count;
23383	                break;
23384	            default:
23385	                console.error('THREE.WebGLInfo: Unknown draw mode:', mode);
23386	                break;
23387	        }
23388	    }
23389	    function reset() {
23390	        render.calls = 0;
23391	        render.triangles = 0;
23392	        render.points = 0;
23393	        render.lines = 0;
23394	    }
23395	    return {
23396	        memory: memory,
23397	        render: render,
23398	        programs: null,
23399	        autoReset: true,
23400	        reset: reset,
23401	        update: update
23402	    };
23403	}
23404	function WebGLMorphtargets(gl, capabilities, textures) {
23405	    const morphTextures = new WeakMap();
23406	    const morph = new Vector4();
23407	    function update(object, geometry, program) {
23408	        const objectInfluences = object.morphTargetInfluences;
23409	        // the following encodes morph targets into an array of data textures. Each layer represents a single morph target.
23410	        const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
23411	        const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
23412	        let entry = morphTextures.get(geometry);
23413	        if (entry === undefined || entry.count !== morphTargetsCount) {
23414	            if (entry !== undefined) entry.texture.dispose();
23415	            const hasMorphPosition = geometry.morphAttributes.position !== undefined;
23416	            const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
23417	            const hasMorphColors = geometry.morphAttributes.color !== undefined;
23418	            const morphTargets = geometry.morphAttributes.position || [];
23419	            const morphNormals = geometry.morphAttributes.normal || [];
23420	            const morphColors = geometry.morphAttributes.color || [];
23421	            let vertexDataCount = 0;
23422	            if (hasMorphPosition === true) vertexDataCount = 1;
23423	            if (hasMorphNormals === true) vertexDataCount = 2;
23424	            if (hasMorphColors === true) vertexDataCount = 3;
23425	            let width = geometry.attributes.position.count * vertexDataCount;
23426	            let height = 1;
23427	            if (width > capabilities.maxTextureSize) {
23428	                height = Math.ceil(width / capabilities.maxTextureSize);
23429	                width = capabilities.maxTextureSize;
23430	            }
23431	            const buffer = new Float32Array(width * height * 4 * morphTargetsCount);
23432	            const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount);
23433	            texture.type = FloatType;
23434	            texture.needsUpdate = true;
23435	            // fill buffer
23436	            const vertexDataStride = vertexDataCount * 4;
23437	            for(let i = 0; i < morphTargetsCount; i++){
23438	                const morphTarget = morphTargets[i];
23439	                const morphNormal = morphNormals[i];
23440	                const morphColor = morphColors[i];
23441	                const offset = width * height * 4 * i;
23442	                for(let j = 0; j < morphTarget.count; j++){
23443	                    const stride = j * vertexDataStride;
23444	                    if (hasMorphPosition === true) {
23445	                        morph.fromBufferAttribute(morphTarget, j);
23446	                        buffer[offset + stride + 0] = morph.x;
23447	                        buffer[offset + stride + 1] = morph.y;
23448	                        buffer[offset + stride + 2] = morph.z;
23449	                        buffer[offset + stride + 3] = 0;
23450	                    }
23451	                    if (hasMorphNormals === true) {
23452	                        morph.fromBufferAttribute(morphNormal, j);
23453	                        buffer[offset + stride + 4] = morph.x;
23454	                        buffer[offset + stride + 5] = morph.y;
23455	                        buffer[offset + stride + 6] = morph.z;
23456	                        buffer[offset + stride + 7] = 0;
23457	                    }
23458	                    if (hasMorphColors === true) {
23459	                        morph.fromBufferAttribute(morphColor, j);
23460	                        buffer[offset + stride + 8] = morph.x;
23461	                        buffer[offset + stride + 9] = morph.y;
23462	                        buffer[offset + stride + 10] = morph.z;
23463	                        buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1;
23464	                    }
23465	                }
23466	            }
23467	            entry = {
23468	                count: morphTargetsCount,
23469	                texture: texture,
23470	                size: new Vector2(width, height)
23471	            };
23472	            morphTextures.set(geometry, entry);
23473	            function disposeTexture() {
23474	                texture.dispose();
23475	                morphTextures.delete(geometry);
23476	                geometry.removeEventListener('dispose', disposeTexture);
23477	            }
23478	            geometry.addEventListener('dispose', disposeTexture);
23479	        }
23480	        //
23481	        if (object.isInstancedMesh === true && object.morphTexture !== null) {
23482	            program.getUniforms().setValue(gl, 'morphTexture', object.morphTexture, textures);
23483	        } else {
23484	            let morphInfluencesSum = 0;
23485	            for(let i = 0; i < objectInfluences.length; i++){
23486	                morphInfluencesSum += objectInfluences[i];
23487	            }
23488	            const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
23489	            program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
23490	            program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences);
23491	        }
23492	        program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures);
23493	        program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size);
23494	    }
23495	    return {
23496	        update: update
23497	    };
23498	}
23499	function WebGLObjects(gl, geometries, attributes, info) {
23500	    let updateMap = new WeakMap();
23501	    function update(object) {
23502	        const frame = info.render.frame;
23503	        const geometry = object.geometry;
23504	        const buffergeometry = geometries.get(object, geometry);
23505	        // Update once per frame
23506	        if (updateMap.get(buffergeometry) !== frame) {
23507	            geometries.update(buffergeometry);
23508	            updateMap.set(buffergeometry, frame);
23509	        }
23510	        if (object.isInstancedMesh) {
23511	            if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) {
23512	                object.addEventListener('dispose', onInstancedMeshDispose);
23513	            }
23514	            if (updateMap.get(object) !== frame) {
23515	                attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER);
23516	                if (object.instanceColor !== null) {
23517	                    attributes.update(object.instanceColor, gl.ARRAY_BUFFER);
23518	                }
23519	                updateMap.set(object, frame);
23520	            }
23521	        }
23522	        if (object.isSkinnedMesh) {
23523	            const skeleton = object.skeleton;
23524	            if (updateMap.get(skeleton) !== frame) {
23525	                skeleton.update();
23526	                updateMap.set(skeleton, frame);
23527	            }
23528	        }
23529	        return buffergeometry;
23530	    }
23531	    function dispose() {
23532	        updateMap = new WeakMap();
23533	    }
23534	    function onInstancedMeshDispose(event) {
23535	        const instancedMesh = event.target;
23536	        instancedMesh.removeEventListener('dispose', onInstancedMeshDispose);
23537	        attributes.remove(instancedMesh.instanceMatrix);
23538	        if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor);
23539	    }
23540	    return {
23541	        update: update,
23542	        dispose: dispose
23543	    };
23544	}
23545	/**
23546	 * Uniforms of a program.
23547	 * Those form a tree structure with a special top-level container for the root,
23548	 * which you get by calling 'new WebGLUniforms( gl, program )'.
23549	 *
23550	 *
23551	 * Properties of inner nodes including the top-level container:
23552	 *
23553	 * .seq - array of nested uniforms
23554	 * .map - nested uniforms by name
23555	 *
23556	 *
23557	 * Methods of all nodes except the top-level container:
23558	 *
23559	 * .setValue( gl, value, [textures] )
23560	 *
23561	 * 		uploads a uniform value(s)
23562	 *  	the 'textures' parameter is needed for sampler uniforms
23563	 *
23564	 *
23565	 * Static methods of the top-level container (textures factorizations):
23566	 *
23567	 * .upload( gl, seq, values, textures )
23568	 *
23569	 * 		sets uniforms in 'seq' to 'values[id].value'
23570	 *
23571	 * .seqWithValue( seq, values ) : filteredSeq
23572	 *
23573	 * 		filters 'seq' entries with corresponding entry in values
23574	 *
23575	 *
23576	 * Methods of the top-level container (textures factorizations):
23577	 *
23578	 * .setValue( gl, name, value, textures )
23579	 *
23580	 * 		sets uniform with  name 'name' to 'value'
23581	 *
23582	 * .setOptional( gl, obj, prop )
23583	 *
23584	 * 		like .set for an optional property of the object
23585	 *
23586	 */ const emptyTexture = /*@__PURE__*/ new Texture$1();
23587	const emptyShadowTexture = /*@__PURE__*/ new DepthTexture(1, 1);
23588	const emptyArrayTexture = /*@__PURE__*/ new DataArrayTexture();
23589	const empty3dTexture = /*@__PURE__*/ new Data3DTexture();
23590	const emptyCubeTexture = /*@__PURE__*/ new CubeTexture();
23591	// --- Utilities ---
23592	// Array Caches (provide typed arrays for temporary by size)
23593	const arrayCacheF32 = [];
23594	const arrayCacheI32 = [];
23595	// Float32Array caches used for uploading Matrix uniforms
23596	const mat4array = new Float32Array(16);
23597	const mat3array = new Float32Array(9);
23598	const mat2array = new Float32Array(4);
23599	// Flattening for arrays of vectors and matrices
23600	function flatten(array, nBlocks, blockSize) {
23601	    const firstElem = array[0];
23602	    if (firstElem <= 0 || firstElem > 0) return array;
23603	    // unoptimized: ! isNaN( firstElem )
23604	    // see http://jacksondunstan.com/articles/983
23605	    const n = nBlocks * blockSize;
23606	    let r = arrayCacheF32[n];
23607	    if (r === undefined) {
23608	        r = new Float32Array(n);
23609	        arrayCacheF32[n] = r;
23610	    }
23611	    if (nBlocks !== 0) {
23612	        firstElem.toArray(r, 0);
23613	        for(let i = 1, offset = 0; i !== nBlocks; ++i){
23614	            offset += blockSize;
23615	            array[i].toArray(r, offset);
23616	        }
23617	    }
23618	    return r;
23619	}
23620	function arraysEqual(a, b) {
23621	    if (a.length !== b.length) return false;
23622	    for(let i = 0, l = a.length; i < l; i++){
23623	        if (a[i] !== b[i]) return false;
23624	    }
23625	    return true;
23626	}
23627	function copyArray(a, b) {
23628	    for(let i = 0, l = b.length; i < l; i++){
23629	        a[i] = b[i];
23630	    }
23631	}
23632	// Texture unit allocation
23633	function allocTexUnits(textures, n) {
23634	    let r = arrayCacheI32[n];
23635	    if (r === undefined) {
23636	        r = new Int32Array(n);
23637	        arrayCacheI32[n] = r;
23638	    }
23639	    for(let i = 0; i !== n; ++i){
23640	        r[i] = textures.allocateTextureUnit();
23641	    }
23642	    return r;
23643	}
23644	// --- Setters ---
23645	// Note: Defining these methods externally, because they come in a bunch
23646	// and this way their names minify.
23647	// Single scalar
23648	function setValueV1f(gl, v) {
23649	    const cache = this.cache;
23650	    if (cache[0] === v) return;
23651	    gl.uniform1f(this.addr, v);
23652	    cache[0] = v;
23653	}
23654	// Single float vector (from flat array or THREE.VectorN)
23655	function setValueV2f(gl, v) {
23656	    const cache = this.cache;
23657	    if (v.x !== undefined) {
23658	        if (cache[0] !== v.x || cache[1] !== v.y) {
23659	            gl.uniform2f(this.addr, v.x, v.y);
23660	            cache[0] = v.x;
23661	            cache[1] = v.y;
23662	        }
23663	    } else {
23664	        if (arraysEqual(cache, v)) return;
23665	        gl.uniform2fv(this.addr, v);
23666	        copyArray(cache, v);
23667	    }
23668	}
23669	function setValueV3f(gl, v) {
23670	    const cache = this.cache;
23671	    if (v.x !== undefined) {
23672	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) {
23673	            gl.uniform3f(this.addr, v.x, v.y, v.z);
23674	            cache[0] = v.x;
23675	            cache[1] = v.y;
23676	            cache[2] = v.z;
23677	        }
23678	    } else if (v.r !== undefined) {
23679	        if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) {
23680	            gl.uniform3f(this.addr, v.r, v.g, v.b);
23681	            cache[0] = v.r;
23682	            cache[1] = v.g;
23683	            cache[2] = v.b;
23684	        }
23685	    } else {
23686	        if (arraysEqual(cache, v)) return;
23687	        gl.uniform3fv(this.addr, v);
23688	        copyArray(cache, v);
23689	    }
23690	}
23691	function setValueV4f(gl, v) {
23692	    const cache = this.cache;
23693	    if (v.x !== undefined) {
23694	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) {
23695	            gl.uniform4f(this.addr, v.x, v.y, v.z, v.w);
23696	            cache[0] = v.x;
23697	            cache[1] = v.y;
23698	            cache[2] = v.z;
23699	            cache[3] = v.w;
23700	        }
23701	    } else {
23702	        if (arraysEqual(cache, v)) return;
23703	        gl.uniform4fv(this.addr, v);
23704	        copyArray(cache, v);
23705	    }
23706	}
23707	// Single matrix (from flat array or THREE.MatrixN)
23708	function setValueM2(gl, v) {
23709	    const cache = this.cache;
23710	    const elements = v.elements;
23711	    if (elements === undefined) {
23712	        if (arraysEqual(cache, v)) return;
23713	        gl.uniformMatrix2fv(this.addr, false, v);
23714	        copyArray(cache, v);
23715	    } else {
23716	        if (arraysEqual(cache, elements)) return;
23717	        mat2array.set(elements);
23718	        gl.uniformMatrix2fv(this.addr, false, mat2array);
23719	        copyArray(cache, elements);
23720	    }
23721	}
23722	function setValueM3(gl, v) {
23723	    const cache = this.cache;
23724	    const elements = v.elements;
23725	    if (elements === undefined) {
23726	        if (arraysEqual(cache, v)) return;
23727	        gl.uniformMatrix3fv(this.addr, false, v);
23728	        copyArray(cache, v);
23729	    } else {
23730	        if (arraysEqual(cache, elements)) return;
23731	        mat3array.set(elements);
23732	        gl.uniformMatrix3fv(this.addr, false, mat3array);
23733	        copyArray(cache, elements);
23734	    }
23735	}
23736	function setValueM4(gl, v) {
23737	    const cache = this.cache;
23738	    const elements = v.elements;
23739	    if (elements === undefined) {
23740	        if (arraysEqual(cache, v)) return;
23741	        gl.uniformMatrix4fv(this.addr, false, v);
23742	        copyArray(cache, v);
23743	    } else {
23744	        if (arraysEqual(cache, elements)) return;
23745	        mat4array.set(elements);
23746	        gl.uniformMatrix4fv(this.addr, false, mat4array);
23747	        copyArray(cache, elements);
23748	    }
23749	}
23750	// Single integer / boolean
23751	function setValueV1i(gl, v) {
23752	    const cache = this.cache;
23753	    if (cache[0] === v) return;
23754	    gl.uniform1i(this.addr, v);
23755	    cache[0] = v;
23756	}
23757	// Single integer / boolean vector (from flat array or THREE.VectorN)
23758	function setValueV2i(gl, v) {
23759	    const cache = this.cache;
23760	    if (v.x !== undefined) {
23761	        if (cache[0] !== v.x || cache[1] !== v.y) {
23762	            gl.uniform2i(this.addr, v.x, v.y);
23763	            cache[0] = v.x;
23764	            cache[1] = v.y;
23765	        }
23766	    } else {
23767	        if (arraysEqual(cache, v)) return;
23768	        gl.uniform2iv(this.addr, v);
23769	        copyArray(cache, v);
23770	    }
23771	}
23772	function setValueV3i(gl, v) {
23773	    const cache = this.cache;
23774	    if (v.x !== undefined) {
23775	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) {
23776	            gl.uniform3i(this.addr, v.x, v.y, v.z);
23777	            cache[0] = v.x;
23778	            cache[1] = v.y;
23779	            cache[2] = v.z;
23780	        }
23781	    } else {
23782	        if (arraysEqual(cache, v)) return;
23783	        gl.uniform3iv(this.addr, v);
23784	        copyArray(cache, v);
23785	    }
23786	}
23787	function setValueV4i(gl, v) {
23788	    const cache = this.cache;
23789	    if (v.x !== undefined) {
23790	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) {
23791	            gl.uniform4i(this.addr, v.x, v.y, v.z, v.w);
23792	            cache[0] = v.x;
23793	            cache[1] = v.y;
23794	            cache[2] = v.z;
23795	            cache[3] = v.w;
23796	        }
23797	    } else {
23798	        if (arraysEqual(cache, v)) return;
23799	        gl.uniform4iv(this.addr, v);
23800	        copyArray(cache, v);
23801	    }
23802	}
23803	// Single unsigned integer
23804	function setValueV1ui(gl, v) {
23805	    const cache = this.cache;
23806	    if (cache[0] === v) return;
23807	    gl.uniform1ui(this.addr, v);
23808	    cache[0] = v;
23809	}
23810	// Single unsigned integer vector (from flat array or THREE.VectorN)
23811	function setValueV2ui(gl, v) {
23812	    const cache = this.cache;
23813	    if (v.x !== undefined) {
23814	        if (cache[0] !== v.x || cache[1] !== v.y) {
23815	            gl.uniform2ui(this.addr, v.x, v.y);
23816	            cache[0] = v.x;
23817	            cache[1] = v.y;
23818	        }
23819	    } else {
23820	        if (arraysEqual(cache, v)) return;
23821	        gl.uniform2uiv(this.addr, v);
23822	        copyArray(cache, v);
23823	    }
23824	}
23825	function setValueV3ui(gl, v) {
23826	    const cache = this.cache;
23827	    if (v.x !== undefined) {
23828	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) {
23829	            gl.uniform3ui(this.addr, v.x, v.y, v.z);
23830	            cache[0] = v.x;
23831	            cache[1] = v.y;
23832	            cache[2] = v.z;
23833	        }
23834	    } else {
23835	        if (arraysEqual(cache, v)) return;
23836	        gl.uniform3uiv(this.addr, v);
23837	        copyArray(cache, v);
23838	    }
23839	}
23840	function setValueV4ui(gl, v) {
23841	    const cache = this.cache;
23842	    if (v.x !== undefined) {
23843	        if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) {
23844	            gl.uniform4ui(this.addr, v.x, v.y, v.z, v.w);
23845	            cache[0] = v.x;
23846	            cache[1] = v.y;
23847	            cache[2] = v.z;
23848	            cache[3] = v.w;
23849	        }
23850	    } else {
23851	        if (arraysEqual(cache, v)) return;
23852	        gl.uniform4uiv(this.addr, v);
23853	        copyArray(cache, v);
23854	    }
23855	}
23856	// Single texture (2D / Cube)
23857	function setValueT1(gl, v, textures) {
23858	    const cache = this.cache;
23859	    const unit = textures.allocateTextureUnit();
23860	    if (cache[0] !== unit) {
23861	        gl.uniform1i(this.addr, unit);
23862	        cache[0] = unit;
23863	    }
23864	    let emptyTexture2D;
23865	    if (this.type === gl.SAMPLER_2D_SHADOW) {
23866	        emptyShadowTexture.compareFunction = LessEqualCompare; // #28670
23867	        emptyTexture2D = emptyShadowTexture;
23868	    } else {
23869	        emptyTexture2D = emptyTexture;
23870	    }
23871	    textures.setTexture2D(v || emptyTexture2D, unit);
23872	}
23873	function setValueT3D1(gl, v, textures) {
23874	    const cache = this.cache;
23875	    const unit = textures.allocateTextureUnit();
23876	    if (cache[0] !== unit) {
23877	        gl.uniform1i(this.addr, unit);
23878	        cache[0] = unit;
23879	    }
23880	    textures.setTexture3D(v || empty3dTexture, unit);
23881	}
23882	function setValueT6(gl, v, textures) {
23883	    const cache = this.cache;
23884	    const unit = textures.allocateTextureUnit();
23885	    if (cache[0] !== unit) {
23886	        gl.uniform1i(this.addr, unit);
23887	        cache[0] = unit;
23888	    }
23889	    textures.setTextureCube(v || emptyCubeTexture, unit);
23890	}
23891	function setValueT2DArray1(gl, v, textures) {
23892	    const cache = this.cache;
23893	    const unit = textures.allocateTextureUnit();
23894	    if (cache[0] !== unit) {
23895	        gl.uniform1i(this.addr, unit);
23896	        cache[0] = unit;
23897	    }
23898	    textures.setTexture2DArray(v || emptyArrayTexture, unit);
23899	}
23900	// Helper to pick the right setter for the singular case
23901	function getSingularSetter(type) {
23902	    switch(type){
23903	        case 0x1406:
23904	            return setValueV1f; // FLOAT
23905	        case 0x8b50:
23906	            return setValueV2f; // _VEC2
23907	        case 0x8b51:
23908	            return setValueV3f; // _VEC3
23909	        case 0x8b52:
23910	            return setValueV4f; // _VEC4
23911	        case 0x8b5a:
23912	            return setValueM2; // _MAT2
23913	        case 0x8b5b:
23914	            return setValueM3; // _MAT3
23915	        case 0x8b5c:
23916	            return setValueM4; // _MAT4
23917	        case 0x1404:
23918	        case 0x8b56:
23919	            return setValueV1i; // INT, BOOL
23920	        case 0x8b53:
23921	        case 0x8b57:
23922	            return setValueV2i; // _VEC2
23923	        case 0x8b54:
23924	        case 0x8b58:
23925	            return setValueV3i; // _VEC3
23926	        case 0x8b55:
23927	        case 0x8b59:
23928	            return setValueV4i; // _VEC4
23929	        case 0x1405:
23930	            return setValueV1ui; // UINT
23931	        case 0x8dc6:
23932	            return setValueV2ui; // _VEC2
23933	        case 0x8dc7:
23934	            return setValueV3ui; // _VEC3
23935	        case 0x8dc8:
23936	            return setValueV4ui; // _VEC4
23937	        case 0x8b5e:
23938	        case 0x8d66:
23939	        case 0x8dca:
23940	        case 0x8dd2:
23941	        case 0x8b62:
23942	            return setValueT1;
23943	        case 0x8b5f:
23944	        case 0x8dcb:
23945	        case 0x8dd3:
23946	            return setValueT3D1;
23947	        case 0x8b60:
23948	        case 0x8dcc:
23949	        case 0x8dd4:
23950	        case 0x8dc5:
23951	            return setValueT6;
23952	        case 0x8dc1:
23953	        case 0x8dcf:
23954	        case 0x8dd7:
23955	        case 0x8dc4:
23956	            return setValueT2DArray1;
23957	    }
23958	}
23959	// Array of scalars
23960	function setValueV1fArray(gl, v) {
23961	    gl.uniform1fv(this.addr, v);
23962	}
23963	// Array of vectors (from flat array or array of THREE.VectorN)
23964	function setValueV2fArray(gl, v) {
23965	    const data = flatten(v, this.size, 2);
23966	    gl.uniform2fv(this.addr, data);
23967	}
23968	function setValueV3fArray(gl, v) {
23969	    const data = flatten(v, this.size, 3);
23970	    gl.uniform3fv(this.addr, data);
23971	}
23972	function setValueV4fArray(gl, v) {
23973	    const data = flatten(v, this.size, 4);
23974	    gl.uniform4fv(this.addr, data);
23975	}
23976	// Array of matrices (from flat array or array of THREE.MatrixN)
23977	function setValueM2Array(gl, v) {
23978	    const data = flatten(v, this.size, 4);
23979	    gl.uniformMatrix2fv(this.addr, false, data);
23980	}
23981	function setValueM3Array(gl, v) {
23982	    const data = flatten(v, this.size, 9);
23983	    gl.uniformMatrix3fv(this.addr, false, data);
23984	}
23985	function setValueM4Array(gl, v) {
23986	    const data = flatten(v, this.size, 16);
23987	    gl.uniformMatrix4fv(this.addr, false, data);
23988	}
23989	// Array of integer / boolean
23990	function setValueV1iArray(gl, v) {
23991	    gl.uniform1iv(this.addr, v);
23992	}
23993	// Array of integer / boolean vectors (from flat array)
23994	function setValueV2iArray(gl, v) {
23995	    gl.uniform2iv(this.addr, v);
23996	}
23997	function setValueV3iArray(gl, v) {
23998	    gl.uniform3iv(this.addr, v);
23999	}
24000	function setValueV4iArray(gl, v) {
24001	    gl.uniform4iv(this.addr, v);
24002	}
24003	// Array of unsigned integer
24004	function setValueV1uiArray(gl, v) {
24005	    gl.uniform1uiv(this.addr, v);
24006	}
24007	// Array of unsigned integer vectors (from flat array)
24008	function setValueV2uiArray(gl, v) {
24009	    gl.uniform2uiv(this.addr, v);
24010	}
24011	function setValueV3uiArray(gl, v) {
24012	    gl.uniform3uiv(this.addr, v);
24013	}
24014	function setValueV4uiArray(gl, v) {
24015	    gl.uniform4uiv(this.addr, v);
24016	}
24017	// Array of textures (2D / 3D / Cube / 2DArray)
24018	function setValueT1Array(gl, v, textures) {
24019	    const cache = this.cache;
24020	    const n = v.length;
24021	    const units = allocTexUnits(textures, n);
24022	    if (!arraysEqual(cache, units)) {
24023	        gl.uniform1iv(this.addr, units);
24024	        copyArray(cache, units);
24025	    }
24026	    for(let i = 0; i !== n; ++i){
24027	        textures.setTexture2D(v[i] || emptyTexture, units[i]);
24028	    }
24029	}
24030	function setValueT3DArray(gl, v, textures) {
24031	    const cache = this.cache;
24032	    const n = v.length;
24033	    const units = allocTexUnits(textures, n);
24034	    if (!arraysEqual(cache, units)) {
24035	        gl.uniform1iv(this.addr, units);
24036	        copyArray(cache, units);
24037	    }
24038	    for(let i = 0; i !== n; ++i){
24039	        textures.setTexture3D(v[i] || empty3dTexture, units[i]);
24040	    }
24041	}
24042	function setValueT6Array(gl, v, textures) {
24043	    const cache = this.cache;
24044	    const n = v.length;
24045	    const units = allocTexUnits(textures, n);
24046	    if (!arraysEqual(cache, units)) {
24047	        gl.uniform1iv(this.addr, units);
24048	        copyArray(cache, units);
24049	    }
24050	    for(let i = 0; i !== n; ++i){
24051	        textures.setTextureCube(v[i] || emptyCubeTexture, units[i]);
24052	    }
24053	}
24054	function setValueT2DArrayArray(gl, v, textures) {
24055	    const cache = this.cache;
24056	    const n = v.length;
24057	    const units = allocTexUnits(textures, n);
24058	    if (!arraysEqual(cache, units)) {
24059	        gl.uniform1iv(this.addr, units);
24060	        copyArray(cache, units);
24061	    }
24062	    for(let i = 0; i !== n; ++i){
24063	        textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]);
24064	    }
24065	}
24066	// Helper to pick the right setter for a pure (bottom-level) array
24067	function getPureArraySetter(type) {
24068	    switch(type){
24069	        case 0x1406:
24070	            return setValueV1fArray; // FLOAT
24071	        case 0x8b50:
24072	            return setValueV2fArray; // _VEC2
24073	        case 0x8b51:
24074	            return setValueV3fArray; // _VEC3
24075	        case 0x8b52:
24076	            return setValueV4fArray; // _VEC4
24077	        case 0x8b5a:
24078	            return setValueM2Array; // _MAT2
24079	        case 0x8b5b:
24080	            return setValueM3Array; // _MAT3
24081	        case 0x8b5c:
24082	            return setValueM4Array; // _MAT4
24083	        case 0x1404:
24084	        case 0x8b56:
24085	            return setValueV1iArray; // INT, BOOL
24086	        case 0x8b53:
24087	        case 0x8b57:
24088	            return setValueV2iArray; // _VEC2
24089	        case 0x8b54:
24090	        case 0x8b58:
24091	            return setValueV3iArray; // _VEC3
24092	        case 0x8b55:
24093	        case 0x8b59:
24094	            return setValueV4iArray; // _VEC4
24095	        case 0x1405:
24096	            return setValueV1uiArray; // UINT
24097	        case 0x8dc6:
24098	            return setValueV2uiArray; // _VEC2
24099	        case 0x8dc7:
24100	            return setValueV3uiArray; // _VEC3
24101	        case 0x8dc8:
24102	            return setValueV4uiArray; // _VEC4
24103	        case 0x8b5e:
24104	        case 0x8d66:
24105	        case 0x8dca:
24106	        case 0x8dd2:
24107	        case 0x8b62:
24108	            return setValueT1Array;
24109	        case 0x8b5f:
24110	        case 0x8dcb:
24111	        case 0x8dd3:
24112	            return setValueT3DArray;
24113	        case 0x8b60:
24114	        case 0x8dcc:
24115	        case 0x8dd4:
24116	        case 0x8dc5:
24117	            return setValueT6Array;
24118	        case 0x8dc1:
24119	        case 0x8dcf:
24120	        case 0x8dd7:
24121	        case 0x8dc4:
24122	            return setValueT2DArrayArray;
24123	    }
24124	}
24125	// --- Uniform Classes ---
24126	class SingleUniform {
24127	    constructor(id, activeInfo, addr){
24128	        this.id = id;
24129	        this.addr = addr;
24130	        this.cache = [];
24131	        this.type = activeInfo.type;
24132	        this.setValue = getSingularSetter(activeInfo.type);
24133	    // this.path = activeInfo.name; // DEBUG
24134	    }
24135	}
24136	class PureArrayUniform {
24137	    constructor(id, activeInfo, addr){
24138	        this.id = id;
24139	        this.addr = addr;
24140	        this.cache = [];
24141	        this.type = activeInfo.type;
24142	        this.size = activeInfo.size;
24143	        this.setValue = getPureArraySetter(activeInfo.type);
24144	    // this.path = activeInfo.name; // DEBUG
24145	    }
24146	}
24147	class StructuredUniform {
24148	    setValue(gl, value, textures) {
24149	        const seq = this.seq;
24150	        for(let i = 0, n = seq.length; i !== n; ++i){
24151	            const u = seq[i];
24152	            u.setValue(gl, value[u.id], textures);
24153	        }
24154	    }
24155	    constructor(id){
24156	        this.id = id;
24157	        this.seq = [];
24158	        this.map = {};
24159	    }
24160	}
24161	// --- Top-level ---
24162	// Parser - builds up the property tree from the path strings
24163	const RePathPart = /(\w+)(\])?(\[|\.)?/g;
24164	// extracts
24165	// 	- the identifier (member name or array index)
24166	//  - followed by an optional right bracket (found when array index)
24167	//  - followed by an optional left bracket or dot (type of subscript)
24168	//
24169	// Note: These portions can be read in a non-overlapping fashion and
24170	// allow straightforward parsing of the hierarchy that WebGL encodes
24171	// in the uniform names.
24172	function addUniform(container, uniformObject) {
24173	    container.seq.push(uniformObject);
24174	    container.map[uniformObject.id] = uniformObject;
24175	}
24176	function parseUniform(activeInfo, addr, container) {
24177	    const path = activeInfo.name, pathLength = path.length;
24178	    // reset RegExp object, because of the early exit of a previous run
24179	    RePathPart.lastIndex = 0;
24180	    while(true){
24181	        const match = RePathPart.exec(path), matchEnd = RePathPart.lastIndex;
24182	        let id = match[1];
24183	        const idIsIndex = match[2] === ']', subscript = match[3];
24184	        if (idIsIndex) id = id | 0; // convert to integer
24185	        if (subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength) {
24186	            // bare name or "pure" bottom-level array "[0]" suffix
24187	            addUniform(container, subscript === undefined ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr));
24188	            break;
24189	        } else {
24190	            // step into inner node / create it in case it doesn't exist
24191	            const map = container.map;
24192	            let next = map[id];
24193	            if (next === undefined) {
24194	                next = new StructuredUniform(id);
24195	                addUniform(container, next);
24196	            }
24197	            container = next;
24198	        }
24199	    }
24200	}
24201	// Root Container
24202	class WebGLUniforms {
24203	    setValue(gl, name, value, textures) {
24204	        const u = this.map[name];
24205	        if (u !== undefined) u.setValue(gl, value, textures);
24206	    }
24207	    setOptional(gl, object, name) {
24208	        const v = object[name];
24209	        if (v !== undefined) this.setValue(gl, name, v);
24210	    }
24211	    static upload(gl, seq, values, textures) {
24212	        for(let i = 0, n = seq.length; i !== n; ++i){
24213	            const u = seq[i], v = values[u.id];
24214	            if (v.needsUpdate !== false) {
24215	                // note: always updating when .needsUpdate is undefined
24216	                u.setValue(gl, v.value, textures);
24217	            }
24218	        }
24219	    }
24220	    static seqWithValue(seq, values) {
24221	        const r = [];
24222	        for(let i = 0, n = seq.length; i !== n; ++i){
24223	            const u = seq[i];
24224	            if (u.id in values) r.push(u);
24225	        }
24226	        return r;
24227	    }
24228	    constructor(gl, program){
24229	        this.seq = [];
24230	        this.map = {};
24231	        const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
24232	        for(let i = 0; i < n; ++i){
24233	            const info = gl.getActiveUniform(program, i), addr = gl.getUniformLocation(program, info.name);
24234	            parseUniform(info, addr, this);
24235	        }
24236	    }
24237	}
24238	function WebGLShader(gl, type, string) {
24239	    const shader = gl.createShader(type);
24240	    gl.shaderSource(shader, string);
24241	    gl.compileShader(shader);
24242	    return shader;
24243	}
24244	// From https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/
24245	const COMPLETION_STATUS_KHR = 0x91B1;
24246	let programIdCount = 0;
24247	function handleSource(string, errorLine) {
24248	    const lines = string.split('\n');
24249	    const lines2 = [];
24250	    const from = Math.max(errorLine - 6, 0);
24251	    const to = Math.min(errorLine + 6, lines.length);
24252	    for(let i = from; i < to; i++){
24253	        const line = i + 1;
24254	        lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`);
24255	    }
24256	    return lines2.join('\n');
24257	}
24258	const _m0 = /*@__PURE__*/ new Matrix3();
24259	function getEncodingComponents(colorSpace) {
24260	    ColorManagement._getMatrix(_m0, ColorManagement.workingColorSpace, colorSpace);
24261	    const encodingMatrix = `mat3( ${_m0.elements.map((v)=>v.toFixed(4))} )`;
24262	    switch(ColorManagement.getTransfer(colorSpace)){
24263	        case LinearTransfer:
24264	            return [
24265	                encodingMatrix,
24266	                'LinearTransferOETF'
24267	            ];
24268	        case SRGBTransfer:
24269	            return [
24270	                encodingMatrix,
24271	                'sRGBTransferOETF'
24272	            ];
24273	        default:
24274	            console.warn('THREE.WebGLProgram: Unsupported color space: ', colorSpace);
24275	            return [
24276	                encodingMatrix,
24277	                'LinearTransferOETF'
24278	            ];
24279	    }
24280	}
24281	function getShaderErrors(gl, shader, type) {
24282	    const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
24283	    const errors = gl.getShaderInfoLog(shader).trim();
24284	    if (status && errors === '') return '';
24285	    const errorMatches = /ERROR: 0:(\d+)/.exec(errors);
24286	    if (errorMatches) {
24287	        // --enable-privileged-webgl-extension
24288	        // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
24289	        const errorLine = parseInt(errorMatches[1]);
24290	        return type.toUpperCase() + '\n\n' + errors + '\n\n' + handleSource(gl.getShaderSource(shader), errorLine);
24291	    } else {
24292	        return errors;
24293	    }
24294	}
24295	function getTexelEncodingFunction(functionName, colorSpace) {
24296	    const components = getEncodingComponents(colorSpace);
24297	    return [
24298	        `vec4 ${functionName}( vec4 value ) {`,
24299	        `	return ${components[1]}( vec4( value.rgb * ${components[0]}, value.a ) );`,
24300	        '}'
24301	    ].join('\n');
24302	}
24303	function getToneMappingFunction(functionName, toneMapping) {
24304	    let toneMappingName;
24305	    switch(toneMapping){
24306	        case LinearToneMapping:
24307	            toneMappingName = 'Linear';
24308	            break;
24309	        case ReinhardToneMapping:
24310	            toneMappingName = 'Reinhard';
24311	            break;
24312	        case CineonToneMapping:
24313	            toneMappingName = 'Cineon';
24314	            break;
24315	        case ACESFilmicToneMapping:
24316	            toneMappingName = 'ACESFilmic';
24317	            break;
24318	        case AgXToneMapping:
24319	            toneMappingName = 'AgX';
24320	            break;
24321	        case NeutralToneMapping:
24322	            toneMappingName = 'Neutral';
24323	            break;
24324	        case CustomToneMapping:
24325	            toneMappingName = 'Custom';
24326	            break;
24327	        default:
24328	            console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping);
24329	            toneMappingName = 'Linear';
24330	    }
24331	    return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
24332	}
24333	const _v0 = /*@__PURE__*/ new Vector3();
24334	function getLuminanceFunction() {
24335	    ColorManagement.getLuminanceCoefficients(_v0);
24336	    const r = _v0.x.toFixed(4);
24337	    const g = _v0.y.toFixed(4);
24338	    const b = _v0.z.toFixed(4);
24339	    return [
24340	        'float luminance( const in vec3 rgb ) {',
24341	        `	const vec3 weights = vec3( ${r}, ${g}, ${b} );`,
24342	        '	return dot( weights, rgb );',
24343	        '}'
24344	    ].join('\n');
24345	}
24346	function generateVertexExtensions(parameters) {
24347	    const chunks = [
24348	        parameters.extensionClipCullDistance ? '#extension GL_ANGLE_clip_cull_distance : require' : '',
24349	        parameters.extensionMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : ''
24350	    ];
24351	    return chunks.filter(filterEmptyLine).join('\n');
24352	}
24353	function generateDefines(defines) {
24354	    const chunks = [];
24355	    for(const name in defines){
24356	        const value = defines[name];
24357	        if (value === false) continue;
24358	        chunks.push('#define ' + name + ' ' + value);
24359	    }
24360	    return chunks.join('\n');
24361	}
24362	function fetchAttributeLocations(gl, program) {
24363	    const attributes = {};
24364	    const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
vendor: 6,850 bytes, lines 24365-24518
24365	    for(let i = 0; i < n; i++){
24366	        const info = gl.getActiveAttrib(program, i);
24367	        const name = info.name;
24368	        let locationSize = 1;
24369	        if (info.type === gl.FLOAT_MAT2) locationSize = 2;
24370	        if (info.type === gl.FLOAT_MAT3) locationSize = 3;
24371	        if (info.type === gl.FLOAT_MAT4) locationSize = 4;
24372	        // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
24373	        attributes[name] = {
24374	            type: info.type,
24375	            location: gl.getAttribLocation(program, name),
24376	            locationSize: locationSize
24377	        };
24378	    }
24379	    return attributes;
24380	}
24381	function filterEmptyLine(string) {
24382	    return string !== '';
24383	}
24384	function replaceLightNums(string, parameters) {
24385	    const numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps;
24386	    return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g, parameters.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g, numSpotLightCoords).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g, parameters.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows);
24387	}
24388	function replaceClippingPlaneNums(string, parameters) {
24389	    return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection);
24390	}
24391	// Resolve Includes
24392	const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
24393	function resolveIncludes(string) {
24394	    return string.replace(includePattern, includeReplacer);
24395	}
24396	const shaderChunkMap = new Map();
24397	function includeReplacer(match, include) {
24398	    let string = ShaderChunk[include];
24399	    if (string === undefined) {
24400	        const newInclude = shaderChunkMap.get(include);
24401	        if (newInclude !== undefined) {
24402	            string = ShaderChunk[newInclude];
24403	            console.warn('THREE.WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.', include, newInclude);
24404	        } else {
24405	            throw new Error('Can not resolve #include <' + include + '>');
24406	        }
24407	    }
24408	    return resolveIncludes(string);
24409	}
24410	// Unroll Loops
24411	const unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;
24412	function unrollLoops(string) {
24413	    return string.replace(unrollLoopPattern, loopReplacer);
24414	}
24415	function loopReplacer(match, start, end, snippet) {
24416	    let string = '';
24417	    for(let i = parseInt(start); i < parseInt(end); i++){
24418	        string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i);
24419	    }
24420	    return string;
24421	}
24422	//
24423	function generatePrecision(parameters) {
24424	    let precisionstring = `precision ${parameters.precision} float;
24425	precision ${parameters.precision} int;
24426	precision ${parameters.precision} sampler2D;
24427	precision ${parameters.precision} samplerCube;
24428	precision ${parameters.precision} sampler3D;
24429	precision ${parameters.precision} sampler2DArray;
24430	precision ${parameters.precision} sampler2DShadow;
24431	precision ${parameters.precision} samplerCubeShadow;
24432	precision ${parameters.precision} sampler2DArrayShadow;
24433	precision ${parameters.precision} isampler2D;
24434	precision ${parameters.precision} isampler3D;
24435	precision ${parameters.precision} isamplerCube;
24436	precision ${parameters.precision} isampler2DArray;
24437	precision ${parameters.precision} usampler2D;
24438	precision ${parameters.precision} usampler3D;
24439	precision ${parameters.precision} usamplerCube;
24440	precision ${parameters.precision} usampler2DArray;
24441	`;
24442	    if (parameters.precision === 'highp') {
24443	        precisionstring += '\n#define HIGH_PRECISION';
24444	    } else if (parameters.precision === 'mediump') {
24445	        precisionstring += '\n#define MEDIUM_PRECISION';
24446	    } else if (parameters.precision === 'lowp') {
24447	        precisionstring += '\n#define LOW_PRECISION';
24448	    }
24449	    return precisionstring;
24450	}
24451	function generateShadowMapTypeDefine(parameters) {
24452	    let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
24453	    if (parameters.shadowMapType === PCFShadowMap) {
24454	        shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
24455	    } else if (parameters.shadowMapType === PCFSoftShadowMap) {
24456	        shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
24457	    } else if (parameters.shadowMapType === VSMShadowMap) {
24458	        shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
24459	    }
24460	    return shadowMapTypeDefine;
24461	}
24462	function generateEnvMapTypeDefine(parameters) {
24463	    let envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
24464	    if (parameters.envMap) {
24465	        switch(parameters.envMapMode){
24466	            case CubeReflectionMapping:
24467	            case CubeRefractionMapping:
24468	                envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
24469	                break;
24470	            case CubeUVReflectionMapping:
24471	                envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
24472	                break;
24473	        }
24474	    }
24475	    return envMapTypeDefine;
24476	}
24477	function generateEnvMapModeDefine(parameters) {
24478	    let envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
24479	    if (parameters.envMap) {
24480	        switch(parameters.envMapMode){
24481	            case CubeRefractionMapping:
24482	                envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
24483	                break;
24484	        }
24485	    }
24486	    return envMapModeDefine;
24487	}
24488	function generateEnvMapBlendingDefine(parameters) {
24489	    let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
24490	    if (parameters.envMap) {
24491	        switch(parameters.combine){
24492	            case MultiplyOperation:
24493	                envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
24494	                break;
24495	            case MixOperation:
24496	                envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
24497	                break;
24498	            case AddOperation:
24499	                envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
24500	                break;
24501	        }
24502	    }
24503	    return envMapBlendingDefine;
24504	}
24505	function generateCubeUVSize(parameters) {
24506	    const imageHeight = parameters.envMapCubeUVHeight;
24507	    if (imageHeight === null) return null;
24508	    const maxMip = Math.log2(imageHeight) - 2;
24509	    const texelHeight = 1.0 / imageHeight;
24510	    const texelWidth = 1.0 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16));
24511	    return {
24512	        texelWidth,
24513	        texelHeight,
24514	        maxMip
24515	    };
24516	}
24517	function WebGLProgram(renderer, cacheKey, parameters, bindingStates) {
24518	    // TODO Send this event to Three.js DevTools
vendor: 43,794 bytes, lines 24519-25300
24519	    // console.log( 'WebGLProgram', cacheKey );
24520	    const gl = renderer.getContext();
24521	    const defines = parameters.defines;
24522	    let vertexShader = parameters.vertexShader;
24523	    let fragmentShader = parameters.fragmentShader;
24524	    const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters);
24525	    const envMapTypeDefine = generateEnvMapTypeDefine(parameters);
24526	    const envMapModeDefine = generateEnvMapModeDefine(parameters);
24527	    const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters);
24528	    const envMapCubeUVSize = generateCubeUVSize(parameters);
24529	    const customVertexExtensions = generateVertexExtensions(parameters);
24530	    const customDefines = generateDefines(defines);
24531	    const program = gl.createProgram();
24532	    let prefixVertex, prefixFragment;
24533	    let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
24534	    if (parameters.isRawShaderMaterial) {
24535	        prefixVertex = [
24536	            '#define SHADER_TYPE ' + parameters.shaderType,
24537	            '#define SHADER_NAME ' + parameters.shaderName,
24538	            customDefines
24539	        ].filter(filterEmptyLine).join('\n');
24540	        if (prefixVertex.length > 0) {
24541	            prefixVertex += '\n';
24542	        }
24543	        prefixFragment = [
24544	            '#define SHADER_TYPE ' + parameters.shaderType,
24545	            '#define SHADER_NAME ' + parameters.shaderName,
24546	            customDefines
24547	        ].filter(filterEmptyLine).join('\n');
24548	        if (prefixFragment.length > 0) {
24549	            prefixFragment += '\n';
24550	        }
24551	    } else {
24552	        prefixVertex = [
24553	            generatePrecision(parameters),
24554	            '#define SHADER_TYPE ' + parameters.shaderType,
24555	            '#define SHADER_NAME ' + parameters.shaderName,
24556	            customDefines,
24557	            parameters.extensionClipCullDistance ? '#define USE_CLIP_DISTANCE' : '',
24558	            parameters.batching ? '#define USE_BATCHING' : '',
24559	            parameters.batchingColor ? '#define USE_BATCHING_COLOR' : '',
24560	            parameters.instancing ? '#define USE_INSTANCING' : '',
24561	            parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '',
24562	            parameters.instancingMorph ? '#define USE_INSTANCING_MORPH' : '',
24563	            parameters.useFog && parameters.fog ? '#define USE_FOG' : '',
24564	            parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '',
24565	            parameters.map ? '#define USE_MAP' : '',
24566	            parameters.envMap ? '#define USE_ENVMAP' : '',
24567	            parameters.envMap ? '#define ' + envMapModeDefine : '',
24568	            parameters.lightMap ? '#define USE_LIGHTMAP' : '',
24569	            parameters.aoMap ? '#define USE_AOMAP' : '',
24570	            parameters.bumpMap ? '#define USE_BUMPMAP' : '',
24571	            parameters.normalMap ? '#define USE_NORMALMAP' : '',
24572	            parameters.normalMapObjectSpace ? '#define USE_NORMALMAP_OBJECTSPACE' : '',
24573	            parameters.normalMapTangentSpace ? '#define USE_NORMALMAP_TANGENTSPACE' : '',
24574	            parameters.displacementMap ? '#define USE_DISPLACEMENTMAP' : '',
24575	            parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
24576	            parameters.anisotropy ? '#define USE_ANISOTROPY' : '',
24577	            parameters.anisotropyMap ? '#define USE_ANISOTROPYMAP' : '',
24578	            parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
24579	            parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
24580	            parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
24581	            parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '',
24582	            parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '',
24583	            parameters.specularMap ? '#define USE_SPECULARMAP' : '',
24584	            parameters.specularColorMap ? '#define USE_SPECULAR_COLORMAP' : '',
24585	            parameters.specularIntensityMap ? '#define USE_SPECULAR_INTENSITYMAP' : '',
24586	            parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
24587	            parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
24588	            parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
24589	            parameters.alphaHash ? '#define USE_ALPHAHASH' : '',
24590	            parameters.transmission ? '#define USE_TRANSMISSION' : '',
24591	            parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
24592	            parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
24593	            parameters.sheenColorMap ? '#define USE_SHEEN_COLORMAP' : '',
24594	            parameters.sheenRoughnessMap ? '#define USE_SHEEN_ROUGHNESSMAP' : '',
24595	            //
24596	            parameters.mapUv ? '#define MAP_UV ' + parameters.mapUv : '',
24597	            parameters.alphaMapUv ? '#define ALPHAMAP_UV ' + parameters.alphaMapUv : '',
24598	            parameters.lightMapUv ? '#define LIGHTMAP_UV ' + parameters.lightMapUv : '',
24599	            parameters.aoMapUv ? '#define AOMAP_UV ' + parameters.aoMapUv : '',
24600	            parameters.emissiveMapUv ? '#define EMISSIVEMAP_UV ' + parameters.emissiveMapUv : '',
24601	            parameters.bumpMapUv ? '#define BUMPMAP_UV ' + parameters.bumpMapUv : '',
24602	            parameters.normalMapUv ? '#define NORMALMAP_UV ' + parameters.normalMapUv : '',
24603	            parameters.displacementMapUv ? '#define DISPLACEMENTMAP_UV ' + parameters.displacementMapUv : '',
24604	            parameters.metalnessMapUv ? '#define METALNESSMAP_UV ' + parameters.metalnessMapUv : '',
24605	            parameters.roughnessMapUv ? '#define ROUGHNESSMAP_UV ' + parameters.roughnessMapUv : '',
24606	            parameters.anisotropyMapUv ? '#define ANISOTROPYMAP_UV ' + parameters.anisotropyMapUv : '',
24607	            parameters.clearcoatMapUv ? '#define CLEARCOATMAP_UV ' + parameters.clearcoatMapUv : '',
24608	            parameters.clearcoatNormalMapUv ? '#define CLEARCOAT_NORMALMAP_UV ' + parameters.clearcoatNormalMapUv : '',
24609	            parameters.clearcoatRoughnessMapUv ? '#define CLEARCOAT_ROUGHNESSMAP_UV ' + parameters.clearcoatRoughnessMapUv : '',
24610	            parameters.iridescenceMapUv ? '#define IRIDESCENCEMAP_UV ' + parameters.iridescenceMapUv : '',
24611	            parameters.iridescenceThicknessMapUv ? '#define IRIDESCENCE_THICKNESSMAP_UV ' + parameters.iridescenceThicknessMapUv : '',
24612	            parameters.sheenColorMapUv ? '#define SHEEN_COLORMAP_UV ' + parameters.sheenColorMapUv : '',
24613	            parameters.sheenRoughnessMapUv ? '#define SHEEN_ROUGHNESSMAP_UV ' + parameters.sheenRoughnessMapUv : '',
24614	            parameters.specularMapUv ? '#define SPECULARMAP_UV ' + parameters.specularMapUv : '',
24615	            parameters.specularColorMapUv ? '#define SPECULAR_COLORMAP_UV ' + parameters.specularColorMapUv : '',
24616	            parameters.specularIntensityMapUv ? '#define SPECULAR_INTENSITYMAP_UV ' + parameters.specularIntensityMapUv : '',
24617	            parameters.transmissionMapUv ? '#define TRANSMISSIONMAP_UV ' + parameters.transmissionMapUv : '',
24618	            parameters.thicknessMapUv ? '#define THICKNESSMAP_UV ' + parameters.thicknessMapUv : '',
24619	            //
24620	            parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
24621	            parameters.vertexColors ? '#define USE_COLOR' : '',
24622	            parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
24623	            parameters.vertexUv1s ? '#define USE_UV1' : '',
24624	            parameters.vertexUv2s ? '#define USE_UV2' : '',
24625	            parameters.vertexUv3s ? '#define USE_UV3' : '',
24626	            parameters.pointsUvs ? '#define USE_POINTS_UV' : '',
24627	            parameters.flatShading ? '#define FLAT_SHADED' : '',
24628	            parameters.skinning ? '#define USE_SKINNING' : '',
24629	            parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
24630	            parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
24631	            parameters.morphColors ? '#define USE_MORPHCOLORS' : '',
24632	            parameters.morphTargetsCount > 0 ? '#define MORPHTARGETS_TEXTURE_STRIDE ' + parameters.morphTextureStride : '',
24633	            parameters.morphTargetsCount > 0 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '',
24634	            parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
24635	            parameters.flipSided ? '#define FLIP_SIDED' : '',
24636	            parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
24637	            parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
24638	            parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
24639	            parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '',
24640	            parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
24641	            parameters.reverseDepthBuffer ? '#define USE_REVERSEDEPTHBUF' : '',
24642	            'uniform mat4 modelMatrix;',
24643	            'uniform mat4 modelViewMatrix;',
24644	            'uniform mat4 projectionMatrix;',
24645	            'uniform mat4 viewMatrix;',
24646	            'uniform mat3 normalMatrix;',
24647	            'uniform vec3 cameraPosition;',
24648	            'uniform bool isOrthographic;',
24649	            '#ifdef USE_INSTANCING',
24650	            '	attribute mat4 instanceMatrix;',
24651	            '#endif',
24652	            '#ifdef USE_INSTANCING_COLOR',
24653	            '	attribute vec3 instanceColor;',
24654	            '#endif',
24655	            '#ifdef USE_INSTANCING_MORPH',
24656	            '	uniform sampler2D morphTexture;',
24657	            '#endif',
24658	            'attribute vec3 position;',
24659	            'attribute vec3 normal;',
24660	            'attribute vec2 uv;',
24661	            '#ifdef USE_UV1',
24662	            '	attribute vec2 uv1;',
24663	            '#endif',
24664	            '#ifdef USE_UV2',
24665	            '	attribute vec2 uv2;',
24666	            '#endif',
24667	            '#ifdef USE_UV3',
24668	            '	attribute vec2 uv3;',
24669	            '#endif',
24670	            '#ifdef USE_TANGENT',
24671	            '	attribute vec4 tangent;',
24672	            '#endif',
24673	            '#if defined( USE_COLOR_ALPHA )',
24674	            '	attribute vec4 color;',
24675	            '#elif defined( USE_COLOR )',
24676	            '	attribute vec3 color;',
24677	            '#endif',
24678	            '#ifdef USE_SKINNING',
24679	            '	attribute vec4 skinIndex;',
24680	            '	attribute vec4 skinWeight;',
24681	            '#endif',
24682	            '\n'
24683	        ].filter(filterEmptyLine).join('\n');
24684	        prefixFragment = [
24685	            generatePrecision(parameters),
24686	            '#define SHADER_TYPE ' + parameters.shaderType,
24687	            '#define SHADER_NAME ' + parameters.shaderName,
24688	            customDefines,
24689	            parameters.useFog && parameters.fog ? '#define USE_FOG' : '',
24690	            parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '',
24691	            parameters.alphaToCoverage ? '#define ALPHA_TO_COVERAGE' : '',
24692	            parameters.map ? '#define USE_MAP' : '',
24693	            parameters.matcap ? '#define USE_MATCAP' : '',
24694	            parameters.envMap ? '#define USE_ENVMAP' : '',
24695	            parameters.envMap ? '#define ' + envMapTypeDefine : '',
24696	            parameters.envMap ? '#define ' + envMapModeDefine : '',
24697	            parameters.envMap ? '#define ' + envMapBlendingDefine : '',
24698	            envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '',
24699	            envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '',
24700	            envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '',
24701	            parameters.lightMap ? '#define USE_LIGHTMAP' : '',
24702	            parameters.aoMap ? '#define USE_AOMAP' : '',
24703	            parameters.bumpMap ? '#define USE_BUMPMAP' : '',
24704	            parameters.normalMap ? '#define USE_NORMALMAP' : '',
24705	            parameters.normalMapObjectSpace ? '#define USE_NORMALMAP_OBJECTSPACE' : '',
24706	            parameters.normalMapTangentSpace ? '#define USE_NORMALMAP_TANGENTSPACE' : '',
24707	            parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
24708	            parameters.anisotropy ? '#define USE_ANISOTROPY' : '',
24709	            parameters.anisotropyMap ? '#define USE_ANISOTROPYMAP' : '',
24710	            parameters.clearcoat ? '#define USE_CLEARCOAT' : '',
24711	            parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '',
24712	            parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '',
24713	            parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
24714	            parameters.dispersion ? '#define USE_DISPERSION' : '',
24715	            parameters.iridescence ? '#define USE_IRIDESCENCE' : '',
24716	            parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '',
24717	            parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '',
24718	            parameters.specularMap ? '#define USE_SPECULARMAP' : '',
24719	            parameters.specularColorMap ? '#define USE_SPECULAR_COLORMAP' : '',
24720	            parameters.specularIntensityMap ? '#define USE_SPECULAR_INTENSITYMAP' : '',
24721	            parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
24722	            parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
24723	            parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
24724	            parameters.alphaTest ? '#define USE_ALPHATEST' : '',
24725	            parameters.alphaHash ? '#define USE_ALPHAHASH' : '',
24726	            parameters.sheen ? '#define USE_SHEEN' : '',
24727	            parameters.sheenColorMap ? '#define USE_SHEEN_COLORMAP' : '',
24728	            parameters.sheenRoughnessMap ? '#define USE_SHEEN_ROUGHNESSMAP' : '',
24729	            parameters.transmission ? '#define USE_TRANSMISSION' : '',
24730	            parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
24731	            parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
24732	            parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
24733	            parameters.vertexColors || parameters.instancingColor || parameters.batchingColor ? '#define USE_COLOR' : '',
24734	            parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
24735	            parameters.vertexUv1s ? '#define USE_UV1' : '',
24736	            parameters.vertexUv2s ? '#define USE_UV2' : '',
24737	            parameters.vertexUv3s ? '#define USE_UV3' : '',
24738	            parameters.pointsUvs ? '#define USE_POINTS_UV' : '',
24739	            parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
24740	            parameters.flatShading ? '#define FLAT_SHADED' : '',
24741	            parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
24742	            parameters.flipSided ? '#define FLIP_SIDED' : '',
24743	            parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
24744	            parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
24745	            parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
24746	            parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '',
24747	            parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '',
24748	            parameters.decodeVideoTextureEmissive ? '#define DECODE_VIDEO_TEXTURE_EMISSIVE' : '',
24749	            parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
24750	            parameters.reverseDepthBuffer ? '#define USE_REVERSEDEPTHBUF' : '',
24751	            'uniform mat4 viewMatrix;',
24752	            'uniform vec3 cameraPosition;',
24753	            'uniform bool isOrthographic;',
24754	            parameters.toneMapping !== NoToneMapping ? '#define TONE_MAPPING' : '',
24755	            parameters.toneMapping !== NoToneMapping ? ShaderChunk['tonemapping_pars_fragment'] : '',
24756	            parameters.toneMapping !== NoToneMapping ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '',
24757	            parameters.dithering ? '#define DITHERING' : '',
24758	            parameters.opaque ? '#define OPAQUE' : '',
24759	            ShaderChunk['colorspace_pars_fragment'],
24760	            getTexelEncodingFunction('linearToOutputTexel', parameters.outputColorSpace),
24761	            getLuminanceFunction(),
24762	            parameters.useDepthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '',
24763	            '\n'
24764	        ].filter(filterEmptyLine).join('\n');
24765	    }
24766	    vertexShader = resolveIncludes(vertexShader);
24767	    vertexShader = replaceLightNums(vertexShader, parameters);
24768	    vertexShader = replaceClippingPlaneNums(vertexShader, parameters);
24769	    fragmentShader = resolveIncludes(fragmentShader);
24770	    fragmentShader = replaceLightNums(fragmentShader, parameters);
24771	    fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters);
24772	    vertexShader = unrollLoops(vertexShader);
24773	    fragmentShader = unrollLoops(fragmentShader);
24774	    if (parameters.isRawShaderMaterial !== true) {
24775	        // GLSL 3.0 conversion for built-in materials and ShaderMaterial
24776	        versionString = '#version 300 es\n';
24777	        prefixVertex = [
24778	            customVertexExtensions,
24779	            '#define attribute in',
24780	            '#define varying out',
24781	            '#define texture2D texture'
24782	        ].join('\n') + '\n' + prefixVertex;
24783	        prefixFragment = [
24784	            '#define varying in',
24785	            parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;',
24786	            parameters.glslVersion === GLSL3 ? '' : '#define gl_FragColor pc_fragColor',
24787	            '#define gl_FragDepthEXT gl_FragDepth',
24788	            '#define texture2D texture',
24789	            '#define textureCube texture',
24790	            '#define texture2DProj textureProj',
24791	            '#define texture2DLodEXT textureLod',
24792	            '#define texture2DProjLodEXT textureProjLod',
24793	            '#define textureCubeLodEXT textureLod',
24794	            '#define texture2DGradEXT textureGrad',
24795	            '#define texture2DProjGradEXT textureProjGrad',
24796	            '#define textureCubeGradEXT textureGrad'
24797	        ].join('\n') + '\n' + prefixFragment;
24798	    }
24799	    const vertexGlsl = versionString + prefixVertex + vertexShader;
24800	    const fragmentGlsl = versionString + prefixFragment + fragmentShader;
24801	    // console.log( '*VERTEX*', vertexGlsl );
24802	    // console.log( '*FRAGMENT*', fragmentGlsl );
24803	    const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl);
24804	    const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl);
24805	    gl.attachShader(program, glVertexShader);
24806	    gl.attachShader(program, glFragmentShader);
24807	    // Force a particular attribute to index 0.
24808	    if (parameters.index0AttributeName !== undefined) {
24809	        gl.bindAttribLocation(program, 0, parameters.index0AttributeName);
24810	    } else if (parameters.morphTargets === true) {
24811	        // programs with morphTargets displace position out of attribute 0
24812	        gl.bindAttribLocation(program, 0, 'position');
24813	    }
24814	    gl.linkProgram(program);
24815	    function onFirstUse(self1) {
24816	        // check for link errors
24817	        if (renderer.debug.checkShaderErrors) {
24818	            const programLog = gl.getProgramInfoLog(program).trim();
24819	            const vertexLog = gl.getShaderInfoLog(glVertexShader).trim();
24820	            const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim();
24821	            let runnable = true;
24822	            let haveDiagnostics = true;
24823	            if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) {
24824	                runnable = false;
24825	                if (typeof renderer.debug.onShaderError === 'function') {
24826	                    renderer.debug.onShaderError(gl, program, glVertexShader, glFragmentShader);
24827	                } else {
24828	                    // default error reporting
24829	                    const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex');
24830	                    const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment');
24831	                    console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Material Name: ' + self1.name + '\n' + 'Material Type: ' + self1.type + '\n\n' + 'Program Info Log: ' + programLog + '\n' + vertexErrors + '\n' + fragmentErrors);
24832	                }
24833	            } else if (programLog !== '') {
24834	                console.warn('THREE.WebGLProgram: Program Info Log:', programLog);
24835	            } else if (vertexLog === '' || fragmentLog === '') {
24836	                haveDiagnostics = false;
24837	            }
24838	            if (haveDiagnostics) {
24839	                self1.diagnostics = {
24840	                    runnable: runnable,
24841	                    programLog: programLog,
24842	                    vertexShader: {
24843	                        log: vertexLog,
24844	                        prefix: prefixVertex
24845	                    },
24846	                    fragmentShader: {
24847	                        log: fragmentLog,
24848	                        prefix: prefixFragment
24849	                    }
24850	                };
24851	            }
24852	        }
24853	        // Clean up
24854	        // Crashes in iOS9 and iOS10. #18402
24855	        // gl.detachShader( program, glVertexShader );
24856	        // gl.detachShader( program, glFragmentShader );
24857	        gl.deleteShader(glVertexShader);
24858	        gl.deleteShader(glFragmentShader);
24859	        cachedUniforms = new WebGLUniforms(gl, program);
24860	        cachedAttributes = fetchAttributeLocations(gl, program);
24861	    }
24862	    // set up caching for uniform locations
24863	    let cachedUniforms;
24864	    this.getUniforms = function() {
24865	        if (cachedUniforms === undefined) {
24866	            // Populates cachedUniforms and cachedAttributes
24867	            onFirstUse(this);
24868	        }
24869	        return cachedUniforms;
24870	    };
24871	    // set up caching for attribute locations
24872	    let cachedAttributes;
24873	    this.getAttributes = function() {
24874	        if (cachedAttributes === undefined) {
24875	            // Populates cachedAttributes and cachedUniforms
24876	            onFirstUse(this);
24877	        }
24878	        return cachedAttributes;
24879	    };
24880	    // indicate when the program is ready to be used. if the KHR_parallel_shader_compile extension isn't supported,
24881	    // flag the program as ready immediately. It may cause a stall when it's first used.
24882	    let programReady = parameters.rendererExtensionParallelShaderCompile === false;
24883	    this.isReady = function() {
24884	        if (programReady === false) {
24885	            programReady = gl.getProgramParameter(program, COMPLETION_STATUS_KHR);
24886	        }
24887	        return programReady;
24888	    };
24889	    // free resource
24890	    this.destroy = function() {
24891	        bindingStates.releaseStatesOfProgram(this);
24892	        gl.deleteProgram(program);
24893	        this.program = undefined;
24894	    };
24895	    //
24896	    this.type = parameters.shaderType;
24897	    this.name = parameters.shaderName;
24898	    this.id = programIdCount++;
24899	    this.cacheKey = cacheKey;
24900	    this.usedTimes = 1;
24901	    this.program = program;
24902	    this.vertexShader = glVertexShader;
24903	    this.fragmentShader = glFragmentShader;
24904	    return this;
24905	}
24906	let _id = 0;
24907	class WebGLShaderCache {
24908	    update(material) {
24909	        const vertexShader = material.vertexShader;
24910	        const fragmentShader = material.fragmentShader;
24911	        const vertexShaderStage = this._getShaderStage(vertexShader);
24912	        const fragmentShaderStage = this._getShaderStage(fragmentShader);
24913	        const materialShaders = this._getShaderCacheForMaterial(material);
24914	        if (materialShaders.has(vertexShaderStage) === false) {
24915	            materialShaders.add(vertexShaderStage);
24916	            vertexShaderStage.usedTimes++;
24917	        }
24918	        if (materialShaders.has(fragmentShaderStage) === false) {
24919	            materialShaders.add(fragmentShaderStage);
24920	            fragmentShaderStage.usedTimes++;
24921	        }
24922	        return this;
24923	    }
24924	    remove(material) {
24925	        const materialShaders = this.materialCache.get(material);
24926	        for (const shaderStage of materialShaders){
24927	            shaderStage.usedTimes--;
24928	            if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code);
24929	        }
24930	        this.materialCache.delete(material);
24931	        return this;
24932	    }
24933	    getVertexShaderID(material) {
24934	        return this._getShaderStage(material.vertexShader).id;
24935	    }
24936	    getFragmentShaderID(material) {
24937	        return this._getShaderStage(material.fragmentShader).id;
24938	    }
24939	    dispose() {
24940	        this.shaderCache.clear();
24941	        this.materialCache.clear();
24942	    }
24943	    _getShaderCacheForMaterial(material) {
24944	        const cache = this.materialCache;
24945	        let set = cache.get(material);
24946	        if (set === undefined) {
24947	            set = new Set();
24948	            cache.set(material, set);
24949	        }
24950	        return set;
24951	    }
24952	    _getShaderStage(code) {
24953	        const cache = this.shaderCache;
24954	        let stage = cache.get(code);
24955	        if (stage === undefined) {
24956	            stage = new WebGLShaderStage(code);
24957	            cache.set(code, stage);
24958	        }
24959	        return stage;
24960	    }
24961	    constructor(){
24962	        this.shaderCache = new Map();
24963	        this.materialCache = new Map();
24964	    }
24965	}
24966	class WebGLShaderStage {
24967	    constructor(code){
24968	        this.id = _id++;
24969	        this.code = code;
24970	        this.usedTimes = 0;
24971	    }
24972	}
24973	function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) {
24974	    const _programLayers = new Layers();
24975	    const _customShaders = new WebGLShaderCache();
24976	    const _activeChannels = new Set();
24977	    const programs = [];
24978	    const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
24979	    const SUPPORTS_VERTEX_TEXTURES = capabilities.vertexTextures;
24980	    let precision = capabilities.precision;
24981	    const shaderIDs = {
24982	        MeshDepthMaterial: 'depth',
24983	        MeshDistanceMaterial: 'distanceRGBA',
24984	        MeshNormalMaterial: 'normal',
24985	        MeshBasicMaterial: 'basic',
24986	        MeshLambertMaterial: 'lambert',
24987	        MeshPhongMaterial: 'phong',
24988	        MeshToonMaterial: 'toon',
24989	        MeshStandardMaterial: 'physical',
24990	        MeshPhysicalMaterial: 'physical',
24991	        MeshMatcapMaterial: 'matcap',
24992	        LineBasicMaterial: 'basic',
24993	        LineDashedMaterial: 'dashed',
24994	        PointsMaterial: 'points',
24995	        ShadowMaterial: 'shadow',
24996	        SpriteMaterial: 'sprite'
24997	    };
24998	    function getChannel(value) {
24999	        _activeChannels.add(value);
25000	        if (value === 0) return 'uv';
25001	        return `uv${value}`;
25002	    }
25003	    function getParameters(material, lights, shadows, scene, object) {
25004	        const fog = scene.fog;
25005	        const geometry = object.geometry;
25006	        const environment = material.isMeshStandardMaterial ? scene.environment : null;
25007	        const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
25008	        const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null;
25009	        const shaderID = shaderIDs[material.type];
25010	        // heuristics to create shader parameters according to lights in the scene
25011	        // (not to blow over maxLights budget)
25012	        if (material.precision !== null) {
25013	            precision = capabilities.getMaxPrecision(material.precision);
25014	            if (precision !== material.precision) {
25015	                console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.');
25016	            }
25017	        }
25018	        //
25019	        const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
25020	        const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
25021	        let morphTextureStride = 0;
25022	        if (geometry.morphAttributes.position !== undefined) morphTextureStride = 1;
25023	        if (geometry.morphAttributes.normal !== undefined) morphTextureStride = 2;
25024	        if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3;
25025	        //
25026	        let vertexShader, fragmentShader;
25027	        let customVertexShaderID, customFragmentShaderID;
25028	        if (shaderID) {
25029	            const shader = ShaderLib[shaderID];
25030	            vertexShader = shader.vertexShader;
25031	            fragmentShader = shader.fragmentShader;
25032	        } else {
25033	            vertexShader = material.vertexShader;
25034	            fragmentShader = material.fragmentShader;
25035	            _customShaders.update(material);
25036	            customVertexShaderID = _customShaders.getVertexShaderID(material);
25037	            customFragmentShaderID = _customShaders.getFragmentShaderID(material);
25038	        }
25039	        const currentRenderTarget = renderer.getRenderTarget();
25040	        const reverseDepthBuffer = renderer.state.buffers.depth.getReversed();
25041	        const IS_INSTANCEDMESH = object.isInstancedMesh === true;
25042	        const IS_BATCHEDMESH = object.isBatchedMesh === true;
25043	        const HAS_MAP = !!material.map;
25044	        const HAS_MATCAP = !!material.matcap;
25045	        const HAS_ENVMAP = !!envMap;
25046	        const HAS_AOMAP = !!material.aoMap;
25047	        const HAS_LIGHTMAP = !!material.lightMap;
25048	        const HAS_BUMPMAP = !!material.bumpMap;
25049	        const HAS_NORMALMAP = !!material.normalMap;
25050	        const HAS_DISPLACEMENTMAP = !!material.displacementMap;
25051	        const HAS_EMISSIVEMAP = !!material.emissiveMap;
25052	        const HAS_METALNESSMAP = !!material.metalnessMap;
25053	        const HAS_ROUGHNESSMAP = !!material.roughnessMap;
25054	        const HAS_ANISOTROPY = material.anisotropy > 0;
25055	        const HAS_CLEARCOAT = material.clearcoat > 0;
25056	        const HAS_DISPERSION = material.dispersion > 0;
25057	        const HAS_IRIDESCENCE = material.iridescence > 0;
25058	        const HAS_SHEEN = material.sheen > 0;
25059	        const HAS_TRANSMISSION = material.transmission > 0;
25060	        const HAS_ANISOTROPYMAP = HAS_ANISOTROPY && !!material.anisotropyMap;
25061	        const HAS_CLEARCOATMAP = HAS_CLEARCOAT && !!material.clearcoatMap;
25062	        const HAS_CLEARCOAT_NORMALMAP = HAS_CLEARCOAT && !!material.clearcoatNormalMap;
25063	        const HAS_CLEARCOAT_ROUGHNESSMAP = HAS_CLEARCOAT && !!material.clearcoatRoughnessMap;
25064	        const HAS_IRIDESCENCEMAP = HAS_IRIDESCENCE && !!material.iridescenceMap;
25065	        const HAS_IRIDESCENCE_THICKNESSMAP = HAS_IRIDESCENCE && !!material.iridescenceThicknessMap;
25066	        const HAS_SHEEN_COLORMAP = HAS_SHEEN && !!material.sheenColorMap;
25067	        const HAS_SHEEN_ROUGHNESSMAP = HAS_SHEEN && !!material.sheenRoughnessMap;
25068	        const HAS_SPECULARMAP = !!material.specularMap;
25069	        const HAS_SPECULAR_COLORMAP = !!material.specularColorMap;
25070	        const HAS_SPECULAR_INTENSITYMAP = !!material.specularIntensityMap;
25071	        const HAS_TRANSMISSIONMAP = HAS_TRANSMISSION && !!material.transmissionMap;
25072	        const HAS_THICKNESSMAP = HAS_TRANSMISSION && !!material.thicknessMap;
25073	        const HAS_GRADIENTMAP = !!material.gradientMap;
25074	        const HAS_ALPHAMAP = !!material.alphaMap;
25075	        const HAS_ALPHATEST = material.alphaTest > 0;
25076	        const HAS_ALPHAHASH = !!material.alphaHash;
25077	        const HAS_EXTENSIONS = !!material.extensions;
25078	        let toneMapping = NoToneMapping;
25079	        if (material.toneMapped) {
25080	            if (currentRenderTarget === null || currentRenderTarget.isXRRenderTarget === true) {
25081	                toneMapping = renderer.toneMapping;
25082	            }
25083	        }
25084	        const parameters = {
25085	            shaderID: shaderID,
25086	            shaderType: material.type,
25087	            shaderName: material.name,
25088	            vertexShader: vertexShader,
25089	            fragmentShader: fragmentShader,
25090	            defines: material.defines,
25091	            customVertexShaderID: customVertexShaderID,
25092	            customFragmentShaderID: customFragmentShaderID,
25093	            isRawShaderMaterial: material.isRawShaderMaterial === true,
25094	            glslVersion: material.glslVersion,
25095	            precision: precision,
25096	            batching: IS_BATCHEDMESH,
25097	            batchingColor: IS_BATCHEDMESH && object._colorsTexture !== null,
25098	            instancing: IS_INSTANCEDMESH,
25099	            instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
25100	            instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null,
25101	            supportsVertexTextures: SUPPORTS_VERTEX_TEXTURES,
25102	            outputColorSpace: currentRenderTarget === null ? renderer.outputColorSpace : currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace,
25103	            alphaToCoverage: !!material.alphaToCoverage,
25104	            map: HAS_MAP,
25105	            matcap: HAS_MATCAP,
25106	            envMap: HAS_ENVMAP,
25107	            envMapMode: HAS_ENVMAP && envMap.mapping,
25108	            envMapCubeUVHeight: envMapCubeUVHeight,
25109	            aoMap: HAS_AOMAP,
25110	            lightMap: HAS_LIGHTMAP,
25111	            bumpMap: HAS_BUMPMAP,
25112	            normalMap: HAS_NORMALMAP,
25113	            displacementMap: SUPPORTS_VERTEX_TEXTURES && HAS_DISPLACEMENTMAP,
25114	            emissiveMap: HAS_EMISSIVEMAP,
25115	            normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap,
25116	            normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap,
25117	            metalnessMap: HAS_METALNESSMAP,
25118	            roughnessMap: HAS_ROUGHNESSMAP,
25119	            anisotropy: HAS_ANISOTROPY,
25120	            anisotropyMap: HAS_ANISOTROPYMAP,
25121	            clearcoat: HAS_CLEARCOAT,
25122	            clearcoatMap: HAS_CLEARCOATMAP,
25123	            clearcoatNormalMap: HAS_CLEARCOAT_NORMALMAP,
25124	            clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP,
25125	            dispersion: HAS_DISPERSION,
25126	            iridescence: HAS_IRIDESCENCE,
25127	            iridescenceMap: HAS_IRIDESCENCEMAP,
25128	            iridescenceThicknessMap: HAS_IRIDESCENCE_THICKNESSMAP,
25129	            sheen: HAS_SHEEN,
25130	            sheenColorMap: HAS_SHEEN_COLORMAP,
25131	            sheenRoughnessMap: HAS_SHEEN_ROUGHNESSMAP,
25132	            specularMap: HAS_SPECULARMAP,
25133	            specularColorMap: HAS_SPECULAR_COLORMAP,
25134	            specularIntensityMap: HAS_SPECULAR_INTENSITYMAP,
25135	            transmission: HAS_TRANSMISSION,
25136	            transmissionMap: HAS_TRANSMISSIONMAP,
25137	            thicknessMap: HAS_THICKNESSMAP,
25138	            gradientMap: HAS_GRADIENTMAP,
25139	            opaque: material.transparent === false && material.blending === NormalBlending && material.alphaToCoverage === false,
25140	            alphaMap: HAS_ALPHAMAP,
25141	            alphaTest: HAS_ALPHATEST,
25142	            alphaHash: HAS_ALPHAHASH,
25143	            combine: material.combine,
25144	            //
25145	            mapUv: HAS_MAP && getChannel(material.map.channel),
25146	            aoMapUv: HAS_AOMAP && getChannel(material.aoMap.channel),
25147	            lightMapUv: HAS_LIGHTMAP && getChannel(material.lightMap.channel),
25148	            bumpMapUv: HAS_BUMPMAP && getChannel(material.bumpMap.channel),
25149	            normalMapUv: HAS_NORMALMAP && getChannel(material.normalMap.channel),
25150	            displacementMapUv: HAS_DISPLACEMENTMAP && getChannel(material.displacementMap.channel),
25151	            emissiveMapUv: HAS_EMISSIVEMAP && getChannel(material.emissiveMap.channel),
25152	            metalnessMapUv: HAS_METALNESSMAP && getChannel(material.metalnessMap.channel),
25153	            roughnessMapUv: HAS_ROUGHNESSMAP && getChannel(material.roughnessMap.channel),
25154	            anisotropyMapUv: HAS_ANISOTROPYMAP && getChannel(material.anisotropyMap.channel),
25155	            clearcoatMapUv: HAS_CLEARCOATMAP && getChannel(material.clearcoatMap.channel),
25156	            clearcoatNormalMapUv: HAS_CLEARCOAT_NORMALMAP && getChannel(material.clearcoatNormalMap.channel),
25157	            clearcoatRoughnessMapUv: HAS_CLEARCOAT_ROUGHNESSMAP && getChannel(material.clearcoatRoughnessMap.channel),
25158	            iridescenceMapUv: HAS_IRIDESCENCEMAP && getChannel(material.iridescenceMap.channel),
25159	            iridescenceThicknessMapUv: HAS_IRIDESCENCE_THICKNESSMAP && getChannel(material.iridescenceThicknessMap.channel),
25160	            sheenColorMapUv: HAS_SHEEN_COLORMAP && getChannel(material.sheenColorMap.channel),
25161	            sheenRoughnessMapUv: HAS_SHEEN_ROUGHNESSMAP && getChannel(material.sheenRoughnessMap.channel),
25162	            specularMapUv: HAS_SPECULARMAP && getChannel(material.specularMap.channel),
25163	            specularColorMapUv: HAS_SPECULAR_COLORMAP && getChannel(material.specularColorMap.channel),
25164	            specularIntensityMapUv: HAS_SPECULAR_INTENSITYMAP && getChannel(material.specularIntensityMap.channel),
25165	            transmissionMapUv: HAS_TRANSMISSIONMAP && getChannel(material.transmissionMap.channel),
25166	            thicknessMapUv: HAS_THICKNESSMAP && getChannel(material.thicknessMap.channel),
25167	            alphaMapUv: HAS_ALPHAMAP && getChannel(material.alphaMap.channel),
25168	            //
25169	            vertexTangents: !!geometry.attributes.tangent && (HAS_NORMALMAP || HAS_ANISOTROPY),
25170	            vertexColors: material.vertexColors,
25171	            vertexAlphas: material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4,
25172	            pointsUvs: object.isPoints === true && !!geometry.attributes.uv && (HAS_MAP || HAS_ALPHAMAP),
25173	            fog: !!fog,
25174	            useFog: material.fog === true,
25175	            fogExp2: !!fog && fog.isFogExp2,
25176	            flatShading: material.flatShading === true,
25177	            sizeAttenuation: material.sizeAttenuation === true,
25178	            logarithmicDepthBuffer: logarithmicDepthBuffer,
25179	            reverseDepthBuffer: reverseDepthBuffer,
25180	            skinning: object.isSkinnedMesh === true,
25181	            morphTargets: geometry.morphAttributes.position !== undefined,
25182	            morphNormals: geometry.morphAttributes.normal !== undefined,
25183	            morphColors: geometry.morphAttributes.color !== undefined,
25184	            morphTargetsCount: morphTargetsCount,
25185	            morphTextureStride: morphTextureStride,
25186	            numDirLights: lights.directional.length,
25187	            numPointLights: lights.point.length,
25188	            numSpotLights: lights.spot.length,
25189	            numSpotLightMaps: lights.spotLightMap.length,
25190	            numRectAreaLights: lights.rectArea.length,
25191	            numHemiLights: lights.hemi.length,
25192	            numDirLightShadows: lights.directionalShadowMap.length,
25193	            numPointLightShadows: lights.pointShadowMap.length,
25194	            numSpotLightShadows: lights.spotShadowMap.length,
25195	            numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps,
25196	            numLightProbes: lights.numLightProbes,
25197	            numClippingPlanes: clipping.numPlanes,
25198	            numClipIntersection: clipping.numIntersection,
25199	            dithering: material.dithering,
25200	            shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
25201	            shadowMapType: renderer.shadowMap.type,
25202	            toneMapping: toneMapping,
25203	            decodeVideoTexture: HAS_MAP && material.map.isVideoTexture === true && ColorManagement.getTransfer(material.map.colorSpace) === SRGBTransfer,
25204	            decodeVideoTextureEmissive: HAS_EMISSIVEMAP && material.emissiveMap.isVideoTexture === true && ColorManagement.getTransfer(material.emissiveMap.colorSpace) === SRGBTransfer,
25205	            premultipliedAlpha: material.premultipliedAlpha,
25206	            doubleSided: material.side === DoubleSide,
25207	            flipSided: material.side === BackSide,
25208	            useDepthPacking: material.depthPacking >= 0,
25209	            depthPacking: material.depthPacking || 0,
25210	            index0AttributeName: material.index0AttributeName,
25211	            extensionClipCullDistance: HAS_EXTENSIONS && material.extensions.clipCullDistance === true && extensions.has('WEBGL_clip_cull_distance'),
25212	            extensionMultiDraw: (HAS_EXTENSIONS && material.extensions.multiDraw === true || IS_BATCHEDMESH) && extensions.has('WEBGL_multi_draw'),
25213	            rendererExtensionParallelShaderCompile: extensions.has('KHR_parallel_shader_compile'),
25214	            customProgramCacheKey: material.customProgramCacheKey()
25215	        };
25216	        // the usage of getChannel() determines the active texture channels for this shader
25217	        parameters.vertexUv1s = _activeChannels.has(1);
25218	        parameters.vertexUv2s = _activeChannels.has(2);
25219	        parameters.vertexUv3s = _activeChannels.has(3);
25220	        _activeChannels.clear();
25221	        return parameters;
25222	    }
25223	    function getProgramCacheKey(parameters) {
25224	        const array = [];
25225	        if (parameters.shaderID) {
25226	            array.push(parameters.shaderID);
25227	        } else {
25228	            array.push(parameters.customVertexShaderID);
25229	            array.push(parameters.customFragmentShaderID);
25230	        }
25231	        if (parameters.defines !== undefined) {
25232	            for(const name in parameters.defines){
25233	                array.push(name);
25234	                array.push(parameters.defines[name]);
25235	            }
25236	        }
25237	        if (parameters.isRawShaderMaterial === false) {
25238	            getProgramCacheKeyParameters(array, parameters);
25239	            getProgramCacheKeyBooleans(array, parameters);
25240	            array.push(renderer.outputColorSpace);
25241	        }
25242	        array.push(parameters.customProgramCacheKey);
25243	        return array.join();
25244	    }
25245	    function getProgramCacheKeyParameters(array, parameters) {
25246	        array.push(parameters.precision);
25247	        array.push(parameters.outputColorSpace);
25248	        array.push(parameters.envMapMode);
25249	        array.push(parameters.envMapCubeUVHeight);
25250	        array.push(parameters.mapUv);
25251	        array.push(parameters.alphaMapUv);
25252	        array.push(parameters.lightMapUv);
25253	        array.push(parameters.aoMapUv);
25254	        array.push(parameters.bumpMapUv);
25255	        array.push(parameters.normalMapUv);
25256	        array.push(parameters.displacementMapUv);
25257	        array.push(parameters.emissiveMapUv);
25258	        array.push(parameters.metalnessMapUv);
25259	        array.push(parameters.roughnessMapUv);
25260	        array.push(parameters.anisotropyMapUv);
25261	        array.push(parameters.clearcoatMapUv);
25262	        array.push(parameters.clearcoatNormalMapUv);
25263	        array.push(parameters.clearcoatRoughnessMapUv);
25264	        array.push(parameters.iridescenceMapUv);
25265	        array.push(parameters.iridescenceThicknessMapUv);
25266	        array.push(parameters.sheenColorMapUv);
25267	        array.push(parameters.sheenRoughnessMapUv);
25268	        array.push(parameters.specularMapUv);
25269	        array.push(parameters.specularColorMapUv);
25270	        array.push(parameters.specularIntensityMapUv);
25271	        array.push(parameters.transmissionMapUv);
25272	        array.push(parameters.thicknessMapUv);
25273	        array.push(parameters.combine);
25274	        array.push(parameters.fogExp2);
25275	        array.push(parameters.sizeAttenuation);
25276	        array.push(parameters.morphTargetsCount);
25277	        array.push(parameters.morphAttributeCount);
25278	        array.push(parameters.numDirLights);
25279	        array.push(parameters.numPointLights);
25280	        array.push(parameters.numSpotLights);
25281	        array.push(parameters.numSpotLightMaps);
25282	        array.push(parameters.numHemiLights);
25283	        array.push(parameters.numRectAreaLights);
25284	        array.push(parameters.numDirLightShadows);
25285	        array.push(parameters.numPointLightShadows);
25286	        array.push(parameters.numSpotLightShadows);
25287	        array.push(parameters.numSpotLightShadowsWithMaps);
25288	        array.push(parameters.numLightProbes);
25289	        array.push(parameters.shadowMapType);
25290	        array.push(parameters.toneMapping);
25291	        array.push(parameters.numClippingPlanes);
25292	        array.push(parameters.numClipIntersection);
25293	        array.push(parameters.depthPacking);
25294	    }
25295	    function getProgramCacheKeyBooleans(array, parameters) {
25296	        _programLayers.disableAll();
25297	        if (parameters.supportsVertexTextures) _programLayers.enable(0);
25298	        if (parameters.instancing) _programLayers.enable(1);
25299	        if (parameters.instancingColor) _programLayers.enable(2);
25300	        if (parameters.instancingMorph) _programLayers.enable(3);
vendor: 4,588 bytes, lines 25301-25397
25301	        if (parameters.matcap) _programLayers.enable(4);
25302	        if (parameters.envMap) _programLayers.enable(5);
25303	        if (parameters.normalMapObjectSpace) _programLayers.enable(6);
25304	        if (parameters.normalMapTangentSpace) _programLayers.enable(7);
25305	        if (parameters.clearcoat) _programLayers.enable(8);
25306	        if (parameters.iridescence) _programLayers.enable(9);
25307	        if (parameters.alphaTest) _programLayers.enable(10);
25308	        if (parameters.vertexColors) _programLayers.enable(11);
25309	        if (parameters.vertexAlphas) _programLayers.enable(12);
25310	        if (parameters.vertexUv1s) _programLayers.enable(13);
25311	        if (parameters.vertexUv2s) _programLayers.enable(14);
25312	        if (parameters.vertexUv3s) _programLayers.enable(15);
25313	        if (parameters.vertexTangents) _programLayers.enable(16);
25314	        if (parameters.anisotropy) _programLayers.enable(17);
25315	        if (parameters.alphaHash) _programLayers.enable(18);
25316	        if (parameters.batching) _programLayers.enable(19);
25317	        if (parameters.dispersion) _programLayers.enable(20);
25318	        if (parameters.batchingColor) _programLayers.enable(21);
25319	        array.push(_programLayers.mask);
25320	        _programLayers.disableAll();
25321	        if (parameters.fog) _programLayers.enable(0);
25322	        if (parameters.useFog) _programLayers.enable(1);
25323	        if (parameters.flatShading) _programLayers.enable(2);
25324	        if (parameters.logarithmicDepthBuffer) _programLayers.enable(3);
25325	        if (parameters.reverseDepthBuffer) _programLayers.enable(4);
25326	        if (parameters.skinning) _programLayers.enable(5);
25327	        if (parameters.morphTargets) _programLayers.enable(6);
25328	        if (parameters.morphNormals) _programLayers.enable(7);
25329	        if (parameters.morphColors) _programLayers.enable(8);
25330	        if (parameters.premultipliedAlpha) _programLayers.enable(9);
25331	        if (parameters.shadowMapEnabled) _programLayers.enable(10);
25332	        if (parameters.doubleSided) _programLayers.enable(11);
25333	        if (parameters.flipSided) _programLayers.enable(12);
25334	        if (parameters.useDepthPacking) _programLayers.enable(13);
25335	        if (parameters.dithering) _programLayers.enable(14);
25336	        if (parameters.transmission) _programLayers.enable(15);
25337	        if (parameters.sheen) _programLayers.enable(16);
25338	        if (parameters.opaque) _programLayers.enable(17);
25339	        if (parameters.pointsUvs) _programLayers.enable(18);
25340	        if (parameters.decodeVideoTexture) _programLayers.enable(19);
25341	        if (parameters.decodeVideoTextureEmissive) _programLayers.enable(20);
25342	        if (parameters.alphaToCoverage) _programLayers.enable(21);
25343	        array.push(_programLayers.mask);
25344	    }
25345	    function getUniforms(material) {
25346	        const shaderID = shaderIDs[material.type];
25347	        let uniforms;
25348	        if (shaderID) {
25349	            const shader = ShaderLib[shaderID];
25350	            uniforms = UniformsUtils.clone(shader.uniforms);
25351	        } else {
25352	            uniforms = material.uniforms;
25353	        }
25354	        return uniforms;
25355	    }
25356	    function acquireProgram(parameters, cacheKey) {
25357	        let program;
25358	        // Check if code has been already compiled
25359	        for(let p = 0, pl = programs.length; p < pl; p++){
25360	            const preexistingProgram = programs[p];
25361	            if (preexistingProgram.cacheKey === cacheKey) {
25362	                program = preexistingProgram;
25363	                ++program.usedTimes;
25364	                break;
25365	            }
25366	        }
25367	        if (program === undefined) {
25368	            program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates);
25369	            programs.push(program);
25370	        }
25371	        return program;
25372	    }
25373	    function releaseProgram(program) {
25374	        if (--program.usedTimes === 0) {
25375	            // Remove from unordered set
25376	            const i = programs.indexOf(program);
25377	            programs[i] = programs[programs.length - 1];
25378	            programs.pop();
25379	            // Free WebGL resources
25380	            program.destroy();
25381	        }
25382	    }
25383	    function releaseShaderCache(material) {
25384	        _customShaders.remove(material);
25385	    }
25386	    function dispose() {
25387	        _customShaders.dispose();
25388	    }
25389	    return {
25390	        getParameters: getParameters,
25391	        getProgramCacheKey: getProgramCacheKey,
25392	        getUniforms: getUniforms,
25393	        acquireProgram: acquireProgram,
25394	        releaseProgram: releaseProgram,
25395	        releaseShaderCache: releaseShaderCache,
25396	        // Exposed for resource monitoring & error feedback via renderer.info:
25397	        programs: programs,
vendor: 5,529 bytes, lines 25398-25566
25398	        dispose: dispose
25399	    };
25400	}
25401	function WebGLProperties() {
25402	    let properties = new WeakMap();
25403	    function has(object) {
25404	        return properties.has(object);
25405	    }
25406	    function get(object) {
25407	        let map = properties.get(object);
25408	        if (map === undefined) {
25409	            map = {};
25410	            properties.set(object, map);
25411	        }
25412	        return map;
25413	    }
25414	    function remove(object) {
25415	        properties.delete(object);
25416	    }
25417	    function update(object, key, value) {
25418	        properties.get(object)[key] = value;
25419	    }
25420	    function dispose() {
25421	        properties = new WeakMap();
25422	    }
25423	    return {
25424	        has: has,
25425	        get: get,
25426	        remove: remove,
25427	        update: update,
25428	        dispose: dispose
25429	    };
25430	}
25431	function painterSortStable(a, b) {
25432	    if (a.groupOrder !== b.groupOrder) {
25433	        return a.groupOrder - b.groupOrder;
25434	    } else if (a.renderOrder !== b.renderOrder) {
25435	        return a.renderOrder - b.renderOrder;
25436	    } else if (a.material.id !== b.material.id) {
25437	        return a.material.id - b.material.id;
25438	    } else if (a.z !== b.z) {
25439	        return a.z - b.z;
25440	    } else {
25441	        return a.id - b.id;
25442	    }
25443	}
25444	function reversePainterSortStable(a, b) {
25445	    if (a.groupOrder !== b.groupOrder) {
25446	        return a.groupOrder - b.groupOrder;
25447	    } else if (a.renderOrder !== b.renderOrder) {
25448	        return a.renderOrder - b.renderOrder;
25449	    } else if (a.z !== b.z) {
25450	        return b.z - a.z;
25451	    } else {
25452	        return a.id - b.id;
25453	    }
25454	}
25455	function WebGLRenderList() {
25456	    const renderItems = [];
25457	    let renderItemsIndex = 0;
25458	    const opaque = [];
25459	    const transmissive = [];
25460	    const transparent = [];
25461	    function init() {
25462	        renderItemsIndex = 0;
25463	        opaque.length = 0;
25464	        transmissive.length = 0;
25465	        transparent.length = 0;
25466	    }
25467	    function getNextRenderItem(object, geometry, material, groupOrder, z, group) {
25468	        let renderItem = renderItems[renderItemsIndex];
25469	        if (renderItem === undefined) {
25470	            renderItem = {
25471	                id: object.id,
25472	                object: object,
25473	                geometry: geometry,
25474	                material: material,
25475	                groupOrder: groupOrder,
25476	                renderOrder: object.renderOrder,
25477	                z: z,
25478	                group: group
25479	            };
25480	            renderItems[renderItemsIndex] = renderItem;
25481	        } else {
25482	            renderItem.id = object.id;
25483	            renderItem.object = object;
25484	            renderItem.geometry = geometry;
25485	            renderItem.material = material;
25486	            renderItem.groupOrder = groupOrder;
25487	            renderItem.renderOrder = object.renderOrder;
25488	            renderItem.z = z;
25489	            renderItem.group = group;
25490	        }
25491	        renderItemsIndex++;
25492	        return renderItem;
25493	    }
25494	    function push(object, geometry, material, groupOrder, z, group) {
25495	        const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
25496	        if (material.transmission > 0.0) {
25497	            transmissive.push(renderItem);
25498	        } else if (material.transparent === true) {
25499	            transparent.push(renderItem);
25500	        } else {
25501	            opaque.push(renderItem);
25502	        }
25503	    }
25504	    function unshift(object, geometry, material, groupOrder, z, group) {
25505	        const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
25506	        if (material.transmission > 0.0) {
25507	            transmissive.unshift(renderItem);
25508	        } else if (material.transparent === true) {
25509	            transparent.unshift(renderItem);
25510	        } else {
25511	            opaque.unshift(renderItem);
25512	        }
25513	    }
25514	    function sort(customOpaqueSort, customTransparentSort) {
25515	        if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable);
25516	        if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable);
25517	        if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable);
25518	    }
25519	    function finish() {
25520	        // Clear references from inactive renderItems in the list
25521	        for(let i = renderItemsIndex, il = renderItems.length; i < il; i++){
25522	            const renderItem = renderItems[i];
25523	            if (renderItem.id === null) break;
25524	            renderItem.id = null;
25525	            renderItem.object = null;
25526	            renderItem.geometry = null;
25527	            renderItem.material = null;
25528	            renderItem.group = null;
25529	        }
25530	    }
25531	    return {
25532	        opaque: opaque,
25533	        transmissive: transmissive,
25534	        transparent: transparent,
25535	        init: init,
25536	        push: push,
25537	        unshift: unshift,
25538	        finish: finish,
25539	        sort: sort
25540	    };
25541	}
25542	function WebGLRenderLists() {
25543	    let lists = new WeakMap();
25544	    function get(scene, renderCallDepth) {
25545	        const listArray = lists.get(scene);
25546	        let list;
25547	        if (listArray === undefined) {
25548	            list = new WebGLRenderList();
25549	            lists.set(scene, [
25550	                list
25551	            ]);
25552	        } else {
25553	            if (renderCallDepth >= listArray.length) {
25554	                list = new WebGLRenderList();
25555	                listArray.push(list);
25556	            } else {
25557	                list = listArray[renderCallDepth];
25558	            }
25559	        }
25560	        return list;
25561	    }
25562	    function dispose() {
25563	        lists = new WeakMap();
25564	    }
25565	    return {
25566	        get: get,
vendor: 9,531 bytes, lines 25567-25804
25567	        dispose: dispose
25568	    };
25569	}
25570	function UniformsCache() {
25571	    const lights = {};
25572	    return {
25573	        get: function(light) {
25574	            if (lights[light.id] !== undefined) {
25575	                return lights[light.id];
25576	            }
25577	            let uniforms;
25578	            switch(light.type){
25579	                case 'DirectionalLight':
25580	                    uniforms = {
25581	                        direction: new Vector3(),
25582	                        color: new Color()
25583	                    };
25584	                    break;
25585	                case 'SpotLight':
25586	                    uniforms = {
25587	                        position: new Vector3(),
25588	                        direction: new Vector3(),
25589	                        color: new Color(),
25590	                        distance: 0,
25591	                        coneCos: 0,
25592	                        penumbraCos: 0,
25593	                        decay: 0
25594	                    };
25595	                    break;
25596	                case 'PointLight':
25597	                    uniforms = {
25598	                        position: new Vector3(),
25599	                        color: new Color(),
25600	                        distance: 0,
25601	                        decay: 0
25602	                    };
25603	                    break;
25604	                case 'HemisphereLight':
25605	                    uniforms = {
25606	                        direction: new Vector3(),
25607	                        skyColor: new Color(),
25608	                        groundColor: new Color()
25609	                    };
25610	                    break;
25611	                case 'RectAreaLight':
25612	                    uniforms = {
25613	                        color: new Color(),
25614	                        position: new Vector3(),
25615	                        halfWidth: new Vector3(),
25616	                        halfHeight: new Vector3()
25617	                    };
25618	                    break;
25619	            }
25620	            lights[light.id] = uniforms;
25621	            return uniforms;
25622	        }
25623	    };
25624	}
25625	function ShadowUniformsCache() {
25626	    const lights = {};
25627	    return {
25628	        get: function(light) {
25629	            if (lights[light.id] !== undefined) {
25630	                return lights[light.id];
25631	            }
25632	            let uniforms;
25633	            switch(light.type){
25634	                case 'DirectionalLight':
25635	                    uniforms = {
25636	                        shadowIntensity: 1,
25637	                        shadowBias: 0,
25638	                        shadowNormalBias: 0,
25639	                        shadowRadius: 1,
25640	                        shadowMapSize: new Vector2()
25641	                    };
25642	                    break;
25643	                case 'SpotLight':
25644	                    uniforms = {
25645	                        shadowIntensity: 1,
25646	                        shadowBias: 0,
25647	                        shadowNormalBias: 0,
25648	                        shadowRadius: 1,
25649	                        shadowMapSize: new Vector2()
25650	                    };
25651	                    break;
25652	                case 'PointLight':
25653	                    uniforms = {
25654	                        shadowIntensity: 1,
25655	                        shadowBias: 0,
25656	                        shadowNormalBias: 0,
25657	                        shadowRadius: 1,
25658	                        shadowMapSize: new Vector2(),
25659	                        shadowCameraNear: 1,
25660	                        shadowCameraFar: 1000
25661	                    };
25662	                    break;
25663	            }
25664	            lights[light.id] = uniforms;
25665	            return uniforms;
25666	        }
25667	    };
25668	}
25669	let nextVersion = 0;
25670	function shadowCastingAndTexturingLightsFirst(lightA, lightB) {
25671	    return (lightB.castShadow ? 2 : 0) - (lightA.castShadow ? 2 : 0) + (lightB.map ? 1 : 0) - (lightA.map ? 1 : 0);
25672	}
25673	function WebGLLights(extensions) {
25674	    const cache = new UniformsCache();
25675	    const shadowCache = ShadowUniformsCache();
25676	    const state = {
25677	        version: 0,
25678	        hash: {
25679	            directionalLength: -1,
25680	            pointLength: -1,
25681	            spotLength: -1,
25682	            rectAreaLength: -1,
25683	            hemiLength: -1,
25684	            numDirectionalShadows: -1,
25685	            numPointShadows: -1,
25686	            numSpotShadows: -1,
25687	            numSpotMaps: -1,
25688	            numLightProbes: -1
25689	        },
25690	        ambient: [
25691	            0,
25692	            0,
25693	            0
25694	        ],
25695	        probe: [],
25696	        directional: [],
25697	        directionalShadow: [],
25698	        directionalShadowMap: [],
25699	        directionalShadowMatrix: [],
25700	        spot: [],
25701	        spotLightMap: [],
25702	        spotShadow: [],
25703	        spotShadowMap: [],
25704	        spotLightMatrix: [],
25705	        rectArea: [],
25706	        rectAreaLTC1: null,
25707	        rectAreaLTC2: null,
25708	        point: [],
25709	        pointShadow: [],
25710	        pointShadowMap: [],
25711	        pointShadowMatrix: [],
25712	        hemi: [],
25713	        numSpotLightShadowsWithMaps: 0,
25714	        numLightProbes: 0
25715	    };
25716	    for(let i = 0; i < 9; i++)state.probe.push(new Vector3());
25717	    const vector3 = new Vector3();
25718	    const matrix4 = new Matrix4();
25719	    const matrix42 = new Matrix4();
25720	    function setup(lights) {
25721	        let r = 0, g = 0, b = 0;
25722	        for(let i = 0; i < 9; i++)state.probe[i].set(0, 0, 0);
25723	        let directionalLength = 0;
25724	        let pointLength = 0;
25725	        let spotLength = 0;
25726	        let rectAreaLength = 0;
25727	        let hemiLength = 0;
25728	        let numDirectionalShadows = 0;
25729	        let numPointShadows = 0;
25730	        let numSpotShadows = 0;
25731	        let numSpotMaps = 0;
25732	        let numSpotShadowsWithMaps = 0;
25733	        let numLightProbes = 0;
25734	        // ordering : [shadow casting + map texturing, map texturing, shadow casting, none ]
25735	        lights.sort(shadowCastingAndTexturingLightsFirst);
25736	        for(let i = 0, l = lights.length; i < l; i++){
25737	            const light = lights[i];
25738	            const color = light.color;
25739	            const intensity = light.intensity;
25740	            const distance = light.distance;
25741	            const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null;
25742	            if (light.isAmbientLight) {
25743	                r += color.r * intensity;
25744	                g += color.g * intensity;
25745	                b += color.b * intensity;
25746	            } else if (light.isLightProbe) {
25747	                for(let j = 0; j < 9; j++){
25748	                    state.probe[j].addScaledVector(light.sh.coefficients[j], intensity);
25749	                }
25750	                numLightProbes++;
25751	            } else if (light.isDirectionalLight) {
25752	                const uniforms = cache.get(light);
25753	                uniforms.color.copy(light.color).multiplyScalar(light.intensity);
25754	                if (light.castShadow) {
25755	                    const shadow = light.shadow;
25756	                    const shadowUniforms = shadowCache.get(light);
25757	                    shadowUniforms.shadowIntensity = shadow.intensity;
25758	                    shadowUniforms.shadowBias = shadow.bias;
25759	                    shadowUniforms.shadowNormalBias = shadow.normalBias;
25760	                    shadowUniforms.shadowRadius = shadow.radius;
25761	                    shadowUniforms.shadowMapSize = shadow.mapSize;
25762	                    state.directionalShadow[directionalLength] = shadowUniforms;
25763	                    state.directionalShadowMap[directionalLength] = shadowMap;
25764	                    state.directionalShadowMatrix[directionalLength] = light.shadow.matrix;
25765	                    numDirectionalShadows++;
25766	                }
25767	                state.directional[directionalLength] = uniforms;
25768	                directionalLength++;
25769	            } else if (light.isSpotLight) {
25770	                const uniforms = cache.get(light);
25771	                uniforms.position.setFromMatrixPosition(light.matrixWorld);
25772	                uniforms.color.copy(color).multiplyScalar(intensity);
25773	                uniforms.distance = distance;
25774	                uniforms.coneCos = Math.cos(light.angle);
25775	                uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra));
25776	                uniforms.decay = light.decay;
25777	                state.spot[spotLength] = uniforms;
25778	                const shadow = light.shadow;
25779	                if (light.map) {
25780	                    state.spotLightMap[numSpotMaps] = light.map;
25781	                    numSpotMaps++;
25782	                    // make sure the lightMatrix is up to date
25783	                    // TODO : do it if required only
25784	                    shadow.updateMatrices(light);
25785	                    if (light.castShadow) numSpotShadowsWithMaps++;
25786	                }
25787	                state.spotLightMatrix[spotLength] = shadow.matrix;
25788	                if (light.castShadow) {
25789	                    const shadowUniforms = shadowCache.get(light);
25790	                    shadowUniforms.shadowIntensity = shadow.intensity;
25791	                    shadowUniforms.shadowBias = shadow.bias;
25792	                    shadowUniforms.shadowNormalBias = shadow.normalBias;
25793	                    shadowUniforms.shadowRadius = shadow.radius;
25794	                    shadowUniforms.shadowMapSize = shadow.mapSize;
25795	                    state.spotShadow[spotLength] = shadowUniforms;
25796	                    state.spotShadowMap[spotLength] = shadowMap;
25797	                    numSpotShadows++;
25798	                }
25799	                spotLength++;
25800	            } else if (light.isRectAreaLight) {
25801	                const uniforms = cache.get(light);
25802	                uniforms.color.copy(color).multiplyScalar(intensity);
25803	                uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
25804	                uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0
vendor: 4,272 bytes, lines 25804-25877
25804);
25805	                state.rectArea[rectAreaLength] = uniforms;
25806	                rectAreaLength++;
25807	            } else if (light.isPointLight) {
25808	                const uniforms = cache.get(light);
25809	                uniforms.color.copy(light.color).multiplyScalar(light.intensity);
25810	                uniforms.distance = light.distance;
25811	                uniforms.decay = light.decay;
25812	                if (light.castShadow) {
25813	                    const shadow = light.shadow;
25814	                    const shadowUniforms = shadowCache.get(light);
25815	                    shadowUniforms.shadowIntensity = shadow.intensity;
25816	                    shadowUniforms.shadowBias = shadow.bias;
25817	                    shadowUniforms.shadowNormalBias = shadow.normalBias;
25818	                    shadowUniforms.shadowRadius = shadow.radius;
25819	                    shadowUniforms.shadowMapSize = shadow.mapSize;
25820	                    shadowUniforms.shadowCameraNear = shadow.camera.near;
25821	                    shadowUniforms.shadowCameraFar = shadow.camera.far;
25822	                    state.pointShadow[pointLength] = shadowUniforms;
25823	                    state.pointShadowMap[pointLength] = shadowMap;
25824	                    state.pointShadowMatrix[pointLength] = light.shadow.matrix;
25825	                    numPointShadows++;
25826	                }
25827	                state.point[pointLength] = uniforms;
25828	                pointLength++;
25829	            } else if (light.isHemisphereLight) {
25830	                const uniforms = cache.get(light);
25831	                uniforms.skyColor.copy(light.color).multiplyScalar(intensity);
25832	                uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity);
25833	                state.hemi[hemiLength] = uniforms;
25834	                hemiLength++;
25835	            }
25836	        }
25837	        if (rectAreaLength > 0) {
25838	            if (extensions.has('OES_texture_float_linear') === true) {
25839	                state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
25840	                state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
25841	            } else {
25842	                state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
25843	                state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
25844	            }
25845	        }
25846	        state.ambient[0] = r;
25847	        state.ambient[1] = g;
25848	        state.ambient[2] = b;
25849	        const hash = state.hash;
25850	        if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows || hash.numSpotMaps !== numSpotMaps || hash.numLightProbes !== numLightProbes) {
25851	            state.directional.length = directionalLength;
25852	            state.spot.length = spotLength;
25853	            state.rectArea.length = rectAreaLength;
25854	            state.point.length = pointLength;
25855	            state.hemi.length = hemiLength;
25856	            state.directionalShadow.length = numDirectionalShadows;
25857	            state.directionalShadowMap.length = numDirectionalShadows;
25858	            state.pointShadow.length = numPointShadows;
25859	            state.pointShadowMap.length = numPointShadows;
25860	            state.spotShadow.length = numSpotShadows;
25861	            state.spotShadowMap.length = numSpotShadows;
25862	            state.directionalShadowMatrix.length = numDirectionalShadows;
25863	            state.pointShadowMatrix.length = numPointShadows;
25864	            state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
25865	            state.spotLightMap.length = numSpotMaps;
25866	            state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
25867	            state.numLightProbes = numLightProbes;
25868	            hash.directionalLength = directionalLength;
25869	            hash.pointLength = pointLength;
25870	            hash.spotLength = spotLength;
25871	            hash.rectAreaLength = rectAreaLength;
25872	            hash.hemiLength = hemiLength;
25873	            hash.numDirectionalShadows = numDirectionalShadows;
25874	            hash.numPointShadows = numPointShadows;
25875	            hash.numSpotShadows = numSpotShadows;
25876	            hash.numSpotMaps = numSpotMaps;
25877	            hash.numLightProbes = numLightProbes;
vendor: 4,372 bytes, lines 25878-25987
25878	            state.version = nextVersion++;
25879	        }
25880	    }
25881	    function setupView(lights, camera) {
25882	        let directionalLength = 0;
25883	        let pointLength = 0;
25884	        let spotLength = 0;
25885	        let rectAreaLength = 0;
25886	        let hemiLength = 0;
25887	        const viewMatrix = camera.matrixWorldInverse;
25888	        for(let i = 0, l = lights.length; i < l; i++){
25889	            const light = lights[i];
25890	            if (light.isDirectionalLight) {
25891	                const uniforms = state.directional[directionalLength];
25892	                uniforms.direction.setFromMatrixPosition(light.matrixWorld);
25893	                vector3.setFromMatrixPosition(light.target.matrixWorld);
25894	                uniforms.direction.sub(vector3);
25895	                uniforms.direction.transformDirection(viewMatrix);
25896	                directionalLength++;
25897	            } else if (light.isSpotLight) {
25898	                const uniforms = state.spot[spotLength];
25899	                uniforms.position.setFromMatrixPosition(light.matrixWorld);
25900	                uniforms.position.applyMatrix4(viewMatrix);
25901	                uniforms.direction.setFromMatrixPosition(light.matrixWorld);
25902	                vector3.setFromMatrixPosition(light.target.matrixWorld);
25903	                uniforms.direction.sub(vector3);
25904	                uniforms.direction.transformDirection(viewMatrix);
25905	                spotLength++;
25906	            } else if (light.isRectAreaLight) {
25907	                const uniforms = state.rectArea[rectAreaLength];
25908	                uniforms.position.setFromMatrixPosition(light.matrixWorld);
25909	                uniforms.position.applyMatrix4(viewMatrix);
25910	                // extract local rotation of light to derive width/height half vectors
25911	                matrix42.identity();
25912	                matrix4.copy(light.matrixWorld);
25913	                matrix4.premultiply(viewMatrix);
25914	                matrix42.extractRotation(matrix4);
25915	                uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
25916	                uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0);
25917	                uniforms.halfWidth.applyMatrix4(matrix42);
25918	                uniforms.halfHeight.applyMatrix4(matrix42);
25919	                rectAreaLength++;
25920	            } else if (light.isPointLight) {
25921	                const uniforms = state.point[pointLength];
25922	                uniforms.position.setFromMatrixPosition(light.matrixWorld);
25923	                uniforms.position.applyMatrix4(viewMatrix);
25924	                pointLength++;
25925	            } else if (light.isHemisphereLight) {
25926	                const uniforms = state.hemi[hemiLength];
25927	                uniforms.direction.setFromMatrixPosition(light.matrixWorld);
25928	                uniforms.direction.transformDirection(viewMatrix);
25929	                hemiLength++;
25930	            }
25931	        }
25932	    }
25933	    return {
25934	        setup: setup,
25935	        setupView: setupView,
25936	        state: state
25937	    };
25938	}
25939	function WebGLRenderState(extensions) {
25940	    const lights = new WebGLLights(extensions);
25941	    const lightsArray = [];
25942	    const shadowsArray = [];
25943	    function init(camera) {
25944	        state.camera = camera;
25945	        lightsArray.length = 0;
25946	        shadowsArray.length = 0;
25947	    }
25948	    function pushLight(light) {
25949	        lightsArray.push(light);
25950	    }
25951	    function pushShadow(shadowLight) {
25952	        shadowsArray.push(shadowLight);
25953	    }
25954	    function setupLights() {
25955	        lights.setup(lightsArray);
25956	    }
25957	    function setupLightsView(camera) {
25958	        lights.setupView(lightsArray, camera);
25959	    }
25960	    const state = {
25961	        lightsArray: lightsArray,
25962	        shadowsArray: shadowsArray,
25963	        camera: null,
25964	        lights: lights,
25965	        transmissionRenderTarget: {}
25966	    };
25967	    return {
25968	        init: init,
25969	        state: state,
25970	        setupLights: setupLights,
25971	        setupLightsView: setupLightsView,
25972	        pushLight: pushLight,
25973	        pushShadow: pushShadow
25974	    };
25975	}
25976	function WebGLRenderStates(extensions) {
25977	    let renderStates = new WeakMap();
25978	    function get(scene, renderCallDepth = 0) {
25979	        const renderStateArray = renderStates.get(scene);
25980	        let renderState;
25981	        if (renderStateArray === undefined) {
25982	            renderState = new WebGLRenderState(extensions);
25983	            renderStates.set(scene, [
25984	                renderState
25985	            ]);
25986	        } else {
25987	            if (renderCallDepth >
vendor: 6,279 bytes, lines 25987-26110
25987= renderStateArray.length) {
25988	                renderState = new WebGLRenderState(extensions);
25989	                renderStateArray.push(renderState);
25990	            } else {
25991	                renderState = renderStateArray[renderCallDepth];
25992	            }
25993	        }
25994	        return renderState;
25995	    }
25996	    function dispose() {
25997	        renderStates = new WeakMap();
25998	    }
25999	    return {
26000	        get: get,
26001	        dispose: dispose
26002	    };
26003	}
26004	const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
26005	const fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
26006	function WebGLShadowMap(renderer, objects, capabilities) {
26007	    let _frustum = new Frustum();
26008	    const _shadowMapSize = new Vector2(), _viewportSize = new Vector2(), _viewport = new Vector4(), _depthMaterial = new MeshDepthMaterial({
26009	        depthPacking: RGBADepthPacking
26010	    }), _distanceMaterial = new MeshDistanceMaterial(), _materialCache = {}, _maxTextureSize = capabilities.maxTextureSize;
26011	    const shadowSide = {
26012	        [FrontSide]: BackSide,
26013	        [BackSide]: FrontSide,
26014	        [DoubleSide]: DoubleSide
26015	    };
26016	    const shadowMaterialVertical = new ShaderMaterial({
26017	        defines: {
26018	            VSM_SAMPLES: 8
26019	        },
26020	        uniforms: {
26021	            shadow_pass: {
26022	                value: null
26023	            },
26024	            resolution: {
26025	                value: new Vector2()
26026	            },
26027	            radius: {
26028	                value: 4.0
26029	            }
26030	        },
26031	        vertexShader: vertex,
26032	        fragmentShader: fragment
26033	    });
26034	    const shadowMaterialHorizontal = shadowMaterialVertical.clone();
26035	    shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;
26036	    const fullScreenTri = new BufferGeometry();
26037	    fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([
26038	        -1,
26039	        -1,
26040	        0.5,
26041	        3,
26042	        -1,
26043	        0.5,
26044	        -1,
26045	        3,
26046	        0.5
26047	    ]), 3));
26048	    const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical);
26049	    const scope = this;
26050	    this.enabled = false;
26051	    this.autoUpdate = true;
26052	    this.needsUpdate = false;
26053	    this.type = PCFShadowMap;
26054	    let _previousType = this.type;
26055	    this.render = function(lights, scene, camera) {
26056	        if (scope.enabled === false) return;
26057	        if (scope.autoUpdate === false && scope.needsUpdate === false) return;
26058	        if (lights.length === 0) return;
26059	        const currentRenderTarget = renderer.getRenderTarget();
26060	        const activeCubeFace = renderer.getActiveCubeFace();
26061	        const activeMipmapLevel = renderer.getActiveMipmapLevel();
26062	        const _state = renderer.state;
26063	        // Set GL state for depth map.
26064	        _state.setBlending(NoBlending);
26065	        _state.buffers.color.setClear(1, 1, 1, 1);
26066	        _state.buffers.depth.setTest(true);
26067	        _state.setScissorTest(false);
26068	        // check for shadow map type changes
26069	        const toVSM = _previousType !== VSMShadowMap && this.type === VSMShadowMap;
26070	        const fromVSM = _previousType === VSMShadowMap && this.type !== VSMShadowMap;
26071	        // render depth map
26072	        for(let i = 0, il = lights.length; i < il; i++){
26073	            const light = lights[i];
26074	            const shadow = light.shadow;
26075	            if (shadow === undefined) {
26076	                console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.');
26077	                continue;
26078	            }
26079	            if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue;
26080	            _shadowMapSize.copy(shadow.mapSize);
26081	            const shadowFrameExtents = shadow.getFrameExtents();
26082	            _shadowMapSize.multiply(shadowFrameExtents);
26083	            _viewportSize.copy(shadow.mapSize);
26084	            if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) {
26085	                if (_shadowMapSize.x > _maxTextureSize) {
26086	                    _viewportSize.x = Math.floor(_maxTextureSize / shadowFrameExtents.x);
26087	                    _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
26088	                    shadow.mapSize.x = _viewportSize.x;
26089	                }
26090	                if (_shadowMapSize.y > _maxTextureSize) {
26091	                    _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y);
26092	                    _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
26093	                    shadow.mapSize.y = _viewportSize.y;
26094	                }
26095	            }
26096	            if (shadow.map === null || toVSM === true || fromVSM === true) {
26097	                const pars = this.type !== VSMShadowMap ? {
26098	                    minFilter: NearestFilter,
26099	                    magFilter: NearestFilter
26100	                } : {};
26101	                if (shadow.map !== null) {
26102	                    shadow.map.dispose();
26103	                }
26104	                shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars);
26105	                shadow.map.texture.name = light.name + '.shadowMap';
26106	                shadow.camera.updateProjectionMatrix();
26107	            }
26108	            renderer.setRenderTarget(shadow.map);
26109	            renderer.clear();
26110	            const viewportCount = shadow.getViewportCount();
vendor: 9,459 bytes, lines 26111-26291
26111	            for(let vp = 0; vp < viewportCount; vp++){
26112	                const viewport = shadow.getViewport(vp);
26113	                _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w);
26114	                _state.viewport(_viewport);
26115	                shadow.updateMatrices(light, vp);
26116	                _frustum = shadow.getFrustum();
26117	                renderObject(scene, camera, shadow.camera, light, this.type);
26118	            }
26119	            // do blur pass for VSM
26120	            if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) {
26121	                VSMPass(shadow, camera);
26122	            }
26123	            shadow.needsUpdate = false;
26124	        }
26125	        _previousType = this.type;
26126	        scope.needsUpdate = false;
26127	        renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel);
26128	    };
26129	    function VSMPass(shadow, camera) {
26130	        const geometry = objects.update(fullScreenMesh);
26131	        if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) {
26132	            shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples;
26133	            shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples;
26134	            shadowMaterialVertical.needsUpdate = true;
26135	            shadowMaterialHorizontal.needsUpdate = true;
26136	        }
26137	        if (shadow.mapPass === null) {
26138	            shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y);
26139	        }
26140	        // vertical pass
26141	        shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
26142	        shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
26143	        shadowMaterialVertical.uniforms.radius.value = shadow.radius;
26144	        renderer.setRenderTarget(shadow.mapPass);
26145	        renderer.clear();
26146	        renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null);
26147	        // horizontal pass
26148	        shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
26149	        shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
26150	        shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
26151	        renderer.setRenderTarget(shadow.map);
26152	        renderer.clear();
26153	        renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null);
26154	    }
26155	    function getDepthMaterial(object, material, light, type) {
26156	        let result = null;
26157	        const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial;
26158	        if (customMaterial !== undefined) {
26159	            result = customMaterial;
26160	        } else {
26161	            result = light.isPointLight === true ? _distanceMaterial : _depthMaterial;
26162	            if (renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0 || material.map && material.alphaTest > 0) {
26163	                // in this case we need a unique material instance reflecting the
26164	                // appropriate state
26165	                const keyA = result.uuid, keyB = material.uuid;
26166	                let materialsForVariant = _materialCache[keyA];
26167	                if (materialsForVariant === undefined) {
26168	                    materialsForVariant = {};
26169	                    _materialCache[keyA] = materialsForVariant;
26170	                }
26171	                let cachedMaterial = materialsForVariant[keyB];
26172	                if (cachedMaterial === undefined) {
26173	                    cachedMaterial = result.clone();
26174	                    materialsForVariant[keyB] = cachedMaterial;
26175	                    material.addEventListener('dispose', onMaterialDispose);
26176	                }
26177	                result = cachedMaterial;
26178	            }
26179	        }
26180	        result.visible = material.visible;
26181	        result.wireframe = material.wireframe;
26182	        if (type === VSMShadowMap) {
26183	            result.side = material.shadowSide !== null ? material.shadowSide : material.side;
26184	        } else {
26185	            result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side];
26186	        }
26187	        result.alphaMap = material.alphaMap;
26188	        result.alphaTest = material.alphaTest;
26189	        result.map = material.map;
26190	        result.clipShadows = material.clipShadows;
26191	        result.clippingPlanes = material.clippingPlanes;
26192	        result.clipIntersection = material.clipIntersection;
26193	        result.displacementMap = material.displacementMap;
26194	        result.displacementScale = material.displacementScale;
26195	        result.displacementBias = material.displacementBias;
26196	        result.wireframeLinewidth = material.wireframeLinewidth;
26197	        result.linewidth = material.linewidth;
26198	        if (light.isPointLight === true && result.isMeshDistanceMaterial === true) {
26199	            const materialProperties = renderer.properties.get(result);
26200	            materialProperties.light = light;
26201	        }
26202	        return result;
26203	    }
26204	    function renderObject(object, camera, shadowCamera, light, type) {
26205	        if (object.visible === false) return;
26206	        const visible = object.layers.test(camera.layers);
26207	        if (visible && (object.isMesh || object.isLine || object.isPoints)) {
26208	            if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) {
26209	                object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld);
26210	                const geometry = objects.update(object);
26211	                const material = object.material;
26212	                if (Array.isArray(material)) {
26213	                    const groups = geometry.groups;
26214	                    for(let k = 0, kl = groups.length; k < kl; k++){
26215	                        const group = groups[k];
26216	                        const groupMaterial = material[group.materialIndex];
26217	                        if (groupMaterial && groupMaterial.visible) {
26218	                            const depthMaterial = getDepthMaterial(object, groupMaterial, light, type);
26219	                            object.onBeforeShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, group);
26220	                            renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group);
26221	                            object.onAfterShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, group);
26222	                        }
26223	                    }
26224	                } else if (material.visible) {
26225	                    const depthMaterial = getDepthMaterial(object, material, light, type);
26226	                    object.onBeforeShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, null);
26227	                    renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null);
26228	                    object.onAfterShadow(renderer, object, camera, shadowCamera, geometry, depthMaterial, null);
26229	                }
26230	            }
26231	        }
26232	        const children = object.children;
26233	        for(let i = 0, l = children.length; i < l; i++){
26234	            renderObject(children[i], camera, shadowCamera, light, type);
26235	        }
26236	    }
26237	    function onMaterialDispose(event) {
26238	        const material = event.target;
26239	        material.removeEventListener('dispose', onMaterialDispose);
26240	        // make sure to remove the unique distance/depth materials used for shadow map rendering
26241	        for(const id in _materialCache){
26242	            const cache = _materialCache[id];
26243	            const uuid = event.target.uuid;
26244	            if (uuid in cache) {
26245	                const shadowMaterial = cache[uuid];
26246	                shadowMaterial.dispose();
26247	                delete cache[uuid];
26248	            }
26249	        }
26250	    }
26251	}
26252	const reversedFuncs = {
26253	    [NeverDepth]: AlwaysDepth,
26254	    [LessDepth]: GreaterDepth,
26255	    [EqualDepth]: NotEqualDepth,
26256	    [LessEqualDepth]: GreaterEqualDepth,
26257	    [AlwaysDepth]: NeverDepth,
26258	    [GreaterDepth]: LessDepth,
26259	    [NotEqualDepth]: EqualDepth,
26260	    [GreaterEqualDepth]: LessEqualDepth
26261	};
26262	function WebGLState(gl, extensions) {
26263	    function ColorBuffer() {
26264	        let locked = false;
26265	        const color = new Vector4();
26266	        let currentColorMask = null;
26267	        const currentColorClear = new Vector4(0, 0, 0, 0);
26268	        return {
26269	            setMask: function(colorMask) {
26270	                if (currentColorMask !== colorMask && !locked) {
26271	                    gl.colorMask(colorMask, colorMask, colorMask, colorMask);
26272	                    currentColorMask = colorMask;
26273	                }
26274	            },
26275	            setLocked: function(lock) {
26276	                locked = lock;
26277	            },
26278	            setClear: function(r, g, b, a, premultipliedAlpha) {
26279	                if (premultipliedAlpha === true) {
26280	                    r *= a;
26281	                    g *= a;
26282	                    b *= a;
26283	                }
26284	                color.set(r, g, b, a);
26285	                if (currentColorClear.equals(color) === false) {
26286	                    gl.clearColor(r, g, b, a);
26287	                    currentColorClear.copy(color);
26288	                }
26289	            },
26290	            reset: function() {
26291	                locked = false;
vendor: 5,256 bytes, lines 26292-26423
26292	                currentColorMask = null;
26293	                currentColorClear.set(-1, 0, 0, 0); // set to invalid state
26294	            }
26295	        };
26296	    }
26297	    function DepthBuffer() {
26298	        let locked = false;
26299	        let reversed = false;
26300	        let currentDepthMask = null;
26301	        let currentDepthFunc = null;
26302	        let currentDepthClear = null;
26303	        return {
26304	            setReversed: function(value) {
26305	                if (reversed !== value) {
26306	                    const ext = extensions.get('EXT_clip_control');
26307	                    if (reversed) {
26308	                        ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT);
26309	                    } else {
26310	                        ext.clipControlEXT(ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT);
26311	                    }
26312	                    const oldDepth = currentDepthClear;
26313	                    currentDepthClear = null;
26314	                    this.setClear(oldDepth);
26315	                }
26316	                reversed = value;
26317	            },
26318	            getReversed: function() {
26319	                return reversed;
26320	            },
26321	            setTest: function(depthTest) {
26322	                if (depthTest) {
26323	                    enable(gl.DEPTH_TEST);
26324	                } else {
26325	                    disable(gl.DEPTH_TEST);
26326	                }
26327	            },
26328	            setMask: function(depthMask) {
26329	                if (currentDepthMask !== depthMask && !locked) {
26330	                    gl.depthMask(depthMask);
26331	                    currentDepthMask = depthMask;
26332	                }
26333	            },
26334	            setFunc: function(depthFunc) {
26335	                if (reversed) depthFunc = reversedFuncs[depthFunc];
26336	                if (currentDepthFunc !== depthFunc) {
26337	                    switch(depthFunc){
26338	                        case NeverDepth:
26339	                            gl.depthFunc(gl.NEVER);
26340	                            break;
26341	                        case AlwaysDepth:
26342	                            gl.depthFunc(gl.ALWAYS);
26343	                            break;
26344	                        case LessDepth:
26345	                            gl.depthFunc(gl.LESS);
26346	                            break;
26347	                        case LessEqualDepth:
26348	                            gl.depthFunc(gl.LEQUAL);
26349	                            break;
26350	                        case EqualDepth:
26351	                            gl.depthFunc(gl.EQUAL);
26352	                            break;
26353	                        case GreaterEqualDepth:
26354	                            gl.depthFunc(gl.GEQUAL);
26355	                            break;
26356	                        case GreaterDepth:
26357	                            gl.depthFunc(gl.GREATER);
26358	                            break;
26359	                        case NotEqualDepth:
26360	                            gl.depthFunc(gl.NOTEQUAL);
26361	                            break;
26362	                        default:
26363	                            gl.depthFunc(gl.LEQUAL);
26364	                    }
26365	                    currentDepthFunc = depthFunc;
26366	                }
26367	            },
26368	            setLocked: function(lock) {
26369	                locked = lock;
26370	            },
26371	            setClear: function(depth) {
26372	                if (currentDepthClear !== depth) {
26373	                    if (reversed) {
26374	                        depth = 1 - depth;
26375	                    }
26376	                    gl.clearDepth(depth);
26377	                    currentDepthClear = depth;
26378	                }
26379	            },
26380	            reset: function() {
26381	                locked = false;
26382	                currentDepthMask = null;
26383	                currentDepthFunc = null;
26384	                currentDepthClear = null;
26385	                reversed = false;
26386	            }
26387	        };
26388	    }
26389	    function StencilBuffer() {
26390	        let locked = false;
26391	        let currentStencilMask = null;
26392	        let currentStencilFunc = null;
26393	        let currentStencilRef = null;
26394	        let currentStencilFuncMask = null;
26395	        let currentStencilFail = null;
26396	        let currentStencilZFail = null;
26397	        let currentStencilZPass = null;
26398	        let currentStencilClear = null;
26399	        return {
26400	            setTest: function(stencilTest) {
26401	                if (!locked) {
26402	                    if (stencilTest) {
26403	                        enable(gl.STENCIL_TEST);
26404	                    } else {
26405	                        disable(gl.STENCIL_TEST);
26406	                    }
26407	                }
26408	            },
26409	            setMask: function(stencilMask) {
26410	                if (currentStencilMask !== stencilMask && !locked) {
26411	                    gl.stencilMask(stencilMask);
26412	                    currentStencilMask = stencilMask;
26413	                }
26414	            },
26415	            setFunc: function(stencilFunc, stencilRef, stencilMask) {
26416	                if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) {
26417	                    gl.stencilFunc(stencilFunc, stencilRef, stencilMask);
26418	                    currentStencilFunc = stencilFunc;
26419	                    currentStencilRef = stencilRef;
26420	                    currentStencilFuncMask = stencilMask;
26421	                }
26422	            },
26423	            setOp: function(stencilFail, stencilZFail, stencilZPass) {
vendor: 36,312 bytes, lines 26424-27238
26424	                if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) {
26425	                    gl.stencilOp(stencilFail, stencilZFail, stencilZPass);
26426	                    currentStencilFail = stencilFail;
26427	                    currentStencilZFail = stencilZFail;
26428	                    currentStencilZPass = stencilZPass;
26429	                }
26430	            },
26431	            setLocked: function(lock) {
26432	                locked = lock;
26433	            },
26434	            setClear: function(stencil) {
26435	                if (currentStencilClear !== stencil) {
26436	                    gl.clearStencil(stencil);
26437	                    currentStencilClear = stencil;
26438	                }
26439	            },
26440	            reset: function() {
26441	                locked = false;
26442	                currentStencilMask = null;
26443	                currentStencilFunc = null;
26444	                currentStencilRef = null;
26445	                currentStencilFuncMask = null;
26446	                currentStencilFail = null;
26447	                currentStencilZFail = null;
26448	                currentStencilZPass = null;
26449	                currentStencilClear = null;
26450	            }
26451	        };
26452	    }
26453	    //
26454	    const colorBuffer = new ColorBuffer();
26455	    const depthBuffer = new DepthBuffer();
26456	    const stencilBuffer = new StencilBuffer();
26457	    const uboBindings = new WeakMap();
26458	    const uboProgramMap = new WeakMap();
26459	    let enabledCapabilities = {};
26460	    let currentBoundFramebuffers = {};
26461	    let currentDrawbuffers = new WeakMap();
26462	    let defaultDrawbuffers = [];
26463	    let currentProgram = null;
26464	    let currentBlendingEnabled = false;
26465	    let currentBlending = null;
26466	    let currentBlendEquation = null;
26467	    let currentBlendSrc = null;
26468	    let currentBlendDst = null;
26469	    let currentBlendEquationAlpha = null;
26470	    let currentBlendSrcAlpha = null;
26471	    let currentBlendDstAlpha = null;
26472	    let currentBlendColor = new Color(0, 0, 0);
26473	    let currentBlendAlpha = 0;
26474	    let currentPremultipledAlpha = false;
26475	    let currentFlipSided = null;
26476	    let currentCullFace = null;
26477	    let currentLineWidth = null;
26478	    let currentPolygonOffsetFactor = null;
26479	    let currentPolygonOffsetUnits = null;
26480	    const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
26481	    let lineWidthAvailable = false;
26482	    let version = 0;
26483	    const glVersion = gl.getParameter(gl.VERSION);
26484	    if (glVersion.indexOf('WebGL') !== -1) {
26485	        version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]);
26486	        lineWidthAvailable = version >= 1.0;
26487	    } else if (glVersion.indexOf('OpenGL ES') !== -1) {
26488	        version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]);
26489	        lineWidthAvailable = version >= 2.0;
26490	    }
26491	    let currentTextureSlot = null;
26492	    let currentBoundTextures = {};
26493	    const scissorParam = gl.getParameter(gl.SCISSOR_BOX);
26494	    const viewportParam = gl.getParameter(gl.VIEWPORT);
26495	    const currentScissor = new Vector4().fromArray(scissorParam);
26496	    const currentViewport = new Vector4().fromArray(viewportParam);
26497	    function createTexture(type, target, count, dimensions) {
26498	        const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4.
26499	        const texture = gl.createTexture();
26500	        gl.bindTexture(type, texture);
26501	        gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
26502	        gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
26503	        for(let i = 0; i < count; i++){
26504	            if (type === gl.TEXTURE_3D || type === gl.TEXTURE_2D_ARRAY) {
26505	                gl.texImage3D(target, 0, gl.RGBA, 1, 1, dimensions, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
26506	            } else {
26507	                gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
26508	            }
26509	        }
26510	        return texture;
26511	    }
26512	    const emptyTextures = {};
26513	    emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1);
26514	    emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6);
26515	    emptyTextures[gl.TEXTURE_2D_ARRAY] = createTexture(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_2D_ARRAY, 1, 1);
26516	    emptyTextures[gl.TEXTURE_3D] = createTexture(gl.TEXTURE_3D, gl.TEXTURE_3D, 1, 1);
26517	    // init
26518	    colorBuffer.setClear(0, 0, 0, 1);
26519	    depthBuffer.setClear(1);
26520	    stencilBuffer.setClear(0);
26521	    enable(gl.DEPTH_TEST);
26522	    depthBuffer.setFunc(LessEqualDepth);
26523	    setFlipSided(false);
26524	    setCullFace(CullFaceBack);
26525	    enable(gl.CULL_FACE);
26526	    setBlending(NoBlending);
26527	    //
26528	    function enable(id) {
26529	        if (enabledCapabilities[id] !== true) {
26530	            gl.enable(id);
26531	            enabledCapabilities[id] = true;
26532	        }
26533	    }
26534	    function disable(id) {
26535	        if (enabledCapabilities[id] !== false) {
26536	            gl.disable(id);
26537	            enabledCapabilities[id] = false;
26538	        }
26539	    }
26540	    function bindFramebuffer(target, framebuffer) {
26541	        if (currentBoundFramebuffers[target] !== framebuffer) {
26542	            gl.bindFramebuffer(target, framebuffer);
26543	            currentBoundFramebuffers[target] = framebuffer;
26544	            // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER
26545	            if (target === gl.DRAW_FRAMEBUFFER) {
26546	                currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer;
26547	            }
26548	            if (target === gl.FRAMEBUFFER) {
26549	                currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer;
26550	            }
26551	            return true;
26552	        }
26553	        return false;
26554	    }
26555	    function drawBuffers(renderTarget, framebuffer) {
26556	        let drawBuffers = defaultDrawbuffers;
26557	        let needsUpdate = false;
26558	        if (renderTarget) {
26559	            drawBuffers = currentDrawbuffers.get(framebuffer);
26560	            if (drawBuffers === undefined) {
26561	                drawBuffers = [];
26562	                currentDrawbuffers.set(framebuffer, drawBuffers);
26563	            }
26564	            const textures = renderTarget.textures;
26565	            if (drawBuffers.length !== textures.length || drawBuffers[0] !== gl.COLOR_ATTACHMENT0) {
26566	                for(let i = 0, il = textures.length; i < il; i++){
26567	                    drawBuffers[i] = gl.COLOR_ATTACHMENT0 + i;
26568	                }
26569	                drawBuffers.length = textures.length;
26570	                needsUpdate = true;
26571	            }
26572	        } else {
26573	            if (drawBuffers[0] !== gl.BACK) {
26574	                drawBuffers[0] = gl.BACK;
26575	                needsUpdate = true;
26576	            }
26577	        }
26578	        if (needsUpdate) {
26579	            gl.drawBuffers(drawBuffers);
26580	        }
26581	    }
26582	    function useProgram(program) {
26583	        if (currentProgram !== program) {
26584	            gl.useProgram(program);
26585	            currentProgram = program;
26586	            return true;
26587	        }
26588	        return false;
26589	    }
26590	    const equationToGL = {
26591	        [AddEquation]: gl.FUNC_ADD,
26592	        [SubtractEquation]: gl.FUNC_SUBTRACT,
26593	        [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT
26594	    };
26595	    equationToGL[MinEquation] = gl.MIN;
26596	    equationToGL[MaxEquation] = gl.MAX;
26597	    const factorToGL = {
26598	        [ZeroFactor]: gl.ZERO,
26599	        [OneFactor]: gl.ONE,
26600	        [SrcColorFactor]: gl.SRC_COLOR,
26601	        [SrcAlphaFactor]: gl.SRC_ALPHA,
26602	        [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE,
26603	        [DstColorFactor]: gl.DST_COLOR,
26604	        [DstAlphaFactor]: gl.DST_ALPHA,
26605	        [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR,
26606	        [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA,
26607	        [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR,
26608	        [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA,
26609	        [ConstantColorFactor]: gl.CONSTANT_COLOR,
26610	        [OneMinusConstantColorFactor]: gl.ONE_MINUS_CONSTANT_COLOR,
26611	        [ConstantAlphaFactor]: gl.CONSTANT_ALPHA,
26612	        [OneMinusConstantAlphaFactor]: gl.ONE_MINUS_CONSTANT_ALPHA
26613	    };
26614	    function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, blendColor, blendAlpha, premultipliedAlpha) {
26615	        if (blending === NoBlending) {
26616	            if (currentBlendingEnabled === true) {
26617	                disable(gl.BLEND);
26618	                currentBlendingEnabled = false;
26619	            }
26620	            return;
26621	        }
26622	        if (currentBlendingEnabled === false) {
26623	            enable(gl.BLEND);
26624	            currentBlendingEnabled = true;
26625	        }
26626	        if (blending !== CustomBlending) {
26627	            if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) {
26628	                if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) {
26629	                    gl.blendEquation(gl.FUNC_ADD);
26630	                    currentBlendEquation = AddEquation;
26631	                    currentBlendEquationAlpha = AddEquation;
26632	                }
26633	                if (premultipliedAlpha) {
26634	                    switch(blending){
26635	                        case NormalBlending:
26636	                            gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
26637	                            break;
26638	                        case AdditiveBlending:
26639	                            gl.blendFunc(gl.ONE, gl.ONE);
26640	                            break;
26641	                        case SubtractiveBlending:
26642	                            gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE);
26643	                            break;
26644	                        case MultiplyBlending:
26645	                            gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA);
26646	                            break;
26647	                        default:
26648	                            console.error('THREE.WebGLState: Invalid blending: ', blending);
26649	                            break;
26650	                    }
26651	                } else {
26652	                    switch(blending){
26653	                        case NormalBlending:
26654	                            gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
26655	                            break;
26656	                        case AdditiveBlending:
26657	                            gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
26658	                            break;
26659	                        case SubtractiveBlending:
26660	                            gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE);
26661	                            break;
26662	                        case MultiplyBlending:
26663	                            gl.blendFunc(gl.ZERO, gl.SRC_COLOR);
26664	                            break;
26665	                        default:
26666	                            console.error('THREE.WebGLState: Invalid blending: ', blending);
26667	                            break;
26668	                    }
26669	                }
26670	                currentBlendSrc = null;
26671	                currentBlendDst = null;
26672	                currentBlendSrcAlpha = null;
26673	                currentBlendDstAlpha = null;
26674	                currentBlendColor.set(0, 0, 0);
26675	                currentBlendAlpha = 0;
26676	                currentBlending = blending;
26677	                currentPremultipledAlpha = premultipliedAlpha;
26678	            }
26679	            return;
26680	        }
26681	        // custom blending
26682	        blendEquationAlpha = blendEquationAlpha || blendEquation;
26683	        blendSrcAlpha = blendSrcAlpha || blendSrc;
26684	        blendDstAlpha = blendDstAlpha || blendDst;
26685	        if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) {
26686	            gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]);
26687	            currentBlendEquation = blendEquation;
26688	            currentBlendEquationAlpha = blendEquationAlpha;
26689	        }
26690	        if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) {
26691	            gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]);
26692	            currentBlendSrc = blendSrc;
26693	            currentBlendDst = blendDst;
26694	            currentBlendSrcAlpha = blendSrcAlpha;
26695	            currentBlendDstAlpha = blendDstAlpha;
26696	        }
26697	        if (blendColor.equals(currentBlendColor) === false || blendAlpha !== currentBlendAlpha) {
26698	            gl.blendColor(blendColor.r, blendColor.g, blendColor.b, blendAlpha);
26699	            currentBlendColor.copy(blendColor);
26700	            currentBlendAlpha = blendAlpha;
26701	        }
26702	        currentBlending = blending;
26703	        currentPremultipledAlpha = false;
26704	    }
26705	    function setMaterial(material, frontFaceCW) {
26706	        material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE);
26707	        let flipSided = material.side === BackSide;
26708	        if (frontFaceCW) flipSided = !flipSided;
26709	        setFlipSided(flipSided);
26710	        material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.blendColor, material.blendAlpha, material.premultipliedAlpha);
26711	        depthBuffer.setFunc(material.depthFunc);
26712	        depthBuffer.setTest(material.depthTest);
26713	        depthBuffer.setMask(material.depthWrite);
26714	        colorBuffer.setMask(material.colorWrite);
26715	        const stencilWrite = material.stencilWrite;
26716	        stencilBuffer.setTest(stencilWrite);
26717	        if (stencilWrite) {
26718	            stencilBuffer.setMask(material.stencilWriteMask);
26719	            stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask);
26720	            stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass);
26721	        }
26722	        setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits);
26723	        material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
26724	    }
26725	    //
26726	    function setFlipSided(flipSided) {
26727	        if (currentFlipSided !== flipSided) {
26728	            if (flipSided) {
26729	                gl.frontFace(gl.CW);
26730	            } else {
26731	                gl.frontFace(gl.CCW);
26732	            }
26733	            currentFlipSided = flipSided;
26734	        }
26735	    }
26736	    function setCullFace(cullFace) {
26737	        if (cullFace !== CullFaceNone) {
26738	            enable(gl.CULL_FACE);
26739	            if (cullFace !== currentCullFace) {
26740	                if (cullFace === CullFaceBack) {
26741	                    gl.cullFace(gl.BACK);
26742	                } else if (cullFace === CullFaceFront) {
26743	                    gl.cullFace(gl.FRONT);
26744	                } else {
26745	                    gl.cullFace(gl.FRONT_AND_BACK);
26746	                }
26747	            }
26748	        } else {
26749	            disable(gl.CULL_FACE);
26750	        }
26751	        currentCullFace = cullFace;
26752	    }
26753	    function setLineWidth(width) {
26754	        if (width !== currentLineWidth) {
26755	            if (lineWidthAvailable) gl.lineWidth(width);
26756	            currentLineWidth = width;
26757	        }
26758	    }
26759	    function setPolygonOffset(polygonOffset, factor, units) {
26760	        if (polygonOffset) {
26761	            enable(gl.POLYGON_OFFSET_FILL);
26762	            if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) {
26763	                gl.polygonOffset(factor, units);
26764	                currentPolygonOffsetFactor = factor;
26765	                currentPolygonOffsetUnits = units;
26766	            }
26767	        } else {
26768	            disable(gl.POLYGON_OFFSET_FILL);
26769	        }
26770	    }
26771	    function setScissorTest(scissorTest) {
26772	        if (scissorTest) {
26773	            enable(gl.SCISSOR_TEST);
26774	        } else {
26775	            disable(gl.SCISSOR_TEST);
26776	        }
26777	    }
26778	    // texture
26779	    function activeTexture(webglSlot) {
26780	        if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1;
26781	        if (currentTextureSlot !== webglSlot) {
26782	            gl.activeTexture(webglSlot);
26783	            currentTextureSlot = webglSlot;
26784	        }
26785	    }
26786	    function bindTexture(webglType, webglTexture, webglSlot) {
26787	        if (webglSlot === undefined) {
26788	            if (currentTextureSlot === null) {
26789	                webglSlot = gl.TEXTURE0 + maxTextures - 1;
26790	            } else {
26791	                webglSlot = currentTextureSlot;
26792	            }
26793	        }
26794	        let boundTexture = currentBoundTextures[webglSlot];
26795	        if (boundTexture === undefined) {
26796	            boundTexture = {
26797	                type: undefined,
26798	                texture: undefined
26799	            };
26800	            currentBoundTextures[webglSlot] = boundTexture;
26801	        }
26802	        if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) {
26803	            if (currentTextureSlot !== webglSlot) {
26804	                gl.activeTexture(webglSlot);
26805	                currentTextureSlot = webglSlot;
26806	            }
26807	            gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]);
26808	            boundTexture.type = webglType;
26809	            boundTexture.texture = webglTexture;
26810	        }
26811	    }
26812	    function unbindTexture() {
26813	        const boundTexture = currentBoundTextures[currentTextureSlot];
26814	        if (boundTexture !== undefined && boundTexture.type !== undefined) {
26815	            gl.bindTexture(boundTexture.type, null);
26816	            boundTexture.type = undefined;
26817	            boundTexture.texture = undefined;
26818	        }
26819	    }
26820	    function compressedTexImage2D() {
26821	        try {
26822	            gl.compressedTexImage2D(...arguments);
26823	        } catch (error) {
26824	            console.error('THREE.WebGLState:', error);
26825	        }
26826	    }
26827	    function compressedTexImage3D() {
26828	        try {
26829	            gl.compressedTexImage3D(...arguments);
26830	        } catch (error) {
26831	            console.error('THREE.WebGLState:', error);
26832	        }
26833	    }
26834	    function texSubImage2D() {
26835	        try {
26836	            gl.texSubImage2D(...arguments);
26837	        } catch (error) {
26838	            console.error('THREE.WebGLState:', error);
26839	        }
26840	    }
26841	    function texSubImage3D() {
26842	        try {
26843	            gl.texSubImage3D(...arguments);
26844	        } catch (error) {
26845	            console.error('THREE.WebGLState:', error);
26846	        }
26847	    }
26848	    function compressedTexSubImage2D() {
26849	        try {
26850	            gl.compressedTexSubImage2D(...arguments);
26851	        } catch (error) {
26852	            console.error('THREE.WebGLState:', error);
26853	        }
26854	    }
26855	    function compressedTexSubImage3D() {
26856	        try {
26857	            gl.compressedTexSubImage3D(...arguments);
26858	        } catch (error) {
26859	            console.error('THREE.WebGLState:', error);
26860	        }
26861	    }
26862	    function texStorage2D() {
26863	        try {
26864	            gl.texStorage2D(...arguments);
26865	        } catch (error) {
26866	            console.error('THREE.WebGLState:', error);
26867	        }
26868	    }
26869	    function texStorage3D() {
26870	        try {
26871	            gl.texStorage3D(...arguments);
26872	        } catch (error) {
26873	            console.error('THREE.WebGLState:', error);
26874	        }
26875	    }
26876	    function texImage2D() {
26877	        try {
26878	            gl.texImage2D(...arguments);
26879	        } catch (error) {
26880	            console.error('THREE.WebGLState:', error);
26881	        }
26882	    }
26883	    function texImage3D() {
26884	        try {
26885	            gl.texImage3D(...arguments);
26886	        } catch (error) {
26887	            console.error('THREE.WebGLState:', error);
26888	        }
26889	    }
26890	    //
26891	    function scissor(scissor) {
26892	        if (currentScissor.equals(scissor) === false) {
26893	            gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w);
26894	            currentScissor.copy(scissor);
26895	        }
26896	    }
26897	    function viewport(viewport) {
26898	        if (currentViewport.equals(viewport) === false) {
26899	            gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w);
26900	            currentViewport.copy(viewport);
26901	        }
26902	    }
26903	    function updateUBOMapping(uniformsGroup, program) {
26904	        let mapping = uboProgramMap.get(program);
26905	        if (mapping === undefined) {
26906	            mapping = new WeakMap();
26907	            uboProgramMap.set(program, mapping);
26908	        }
26909	        let blockIndex = mapping.get(uniformsGroup);
26910	        if (blockIndex === undefined) {
26911	            blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name);
26912	            mapping.set(uniformsGroup, blockIndex);
26913	        }
26914	    }
26915	    function uniformBlockBinding(uniformsGroup, program) {
26916	        const mapping = uboProgramMap.get(program);
26917	        const blockIndex = mapping.get(uniformsGroup);
26918	        if (uboBindings.get(program) !== blockIndex) {
26919	            // bind shader specific block index to global block point
26920	            gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex);
26921	            uboBindings.set(program, blockIndex);
26922	        }
26923	    }
26924	    //
26925	    function reset() {
26926	        // reset state
26927	        gl.disable(gl.BLEND);
26928	        gl.disable(gl.CULL_FACE);
26929	        gl.disable(gl.DEPTH_TEST);
26930	        gl.disable(gl.POLYGON_OFFSET_FILL);
26931	        gl.disable(gl.SCISSOR_TEST);
26932	        gl.disable(gl.STENCIL_TEST);
26933	        gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
26934	        gl.blendEquation(gl.FUNC_ADD);
26935	        gl.blendFunc(gl.ONE, gl.ZERO);
26936	        gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO);
26937	        gl.blendColor(0, 0, 0, 0);
26938	        gl.colorMask(true, true, true, true);
26939	        gl.clearColor(0, 0, 0, 0);
26940	        gl.depthMask(true);
26941	        gl.depthFunc(gl.LESS);
26942	        depthBuffer.setReversed(false);
26943	        gl.clearDepth(1);
26944	        gl.stencilMask(0xffffffff);
26945	        gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff);
26946	        gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
26947	        gl.clearStencil(0);
26948	        gl.cullFace(gl.BACK);
26949	        gl.frontFace(gl.CCW);
26950	        gl.polygonOffset(0, 0);
26951	        gl.activeTexture(gl.TEXTURE0);
26952	        gl.bindFramebuffer(gl.FRAMEBUFFER, null);
26953	        gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
26954	        gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
26955	        gl.useProgram(null);
26956	        gl.lineWidth(1);
26957	        gl.scissor(0, 0, gl.canvas.width, gl.canvas.height);
26958	        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
26959	        // reset internals
26960	        enabledCapabilities = {};
26961	        currentTextureSlot = null;
26962	        currentBoundTextures = {};
26963	        currentBoundFramebuffers = {};
26964	        currentDrawbuffers = new WeakMap();
26965	        defaultDrawbuffers = [];
26966	        currentProgram = null;
26967	        currentBlendingEnabled = false;
26968	        currentBlending = null;
26969	        currentBlendEquation = null;
26970	        currentBlendSrc = null;
26971	        currentBlendDst = null;
26972	        currentBlendEquationAlpha = null;
26973	        currentBlendSrcAlpha = null;
26974	        currentBlendDstAlpha = null;
26975	        currentBlendColor = new Color(0, 0, 0);
26976	        currentBlendAlpha = 0;
26977	        currentPremultipledAlpha = false;
26978	        currentFlipSided = null;
26979	        currentCullFace = null;
26980	        currentLineWidth = null;
26981	        currentPolygonOffsetFactor = null;
26982	        currentPolygonOffsetUnits = null;
26983	        currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height);
26984	        currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height);
26985	        colorBuffer.reset();
26986	        depthBuffer.reset();
26987	        stencilBuffer.reset();
26988	    }
26989	    return {
26990	        buffers: {
26991	            color: colorBuffer,
26992	            depth: depthBuffer,
26993	            stencil: stencilBuffer
26994	        },
26995	        enable: enable,
26996	        disable: disable,
26997	        bindFramebuffer: bindFramebuffer,
26998	        drawBuffers: drawBuffers,
26999	        useProgram: useProgram,
27000	        setBlending: setBlending,
27001	        setMaterial: setMaterial,
27002	        setFlipSided: setFlipSided,
27003	        setCullFace: setCullFace,
27004	        setLineWidth: setLineWidth,
27005	        setPolygonOffset: setPolygonOffset,
27006	        setScissorTest: setScissorTest,
27007	        activeTexture: activeTexture,
27008	        bindTexture: bindTexture,
27009	        unbindTexture: unbindTexture,
27010	        compressedTexImage2D: compressedTexImage2D,
27011	        compressedTexImage3D: compressedTexImage3D,
27012	        texImage2D: texImage2D,
27013	        texImage3D: texImage3D,
27014	        updateUBOMapping: updateUBOMapping,
27015	        uniformBlockBinding: uniformBlockBinding,
27016	        texStorage2D: texStorage2D,
27017	        texStorage3D: texStorage3D,
27018	        texSubImage2D: texSubImage2D,
27019	        texSubImage3D: texSubImage3D,
27020	        compressedTexSubImage2D: compressedTexSubImage2D,
27021	        compressedTexSubImage3D: compressedTexSubImage3D,
27022	        scissor: scissor,
27023	        viewport: viewport,
27024	        reset: reset
27025	    };
27026	}
27027	function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) {
27028	    const multisampledRTTExt = extensions.has('WEBGL_multisampled_render_to_texture') ? extensions.get('WEBGL_multisampled_render_to_texture') : null;
27029	    const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test(navigator.userAgent);
27030	    const _imageDimensions = new Vector2();
27031	    const _videoTextures = new WeakMap();
27032	    let _canvas;
27033	    const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
27034	    // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
27035	    // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
27036	    // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
27037	    let useOffscreenCanvas = false;
27038	    try {
27039	        useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' && new OffscreenCanvas(1, 1).getContext('2d') !== null;
27040	    } catch (err) {
27041	    // Ignore any errors
27042	    }
27043	    function createCanvas(width, height) {
27044	        // Use OffscreenCanvas when available. Specially needed in web workers
27045	        return useOffscreenCanvas ? // eslint-disable-next-line compat/compat
27046	        new OffscreenCanvas(width, height) : createElementNS('canvas');
27047	    }
27048	    function resizeImage(image, needsNewCanvas, maxSize) {
27049	        let scale = 1;
27050	        const dimensions = getDimensions(image);
27051	        // handle case if texture exceeds max size
27052	        if (dimensions.width > maxSize || dimensions.height > maxSize) {
27053	            scale = maxSize / Math.max(dimensions.width, dimensions.height);
27054	        }
27055	        // only perform resize if necessary
27056	        if (scale < 1) {
27057	            // only perform resize for certain image types
27058	            if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap || typeof VideoFrame !== 'undefined' && image instanceof VideoFrame) {
27059	                const width = Math.floor(scale * dimensions.width);
27060	                const height = Math.floor(scale * dimensions.height);
27061	                if (_canvas === undefined) _canvas = createCanvas(width, height);
27062	                // cube textures can't reuse the same canvas
27063	                const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas;
27064	                canvas.width = width;
27065	                canvas.height = height;
27066	                const context = canvas.getContext('2d');
27067	                context.drawImage(image, 0, 0, width, height);
27068	                console.warn('THREE.WebGLRenderer: Texture has been resized from (' + dimensions.width + 'x' + dimensions.height + ') to (' + width + 'x' + height + ').');
27069	                return canvas;
27070	            } else {
27071	                if ('data' in image) {
27072	                    console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + dimensions.width + 'x' + dimensions.height + ').');
27073	                }
27074	                return image;
27075	            }
27076	        }
27077	        return image;
27078	    }
27079	    function textureNeedsGenerateMipmaps(texture) {
27080	        return texture.generateMipmaps;
27081	    }
27082	    function generateMipmap(target) {
27083	        _gl.generateMipmap(target);
27084	    }
27085	    function getTargetType(texture) {
27086	        if (texture.isWebGLCubeRenderTarget) return _gl.TEXTURE_CUBE_MAP;
27087	        if (texture.isWebGL3DRenderTarget) return _gl.TEXTURE_3D;
27088	        if (texture.isWebGLArrayRenderTarget || texture.isCompressedArrayTexture) return _gl.TEXTURE_2D_ARRAY;
27089	        return _gl.TEXTURE_2D;
27090	    }
27091	    function getInternalFormat(internalFormatName, glFormat, glType, colorSpace, forceLinearTransfer = false) {
27092	        if (internalFormatName !== null) {
27093	            if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName];
27094	            console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'');
27095	        }
27096	        let internalFormat = glFormat;
27097	        if (glFormat === _gl.RED) {
27098	            if (glType === _gl.FLOAT) internalFormat = _gl.R32F;
27099	            if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F;
27100	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8;
27101	        }
27102	        if (glFormat === _gl.RED_INTEGER) {
27103	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8UI;
27104	            if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.R16UI;
27105	            if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.R32UI;
27106	            if (glType === _gl.BYTE) internalFormat = _gl.R8I;
27107	            if (glType === _gl.SHORT) internalFormat = _gl.R16I;
27108	            if (glType === _gl.INT) internalFormat = _gl.R32I;
27109	        }
27110	        if (glFormat === _gl.RG) {
27111	            if (glType === _gl.FLOAT) internalFormat = _gl.RG32F;
27112	            if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F;
27113	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8;
27114	        }
27115	        if (glFormat === _gl.RG_INTEGER) {
27116	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8UI;
27117	            if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RG16UI;
27118	            if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RG32UI;
27119	            if (glType === _gl.BYTE) internalFormat = _gl.RG8I;
27120	            if (glType === _gl.SHORT) internalFormat = _gl.RG16I;
27121	            if (glType === _gl.INT) internalFormat = _gl.RG32I;
27122	        }
27123	        if (glFormat === _gl.RGB_INTEGER) {
27124	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGB8UI;
27125	            if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGB16UI;
27126	            if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGB32UI;
27127	            if (glType === _gl.BYTE) internalFormat = _gl.RGB8I;
27128	            if (glType === _gl.SHORT) internalFormat = _gl.RGB16I;
27129	            if (glType === _gl.INT) internalFormat = _gl.RGB32I;
27130	        }
27131	        if (glFormat === _gl.RGBA_INTEGER) {
27132	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RGBA8UI;
27133	            if (glType === _gl.UNSIGNED_SHORT) internalFormat = _gl.RGBA16UI;
27134	            if (glType === _gl.UNSIGNED_INT) internalFormat = _gl.RGBA32UI;
27135	            if (glType === _gl.BYTE) internalFormat = _gl.RGBA8I;
27136	            if (glType === _gl.SHORT) internalFormat = _gl.RGBA16I;
27137	            if (glType === _gl.INT) internalFormat = _gl.RGBA32I;
27138	        }
27139	        if (glFormat === _gl.RGB) {
27140	            if (glType === _gl.UNSIGNED_INT_5_9_9_9_REV) internalFormat = _gl.RGB9_E5;
27141	        }
27142	        if (glFormat === _gl.RGBA) {
27143	            const transfer = forceLinearTransfer ? LinearTransfer : ColorManagement.getTransfer(colorSpace);
27144	            if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F;
27145	            if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F;
27146	            if (glType === _gl.UNSIGNED_BYTE) internalFormat = transfer === SRGBTransfer ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
27147	            if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4;
27148	            if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1;
27149	        }
27150	        if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) {
27151	            extensions.get('EXT_color_buffer_float');
27152	        }
27153	        return internalFormat;
27154	    }
27155	    function getInternalDepthFormat(useStencil, depthType) {
27156	        let glInternalFormat;
27157	        if (useStencil) {
27158	            if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) {
27159	                glInternalFormat = _gl.DEPTH24_STENCIL8;
27160	            } else if (depthType === FloatType) {
27161	                glInternalFormat = _gl.DEPTH32F_STENCIL8;
27162	            } else if (depthType === UnsignedShortType) {
27163	                glInternalFormat = _gl.DEPTH24_STENCIL8;
27164	                console.warn('DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.');
27165	            }
27166	        } else {
27167	            if (depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type) {
27168	                glInternalFormat = _gl.DEPTH_COMPONENT24;
27169	            } else if (depthType === FloatType) {
27170	                glInternalFormat = _gl.DEPTH_COMPONENT32F;
27171	            } else if (depthType === UnsignedShortType) {
27172	                glInternalFormat = _gl.DEPTH_COMPONENT16;
27173	            }
27174	        }
27175	        return glInternalFormat;
27176	    }
27177	    function getMipLevels(texture, image) {
27178	        if (textureNeedsGenerateMipmaps(texture) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) {
27179	            return Math.log2(Math.max(image.width, image.height)) + 1;
27180	        } else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) {
27181	            // user-defined mipmaps
27182	            return texture.mipmaps.length;
27183	        } else if (texture.isCompressedTexture && Array.isArray(texture.image)) {
27184	            return image.mipmaps.length;
27185	        } else {
27186	            // texture without mipmaps (only base level)
27187	            return 1;
27188	        }
27189	    }
27190	    //
27191	    function onTextureDispose(event) {
27192	        const texture = event.target;
27193	        texture.removeEventListener('dispose', onTextureDispose);
27194	        deallocateTexture(texture);
27195	        if (texture.isVideoTexture) {
27196	            _videoTextures.delete(texture);
27197	        }
27198	    }
27199	    function onRenderTargetDispose(event) {
27200	        const renderTarget = event.target;
27201	        renderTarget.removeEventListener('dispose', onRenderTargetDispose);
27202	        deallocateRenderTarget(renderTarget);
27203	    }
27204	    //
27205	    function deallocateTexture(texture) {
27206	        const textureProperties = properties.get(texture);
27207	        if (textureProperties.__webglInit === undefined) return;
27208	        // check if it's necessary to remove the WebGLTexture object
27209	        const source = texture.source;
27210	        const webglTextures = _sources.get(source);
27211	        if (webglTextures) {
27212	            const webglTexture = webglTextures[textureProperties.__cacheKey];
27213	            webglTexture.usedTimes--;
27214	            // the WebGLTexture object is not used anymore, remove it
27215	            if (webglTexture.usedTimes === 0) {
27216	                deleteTexture(texture);
27217	            }
27218	            // remove the weak map entry if no WebGLTexture uses the source anymore
27219	            if (Object.keys(webglTextures).length === 0) {
27220	                _sources.delete(source);
27221	            }
27222	        }
27223	        properties.remove(texture);
27224	    }
27225	    function deleteTexture(texture) {
27226	        const textureProperties = properties.get(texture);
27227	        _gl.deleteTexture(textureProperties.__webglTexture);
27228	        const source = texture.source;
27229	        const webglTextures = _sources.get(source);
27230	        delete webglTextures[textureProperties.__cacheKey];
27231	        info.memory.textures--;
27232	    }
27233	    function deallocateRenderTarget(renderTarget) {
27234	        const renderTargetProperties = properties.get(renderTarget);
27235	        if (renderTarget.depthTexture) {
27236	            renderTarget.depthTexture.dispose();
27237	            properties.remove(renderTarget.depthTexture);
27238	        }
vendor: 8,880 bytes, lines 27239-27396
27239	        if (renderTarget.isWebGLCubeRenderTarget) {
27240	            for(let i = 0; i < 6; i++){
27241	                if (Array.isArray(renderTargetProperties.__webglFramebuffer[i])) {
27242	                    for(let level = 0; level < renderTargetProperties.__webglFramebuffer[i].length; level++)_gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i][level]);
27243	                } else {
27244	                    _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]);
27245	                }
27246	                if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]);
27247	            }
27248	        } else {
27249	            if (Array.isArray(renderTargetProperties.__webglFramebuffer)) {
27250	                for(let level = 0; level < renderTargetProperties.__webglFramebuffer.length; level++)_gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[level]);
27251	            } else {
27252	                _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer);
27253	            }
27254	            if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer);
27255	            if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer);
27256	            if (renderTargetProperties.__webglColorRenderbuffer) {
27257	                for(let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++){
27258	                    if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]);
27259	                }
27260	            }
27261	            if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer);
27262	        }
27263	        const textures = renderTarget.textures;
27264	        for(let i = 0, il = textures.length; i < il; i++){
27265	            const attachmentProperties = properties.get(textures[i]);
27266	            if (attachmentProperties.__webglTexture) {
27267	                _gl.deleteTexture(attachmentProperties.__webglTexture);
27268	                info.memory.textures--;
27269	            }
27270	            properties.remove(textures[i]);
27271	        }
27272	        properties.remove(renderTarget);
27273	    }
27274	    //
27275	    let textureUnits = 0;
27276	    function resetTextureUnits() {
27277	        textureUnits = 0;
27278	    }
27279	    function allocateTextureUnit() {
27280	        const textureUnit = textureUnits;
27281	        if (textureUnit >= capabilities.maxTextures) {
27282	            console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + capabilities.maxTextures);
27283	        }
27284	        textureUnits += 1;
27285	        return textureUnit;
27286	    }
27287	    function getTextureCacheKey(texture) {
27288	        const array = [];
27289	        array.push(texture.wrapS);
27290	        array.push(texture.wrapT);
27291	        array.push(texture.wrapR || 0);
27292	        array.push(texture.magFilter);
27293	        array.push(texture.minFilter);
27294	        array.push(texture.anisotropy);
27295	        array.push(texture.internalFormat);
27296	        array.push(texture.format);
27297	        array.push(texture.type);
27298	        array.push(texture.generateMipmaps);
27299	        array.push(texture.premultiplyAlpha);
27300	        array.push(texture.flipY);
27301	        array.push(texture.unpackAlignment);
27302	        array.push(texture.colorSpace);
27303	        return array.join();
27304	    }
27305	    //
27306	    function setTexture2D(texture, slot) {
27307	        const textureProperties = properties.get(texture);
27308	        if (texture.isVideoTexture) updateVideoTexture(texture);
27309	        if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) {
27310	            const image = texture.image;
27311	            if (image === null) {
27312	                console.warn('THREE.WebGLRenderer: Texture marked for update but no image data found.');
27313	            } else if (image.complete === false) {
27314	                console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete');
27315	            } else {
27316	                uploadTexture(textureProperties, texture, slot);
27317	                return;
27318	            }
27319	        }
27320	        state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27321	    }
27322	    function setTexture2DArray(texture, slot) {
27323	        const textureProperties = properties.get(texture);
27324	        if (texture.version > 0 && textureProperties.__version !== texture.version) {
27325	            uploadTexture(textureProperties, texture, slot);
27326	            return;
27327	        }
27328	        state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27329	    }
27330	    function setTexture3D(texture, slot) {
27331	        const textureProperties = properties.get(texture);
27332	        if (texture.version > 0 && textureProperties.__version !== texture.version) {
27333	            uploadTexture(textureProperties, texture, slot);
27334	            return;
27335	        }
27336	        state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27337	    }
27338	    function setTextureCube(texture, slot) {
27339	        const textureProperties = properties.get(texture);
27340	        if (texture.version > 0 && textureProperties.__version !== texture.version) {
27341	            uploadCubeTexture(textureProperties, texture, slot);
27342	            return;
27343	        }
27344	        state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27345	    }
27346	    const wrappingToGL = {
27347	        [RepeatWrapping]: _gl.REPEAT,
27348	        [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE,
27349	        [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT
27350	    };
27351	    const filterToGL = {
27352	        [NearestFilter]: _gl.NEAREST,
27353	        [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST,
27354	        [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR,
27355	        [LinearFilter]: _gl.LINEAR,
27356	        [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST,
27357	        [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR
27358	    };
27359	    const compareToGL = {
27360	        [NeverCompare]: _gl.NEVER,
27361	        [AlwaysCompare]: _gl.ALWAYS,
27362	        [LessCompare]: _gl.LESS,
27363	        [LessEqualCompare]: _gl.LEQUAL,
27364	        [EqualCompare]: _gl.EQUAL,
27365	        [GreaterEqualCompare]: _gl.GEQUAL,
27366	        [GreaterCompare]: _gl.GREATER,
27367	        [NotEqualCompare]: _gl.NOTEQUAL
27368	    };
27369	    function setTextureParameters(textureType, texture) {
27370	        if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false && (texture.magFilter === LinearFilter || texture.magFilter === LinearMipmapNearestFilter || texture.magFilter === NearestMipmapLinearFilter || texture.magFilter === LinearMipmapLinearFilter || texture.minFilter === LinearFilter || texture.minFilter === LinearMipmapNearestFilter || texture.minFilter === NearestMipmapLinearFilter || texture.minFilter === LinearMipmapLinearFilter)) {
27371	            console.warn('THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device.');
27372	        }
27373	        _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]);
27374	        _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]);
27375	        if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) {
27376	            _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]);
27377	        }
27378	        _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]);
27379	        _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]);
27380	        if (texture.compareFunction) {
27381	            _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_MODE, _gl.COMPARE_REF_TO_TEXTURE);
27382	            _gl.texParameteri(textureType, _gl.TEXTURE_COMPARE_FUNC, compareToGL[texture.compareFunction]);
27383	        }
27384	        if (extensions.has('EXT_texture_filter_anisotropic') === true) {
27385	            if (texture.magFilter === NearestFilter) return;
27386	            if (texture.minFilter !== NearestMipmapLinearFilter && texture.minFilter !== LinearMipmapLinearFilter) return;
27387	            if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension
27388	            if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) {
27389	                const extension = extensions.get('EXT_texture_filter_anisotropic');
27390	                _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy()));
27391	                properties.get(texture).__currentAnisotropy = texture.anisotropy;
27392	            }
27393	        }
27394	    }
27395	    function initTexture(textureProperties, texture) {
27396	        let forceUpload = false;
vendor: 32,977 bytes, lines 27397-27906
27397	        if (textureProperties.__webglInit === undefined) {
27398	            textureProperties.__webglInit = true;
27399	            texture.addEventListener('dispose', onTextureDispose);
27400	        }
27401	        // create Source <-> WebGLTextures mapping if necessary
27402	        const source = texture.source;
27403	        let webglTextures = _sources.get(source);
27404	        if (webglTextures === undefined) {
27405	            webglTextures = {};
27406	            _sources.set(source, webglTextures);
27407	        }
27408	        // check if there is already a WebGLTexture object for the given texture parameters
27409	        const textureCacheKey = getTextureCacheKey(texture);
27410	        if (textureCacheKey !== textureProperties.__cacheKey) {
27411	            // if not, create a new instance of WebGLTexture
27412	            if (webglTextures[textureCacheKey] === undefined) {
27413	                // create new entry
27414	                webglTextures[textureCacheKey] = {
27415	                    texture: _gl.createTexture(),
27416	                    usedTimes: 0
27417	                };
27418	                info.memory.textures++;
27419	                // when a new instance of WebGLTexture was created, a texture upload is required
27420	                // even if the image contents are identical
27421	                forceUpload = true;
27422	            }
27423	            webglTextures[textureCacheKey].usedTimes++;
27424	            // every time the texture cache key changes, it's necessary to check if an instance of
27425	            // WebGLTexture can be deleted in order to avoid a memory leak.
27426	            const webglTexture = webglTextures[textureProperties.__cacheKey];
27427	            if (webglTexture !== undefined) {
27428	                webglTextures[textureProperties.__cacheKey].usedTimes--;
27429	                if (webglTexture.usedTimes === 0) {
27430	                    deleteTexture(texture);
27431	                }
27432	            }
27433	            // store references to cache key and WebGLTexture object
27434	            textureProperties.__cacheKey = textureCacheKey;
27435	            textureProperties.__webglTexture = webglTextures[textureCacheKey].texture;
27436	        }
27437	        return forceUpload;
27438	    }
27439	    function uploadTexture(textureProperties, texture, slot) {
27440	        let textureType = _gl.TEXTURE_2D;
27441	        if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY;
27442	        if (texture.isData3DTexture) textureType = _gl.TEXTURE_3D;
27443	        const forceUpload = initTexture(textureProperties, texture);
27444	        const source = texture.source;
27445	        state.bindTexture(textureType, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27446	        const sourceProperties = properties.get(source);
27447	        if (source.version !== sourceProperties.__version || forceUpload === true) {
27448	            state.activeTexture(_gl.TEXTURE0 + slot);
27449	            const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace);
27450	            const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture.colorSpace);
27451	            const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
27452	            _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
27453	            _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
27454	            _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
27455	            _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion);
27456	            let image = resizeImage(texture.image, false, capabilities.maxTextureSize);
27457	            image = verifyColorSpace(texture, image);
27458	            const glFormat = utils.convert(texture.format, texture.colorSpace);
27459	            const glType = utils.convert(texture.type);
27460	            let glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace, texture.isVideoTexture);
27461	            setTextureParameters(textureType, texture);
27462	            let mipmap;
27463	            const mipmaps = texture.mipmaps;
27464	            const useTexStorage = texture.isVideoTexture !== true;
27465	            const allocateMemory = sourceProperties.__version === undefined || forceUpload === true;
27466	            const dataReady = source.dataReady;
27467	            const levels = getMipLevels(texture, image);
27468	            if (texture.isDepthTexture) {
27469	                glInternalFormat = getInternalDepthFormat(texture.format === DepthStencilFormat, texture.type);
27470	                //
27471	                if (allocateMemory) {
27472	                    if (useTexStorage) {
27473	                        state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height);
27474	                    } else {
27475	                        state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null);
27476	                    }
27477	                }
27478	            } else if (texture.isDataTexture) {
27479	                // use manually created mipmaps if available
27480	                // if there are no manual mipmaps
27481	                // set 0 level mipmap and then use GL to generate other mipmap levels
27482	                if (mipmaps.length > 0) {
27483	                    if (useTexStorage && allocateMemory) {
27484	                        state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
27485	                    }
27486	                    for(let i = 0, il = mipmaps.length; i < il; i++){
27487	                        mipmap = mipmaps[i];
27488	                        if (useTexStorage) {
27489	                            if (dataReady) {
27490	                                state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
27491	                            }
27492	                        } else {
27493	                            state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
27494	                        }
27495	                    }
27496	                    texture.generateMipmaps = false;
27497	                } else {
27498	                    if (useTexStorage) {
27499	                        if (allocateMemory) {
27500	                            state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
27501	                        }
27502	                        if (dataReady) {
27503	                            state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data);
27504	                        }
27505	                    } else {
27506	                        state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data);
27507	                    }
27508	                }
27509	            } else if (texture.isCompressedTexture) {
27510	                if (texture.isCompressedArrayTexture) {
27511	                    if (useTexStorage && allocateMemory) {
27512	                        state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height, image.depth);
27513	                    }
27514	                    for(let i = 0, il = mipmaps.length; i < il; i++){
27515	                        mipmap = mipmaps[i];
27516	                        if (texture.format !== RGBAFormat) {
27517	                            if (glFormat !== null) {
27518	                                if (useTexStorage) {
27519	                                    if (dataReady) {
27520	                                        if (texture.layerUpdates.size > 0) {
27521	                                            const layerByteLength = getByteLength(mipmap.width, mipmap.height, texture.format, texture.type);
27522	                                            for (const layerIndex of texture.layerUpdates){
27523	                                                const layerData = mipmap.data.subarray(layerIndex * layerByteLength / mipmap.data.BYTES_PER_ELEMENT, (layerIndex + 1) * layerByteLength / mipmap.data.BYTES_PER_ELEMENT);
27524	                                                state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData);
27525	                                            }
27526	                                            texture.clearLayerUpdates();
27527	                                        } else {
27528	                                            state.compressedTexSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data);
27529	                                        }
27530	                                    }
27531	                                } else {
27532	                                    state.compressedTexImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data, 0, 0);
27533	                                }
27534	                            } else {
27535	                                console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()');
27536	                            }
27537	                        } else {
27538	                            if (useTexStorage) {
27539	                                if (dataReady) {
27540	                                    state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data);
27541	                                }
27542	                            } else {
27543	                                state.texImage3D(_gl.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data);
27544	                            }
27545	                        }
27546	                    }
27547	                } else {
27548	                    if (useTexStorage && allocateMemory) {
27549	                        state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
27550	                    }
27551	                    for(let i = 0, il = mipmaps.length; i < il; i++){
27552	                        mipmap = mipmaps[i];
27553	                        if (texture.format !== RGBAFormat) {
27554	                            if (glFormat !== null) {
27555	                                if (useTexStorage) {
27556	                                    if (dataReady) {
27557	                                        state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
27558	                                    }
27559	                                } else {
27560	                                    state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
27561	                                }
27562	                            } else {
27563	                                console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()');
27564	                            }
27565	                        } else {
27566	                            if (useTexStorage) {
27567	                                if (dataReady) {
27568	                                    state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
27569	                                }
27570	                            } else {
27571	                                state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
27572	                            }
27573	                        }
27574	                    }
27575	                }
27576	            } else if (texture.isDataArrayTexture) {
27577	                if (useTexStorage) {
27578	                    if (allocateMemory) {
27579	                        state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth);
27580	                    }
27581	                    if (dataReady) {
27582	                        if (texture.layerUpdates.size > 0) {
27583	                            const layerByteLength = getByteLength(image.width, image.height, texture.format, texture.type);
27584	                            for (const layerIndex of texture.layerUpdates){
27585	                                const layerData = image.data.subarray(layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, (layerIndex + 1) * layerByteLength / image.data.BYTES_PER_ELEMENT);
27586	                                state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData);
27587	                            }
27588	                            texture.clearLayerUpdates();
27589	                        } else {
27590	                            state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
27591	                        }
27592	                    }
27593	                } else {
27594	                    state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
27595	                }
27596	            } else if (texture.isData3DTexture) {
27597	                if (useTexStorage) {
27598	                    if (allocateMemory) {
27599	                        state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth);
27600	                    }
27601	                    if (dataReady) {
27602	                        state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
27603	                    }
27604	                } else {
27605	                    state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
27606	                }
27607	            } else if (texture.isFramebufferTexture) {
27608	                if (allocateMemory) {
27609	                    if (useTexStorage) {
27610	                        state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
27611	                    } else {
27612	                        let width = image.width, height = image.height;
27613	                        for(let i = 0; i < levels; i++){
27614	                            state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null);
27615	                            width >>= 1;
27616	                            height >>= 1;
27617	                        }
27618	                    }
27619	                }
27620	            } else {
27621	                // regular Texture (image, video, canvas)
27622	                // use manually created mipmaps if available
27623	                // if there are no manual mipmaps
27624	                // set 0 level mipmap and then use GL to generate other mipmap levels
27625	                if (mipmaps.length > 0) {
27626	                    if (useTexStorage && allocateMemory) {
27627	                        const dimensions = getDimensions(mipmaps[0]);
27628	                        state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height);
27629	                    }
27630	                    for(let i = 0, il = mipmaps.length; i < il; i++){
27631	                        mipmap = mipmaps[i];
27632	                        if (useTexStorage) {
27633	                            if (dataReady) {
27634	                                state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap);
27635	                            }
27636	                        } else {
27637	                            state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap);
27638	                        }
27639	                    }
27640	                    texture.generateMipmaps = false;
27641	                } else {
27642	                    if (useTexStorage) {
27643	                        if (allocateMemory) {
27644	                            const dimensions = getDimensions(image);
27645	                            state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height);
27646	                        }
27647	                        if (dataReady) {
27648	                            state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image);
27649	                        }
27650	                    } else {
27651	                        state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image);
27652	                    }
27653	                }
27654	            }
27655	            if (textureNeedsGenerateMipmaps(texture)) {
27656	                generateMipmap(textureType);
27657	            }
27658	            sourceProperties.__version = source.version;
27659	            if (texture.onUpdate) texture.onUpdate(texture);
27660	        }
27661	        textureProperties.__version = texture.version;
27662	    }
27663	    function uploadCubeTexture(textureProperties, texture, slot) {
27664	        if (texture.image.length !== 6) return;
27665	        const forceUpload = initTexture(textureProperties, texture);
27666	        const source = texture.source;
27667	        state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture, _gl.TEXTURE0 + slot);
27668	        const sourceProperties = properties.get(source);
27669	        if (source.version !== sourceProperties.__version || forceUpload === true) {
27670	            state.activeTexture(_gl.TEXTURE0 + slot);
27671	            const workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace);
27672	            const texturePrimaries = texture.colorSpace === NoColorSpace ? null : ColorManagement.getPrimaries(texture.colorSpace);
27673	            const unpackConversion = texture.colorSpace === NoColorSpace || workingPrimaries === texturePrimaries ? _gl.NONE : _gl.BROWSER_DEFAULT_WEBGL;
27674	            _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
27675	            _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
27676	            _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
27677	            _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion);
27678	            const isCompressed = texture.isCompressedTexture || texture.image[0].isCompressedTexture;
27679	            const isDataTexture = texture.image[0] && texture.image[0].isDataTexture;
27680	            const cubeImage = [];
27681	            for(let i = 0; i < 6; i++){
27682	                if (!isCompressed && !isDataTexture) {
27683	                    cubeImage[i] = resizeImage(texture.image[i], true, capabilities.maxCubemapSize);
27684	                } else {
27685	                    cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i];
27686	                }
27687	                cubeImage[i] = verifyColorSpace(texture, cubeImage[i]);
27688	            }
27689	            const image = cubeImage[0], glFormat = utils.convert(texture.format, texture.colorSpace), glType = utils.convert(texture.type), glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace);
27690	            const useTexStorage = texture.isVideoTexture !== true;
27691	            const allocateMemory = sourceProperties.__version === undefined || forceUpload === true;
27692	            const dataReady = source.dataReady;
27693	            let levels = getMipLevels(texture, image);
27694	            setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture);
27695	            let mipmaps;
27696	            if (isCompressed) {
27697	                if (useTexStorage && allocateMemory) {
27698	                    state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height);
27699	                }
27700	                for(let i = 0; i < 6; i++){
27701	                    mipmaps = cubeImage[i].mipmaps;
27702	                    for(let j = 0; j < mipmaps.length; j++){
27703	                        const mipmap = mipmaps[j];
27704	                        if (texture.format !== RGBAFormat) {
27705	                            if (glFormat !== null) {
27706	                                if (useTexStorage) {
27707	                                    if (dataReady) {
27708	                                        state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
27709	                                    }
27710	                                } else {
27711	                                    state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
27712	                                }
27713	                            } else {
27714	                                console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()');
27715	                            }
27716	                        } else {
27717	                            if (useTexStorage) {
27718	                                if (dataReady) {
27719	                                    state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
27720	                                }
27721	                            } else {
27722	                                state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
27723	                            }
27724	                        }
27725	                    }
27726	                }
27727	            } else {
27728	                mipmaps = texture.mipmaps;
27729	                if (useTexStorage && allocateMemory) {
27730	                    // TODO: Uniformly handle mipmap definitions
27731	                    // Normal textures and compressed cube textures define base level + mips with their mipmap array
27732	                    // Uncompressed cube textures use their mipmap array only for mips (no base level)
27733	                    if (mipmaps.length > 0) levels++;
27734	                    const dimensions = getDimensions(cubeImage[0]);
27735	                    state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, dimensions.width, dimensions.height);
27736	                }
27737	                for(let i = 0; i < 6; i++){
27738	                    if (isDataTexture) {
27739	                        if (useTexStorage) {
27740	                            if (dataReady) {
27741	                                state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data);
27742	                            }
27743	                        } else {
27744	                            state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data);
27745	                        }
27746	                        for(let j = 0; j < mipmaps.length; j++){
27747	                            const mipmap = mipmaps[j];
27748	                            const mipmapImage = mipmap.image[i].image;
27749	                            if (useTexStorage) {
27750	                                if (dataReady) {
27751	                                    state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data);
27752	                                }
27753	                            } else {
27754	                                state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data);
27755	                            }
27756	                        }
27757	                    } else {
27758	                        if (useTexStorage) {
27759	                            if (dataReady) {
27760	                                state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]);
27761	                            }
27762	                        } else {
27763	                            state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]);
27764	                        }
27765	                        for(let j = 0; j < mipmaps.length; j++){
27766	                            const mipmap = mipmaps[j];
27767	                            if (useTexStorage) {
27768	                                if (dataReady) {
27769	                                    state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]);
27770	                                }
27771	                            } else {
27772	                                state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]);
27773	                            }
27774	                        }
27775	                    }
27776	                }
27777	            }
27778	            if (textureNeedsGenerateMipmaps(texture)) {
27779	                // We assume images for cube map have the same size.
27780	                generateMipmap(_gl.TEXTURE_CUBE_MAP);
27781	            }
27782	            sourceProperties.__version = source.version;
27783	            if (texture.onUpdate) texture.onUpdate(texture);
27784	        }
27785	        textureProperties.__version = texture.version;
27786	    }
27787	    // Render targets
27788	    // Setup storage for target texture and bind it to correct framebuffer
27789	    function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget, level) {
27790	        const glFormat = utils.convert(texture.format, texture.colorSpace);
27791	        const glType = utils.convert(texture.type);
27792	        const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace);
27793	        const renderTargetProperties = properties.get(renderTarget);
27794	        const textureProperties = properties.get(texture);
27795	        textureProperties.__renderTarget = renderTarget;
27796	        if (!renderTargetProperties.__hasExternalTextures) {
27797	            const width = Math.max(1, renderTarget.width >> level);
27798	            const height = Math.max(1, renderTarget.height >> level);
27799	            if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) {
27800	                state.texImage3D(textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null);
27801	            } else {
27802	                state.texImage2D(textureTarget, level, glInternalFormat, width, height, 0, glFormat, glType, null);
27803	            }
27804	        }
27805	        state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
27806	        if (useMultisampledRTT(renderTarget)) {
27807	            multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, 0, getRenderTargetSamples(renderTarget));
27808	        } else if (textureTarget === _gl.TEXTURE_2D || textureTarget >= _gl.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= _gl.TEXTURE_CUBE_MAP_NEGATIVE_Z) {
27809	            _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, textureProperties.__webglTexture, level);
27810	        }
27811	        state.bindFramebuffer(_gl.FRAMEBUFFER, null);
27812	    }
27813	    // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
27814	    function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) {
27815	        _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer);
27816	        if (renderTarget.depthBuffer) {
27817	            // retrieve the depth attachment types
27818	            const depthTexture = renderTarget.depthTexture;
27819	            const depthType = depthTexture && depthTexture.isDepthTexture ? depthTexture.type : null;
27820	            const glInternalFormat = getInternalDepthFormat(renderTarget.stencilBuffer, depthType);
27821	            const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
27822	            // set up the attachment
27823	            const samples = getRenderTargetSamples(renderTarget);
27824	            const isUseMultisampledRTT = useMultisampledRTT(renderTarget);
27825	            if (isUseMultisampledRTT) {
27826	                multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
27827	            } else if (isMultisample) {
27828	                _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
27829	            } else {
27830	                _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
27831	            }
27832	            _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer);
27833	        } else {
27834	            const textures = renderTarget.textures;
27835	            for(let i = 0; i < textures.length; i++){
27836	                const texture = textures[i];
27837	                const glFormat = utils.convert(texture.format, texture.colorSpace);
27838	                const glType = utils.convert(texture.type);
27839	                const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace);
27840	                const samples = getRenderTargetSamples(renderTarget);
27841	                if (isMultisample && useMultisampledRTT(renderTarget) === false) {
27842	                    _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
27843	                } else if (useMultisampledRTT(renderTarget)) {
27844	                    multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
27845	                } else {
27846	                    _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
27847	                }
27848	            }
27849	        }
27850	        _gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
27851	    }
27852	    // Setup resources for a Depth Texture for a FBO (needs an extension)
27853	    function setupDepthTexture(framebuffer, renderTarget) {
27854	        const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget;
27855	        if (isCube) throw new Error('Depth Texture with cube render targets is not supported');
27856	        state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
27857	        if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) {
27858	            throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
27859	        }
27860	        const textureProperties = properties.get(renderTarget.depthTexture);
27861	        textureProperties.__renderTarget = renderTarget;
27862	        // upload an empty depth texture with framebuffer size
27863	        if (!textureProperties.__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) {
27864	            renderTarget.depthTexture.image.width = renderTarget.width;
27865	            renderTarget.depthTexture.image.height = renderTarget.height;
27866	            renderTarget.depthTexture.needsUpdate = true;
27867	        }
27868	        setTexture2D(renderTarget.depthTexture, 0);
27869	        const webglDepthTexture = textureProperties.__webglTexture;
27870	        const samples = getRenderTargetSamples(renderTarget);
27871	        if (renderTarget.depthTexture.format === DepthFormat) {
27872	            if (useMultisampledRTT(renderTarget)) {
27873	                multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
27874	            } else {
27875	                _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
27876	            }
27877	        } else if (renderTarget.depthTexture.format === DepthStencilFormat) {
27878	            if (useMultisampledRTT(renderTarget)) {
27879	                multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
27880	            } else {
27881	                _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
27882	            }
27883	        } else {
27884	            throw new Error('Unknown depthTexture format');
27885	        }
27886	    }
27887	    // Setup GL resources for a non-texture depth buffer
27888	    function setupDepthRenderbuffer(renderTarget) {
27889	        const renderTargetProperties = properties.get(renderTarget);
27890	        const isCube = renderTarget.isWebGLCubeRenderTarget === true;
27891	        // if the bound depth texture has changed
27892	        if (renderTargetProperties.__boundDepthTexture !== renderTarget.depthTexture) {
27893	            // fire the dispose event to get rid of stored state associated with the previously bound depth buffer
27894	            const depthTexture = renderTarget.depthTexture;
27895	            if (renderTargetProperties.__depthDisposeCallback) {
27896	                renderTargetProperties.__depthDisposeCallback();
27897	            }
27898	            // set up dispose listeners to track when the currently attached buffer is implicitly unbound
27899	            if (depthTexture) {
27900	                const disposeEvent = ()=>{
27901	                    delete renderTargetProperties.__boundDepthTexture;
27902	                    delete renderTargetProperties.__depthDisposeCallback;
27903	                    depthTexture.removeEventListener('dispose', disposeEvent);
27904	                };
27905	                depthTexture.addEventListener('dispose', disposeEvent);
27906	                renderTargetProperties.__depthDisposeCallback = dis
vendor: 5,662 bytes, lines 27906-28003
27906poseEvent;
27907	            }
27908	            renderTargetProperties.__boundDepthTexture = depthTexture;
27909	        }
27910	        if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) {
27911	            if (isCube) throw new Error('target.depthTexture not supported in Cube render targets');
27912	            setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget);
27913	        } else {
27914	            if (isCube) {
27915	                renderTargetProperties.__webglDepthbuffer = [];
27916	                for(let i = 0; i < 6; i++){
27917	                    state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]);
27918	                    if (renderTargetProperties.__webglDepthbuffer[i] === undefined) {
27919	                        renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer();
27920	                        setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false);
27921	                    } else {
27922	                        // attach buffer if it's been created already
27923	                        const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
27924	                        const renderbuffer = renderTargetProperties.__webglDepthbuffer[i];
27925	                        _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer);
27926	                        _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer);
27927	                    }
27928	                }
27929	            } else {
27930	                state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
27931	                if (renderTargetProperties.__webglDepthbuffer === undefined) {
27932	                    renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
27933	                    setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false);
27934	                } else {
27935	                    // attach buffer if it's been created already
27936	                    const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
27937	                    const renderbuffer = renderTargetProperties.__webglDepthbuffer;
27938	                    _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer);
27939	                    _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer);
27940	                }
27941	            }
27942	        }
27943	        state.bindFramebuffer(_gl.FRAMEBUFFER, null);
27944	    }
27945	    // rebind framebuffer with external textures
27946	    function rebindTextures(renderTarget, colorTexture, depthTexture) {
27947	        const renderTargetProperties = properties.get(renderTarget);
27948	        if (colorTexture !== undefined) {
27949	            setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, 0);
27950	        }
27951	        if (depthTexture !== undefined) {
27952	            setupDepthRenderbuffer(renderTarget);
27953	        }
27954	    }
27955	    // Set up GL resources for the render target
27956	    function setupRenderTarget(renderTarget) {
27957	        const texture = renderTarget.texture;
27958	        const renderTargetProperties = properties.get(renderTarget);
27959	        const textureProperties = properties.get(texture);
27960	        renderTarget.addEventListener('dispose', onRenderTargetDispose);
27961	        const textures = renderTarget.textures;
27962	        const isCube = renderTarget.isWebGLCubeRenderTarget === true;
27963	        const isMultipleRenderTargets = textures.length > 1;
27964	        if (!isMultipleRenderTargets) {
27965	            if (textureProperties.__webglTexture === undefined) {
27966	                textureProperties.__webglTexture = _gl.createTexture();
27967	            }
27968	            textureProperties.__version = texture.version;
27969	            info.memory.textures++;
27970	        }
27971	        // Setup framebuffer
27972	        if (isCube) {
27973	            renderTargetProperties.__webglFramebuffer = [];
27974	            for(let i = 0; i < 6; i++){
27975	                if (texture.mipmaps && texture.mipmaps.length > 0) {
27976	                    renderTargetProperties.__webglFramebuffer[i] = [];
27977	                    for(let level = 0; level < texture.mipmaps.length; level++){
27978	                        renderTargetProperties.__webglFramebuffer[i][level] = _gl.createFramebuffer();
27979	                    }
27980	                } else {
27981	                    renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer();
27982	                }
27983	            }
27984	        } else {
27985	            if (texture.mipmaps && texture.mipmaps.length > 0) {
27986	                renderTargetProperties.__webglFramebuffer = [];
27987	                for(let level = 0; level < texture.mipmaps.length; level++){
27988	                    renderTargetProperties.__webglFramebuffer[level] = _gl.createFramebuffer();
27989	                }
27990	            } else {
27991	                renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
27992	            }
27993	            if (isMultipleRenderTargets) {
27994	                for(let i = 0, il = textures.length; i < il; i++){
27995	                    const attachmentProperties = properties.get(textures[i]);
27996	                    if (attachmentProperties.__webglTexture === undefined) {
27997	                        attachmentProperties.__webglTexture = _gl.createTexture();
27998	                        info.memory.textures++;
27999	                    }
28000	                }
28001	            }
28002	            if (renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) {
28003	                renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
vendor: 7,582 bytes, lines 28004-28121
28004	                renderTargetProperties.__webglColorRenderbuffer = [];
28005	                state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
28006	                for(let i = 0; i < textures.length; i++){
28007	                    const texture = textures[i];
28008	                    renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer();
28009	                    _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
28010	                    const glFormat = utils.convert(texture.format, texture.colorSpace);
28011	                    const glType = utils.convert(texture.type);
28012	                    const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget === true);
28013	                    const samples = getRenderTargetSamples(renderTarget);
28014	                    _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
28015	                    _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
28016	                }
28017	                _gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
28018	                if (renderTarget.depthBuffer) {
28019	                    renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
28020	                    setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true);
28021	                }
28022	                state.bindFramebuffer(_gl.FRAMEBUFFER, null);
28023	            }
28024	        }
28025	        // Setup color buffer
28026	        if (isCube) {
28027	            state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
28028	            setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture);
28029	            for(let i = 0; i < 6; i++){
28030	                if (texture.mipmaps && texture.mipmaps.length > 0) {
28031	                    for(let level = 0; level < texture.mipmaps.length; level++){
28032	                        setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i][level], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level);
28033	                    }
28034	                } else {
28035	                    setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0);
28036	                }
28037	            }
28038	            if (textureNeedsGenerateMipmaps(texture)) {
28039	                generateMipmap(_gl.TEXTURE_CUBE_MAP);
28040	            }
28041	            state.unbindTexture();
28042	        } else if (isMultipleRenderTargets) {
28043	            for(let i = 0, il = textures.length; i < il; i++){
28044	                const attachment = textures[i];
28045	                const attachmentProperties = properties.get(attachment);
28046	                state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture);
28047	                setTextureParameters(_gl.TEXTURE_2D, attachment);
28048	                setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, 0);
28049	                if (textureNeedsGenerateMipmaps(attachment)) {
28050	                    generateMipmap(_gl.TEXTURE_2D);
28051	                }
28052	            }
28053	            state.unbindTexture();
28054	        } else {
28055	            let glTextureType = _gl.TEXTURE_2D;
28056	            if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) {
28057	                glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY;
28058	            }
28059	            state.bindTexture(glTextureType, textureProperties.__webglTexture);
28060	            setTextureParameters(glTextureType, texture);
28061	            if (texture.mipmaps && texture.mipmaps.length > 0) {
28062	                for(let level = 0; level < texture.mipmaps.length; level++){
28063	                    setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[level], renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType, level);
28064	                }
28065	            } else {
28066	                setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType, 0);
28067	            }
28068	            if (textureNeedsGenerateMipmaps(texture)) {
28069	                generateMipmap(glTextureType);
28070	            }
28071	            state.unbindTexture();
28072	        }
28073	        // Setup depth and stencil buffers
28074	        if (renderTarget.depthBuffer) {
28075	            setupDepthRenderbuffer(renderTarget);
28076	        }
28077	    }
28078	    function updateRenderTargetMipmap(renderTarget) {
28079	        const textures = renderTarget.textures;
28080	        for(let i = 0, il = textures.length; i < il; i++){
28081	            const texture = textures[i];
28082	            if (textureNeedsGenerateMipmaps(texture)) {
28083	                const targetType = getTargetType(renderTarget);
28084	                const webglTexture = properties.get(texture).__webglTexture;
28085	                state.bindTexture(targetType, webglTexture);
28086	                generateMipmap(targetType);
28087	                state.unbindTexture();
28088	            }
28089	        }
28090	    }
28091	    const invalidationArrayRead = [];
28092	    const invalidationArrayDraw = [];
28093	    function updateMultisampleRenderTarget(renderTarget) {
28094	        if (renderTarget.samples > 0) {
28095	            if (useMultisampledRTT(renderTarget) === false) {
28096	                const textures = renderTarget.textures;
28097	                const width = renderTarget.width;
28098	                const height = renderTarget.height;
28099	                let mask = _gl.COLOR_BUFFER_BIT;
28100	                const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
28101	                const renderTargetProperties = properties.get(renderTarget);
28102	                const isMultipleRenderTargets = textures.length > 1;
28103	                // If MRT we need to remove FBO attachments
28104	                if (isMultipleRenderTargets) {
28105	                    for(let i = 0; i < textures.length; i++){
28106	                        state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
28107	                        _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null);
28108	                        state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
28109	                        _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0);
28110	                    }
28111	                }
28112	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
28113	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
28114	                for(let i = 0; i < textures.length; i++){
28115	                    if (renderTarget.resolveDepthBuffer) {
28116	                        if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT;
28117	                        // resolving stencil is slow with a D3D backend. disable it for all transmission render targets (see #27799)
28118	                        if (renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT;
28119	                    }
28120	                    if (isMultipleRenderTargets) {
28121	                        _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRen
vendor: 4,605 bytes, lines 28121-28196
28121derbuffer[i]);
28122	                        const webglTexture = properties.get(textures[i]).__webglTexture;
28123	                        _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0);
28124	                    }
28125	                    _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST);
28126	                    if (supportsInvalidateFramebuffer === true) {
28127	                        invalidationArrayRead.length = 0;
28128	                        invalidationArrayDraw.length = 0;
28129	                        invalidationArrayRead.push(_gl.COLOR_ATTACHMENT0 + i);
28130	                        if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false) {
28131	                            invalidationArrayRead.push(depthStyle);
28132	                            invalidationArrayDraw.push(depthStyle);
28133	                            _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, invalidationArrayDraw);
28134	                        }
28135	                        _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArrayRead);
28136	                    }
28137	                }
28138	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null);
28139	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null);
28140	                // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments
28141	                if (isMultipleRenderTargets) {
28142	                    for(let i = 0; i < textures.length; i++){
28143	                        state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
28144	                        _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
28145	                        const webglTexture = properties.get(textures[i]).__webglTexture;
28146	                        state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
28147	                        _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0);
28148	                    }
28149	                }
28150	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
28151	            } else {
28152	                if (renderTarget.depthBuffer && renderTarget.resolveDepthBuffer === false && supportsInvalidateFramebuffer) {
28153	                    const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
28154	                    _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [
28155	                        depthStyle
28156	                    ]);
28157	                }
28158	            }
28159	        }
28160	    }
28161	    function getRenderTargetSamples(renderTarget) {
28162	        return Math.min(capabilities.maxSamples, renderTarget.samples);
28163	    }
28164	    function useMultisampledRTT(renderTarget) {
28165	        const renderTargetProperties = properties.get(renderTarget);
28166	        return renderTarget.samples > 0 && extensions.has('WEBGL_multisampled_render_to_texture') === true && renderTargetProperties.__useRenderToTexture !== false;
28167	    }
28168	    function updateVideoTexture(texture) {
28169	        const frame = info.render.frame;
28170	        // Check the last frame we updated the VideoTexture
28171	        if (_videoTextures.get(texture) !== frame) {
28172	            _videoTextures.set(texture, frame);
28173	            texture.update();
28174	        }
28175	    }
28176	    function verifyColorSpace(texture, image) {
28177	        const colorSpace = texture.colorSpace;
28178	        const format = texture.format;
28179	        const type = texture.type;
28180	        if (texture.isCompressedTexture === true || texture.isVideoTexture === true) return image;
28181	        if (colorSpace !== LinearSRGBColorSpace && colorSpace !== NoColorSpace) {
28182	            // sRGB
28183	            if (ColorManagement.getTransfer(colorSpace) === SRGBTransfer) {
28184	                // in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format
28185	                if (format !== RGBAFormat || type !== UnsignedByteType) {
28186	                    console.warn('THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.');
28187	                }
28188	            } else {
28189	                console.error('THREE.WebGLTextures: Unsupported texture color space:', colorSpace);
28190	            }
28191	        }
28192	        return image;
28193	    }
28194	    function getDimensions(image) {
28195	        if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement) {
28196	            // if intrinsic data are not available, fallback to width/height
vendor: 14,125 bytes, lines 28197-28466
28197	            _imageDimensions.width = image.naturalWidth || image.width;
28198	            _imageDimensions.height = image.naturalHeight || image.height;
28199	        } else if (typeof VideoFrame !== 'undefined' && image instanceof VideoFrame) {
28200	            _imageDimensions.width = image.displayWidth;
28201	            _imageDimensions.height = image.displayHeight;
28202	        } else {
28203	            _imageDimensions.width = image.width;
28204	            _imageDimensions.height = image.height;
28205	        }
28206	        return _imageDimensions;
28207	    }
28208	    //
28209	    this.allocateTextureUnit = allocateTextureUnit;
28210	    this.resetTextureUnits = resetTextureUnits;
28211	    this.setTexture2D = setTexture2D;
28212	    this.setTexture2DArray = setTexture2DArray;
28213	    this.setTexture3D = setTexture3D;
28214	    this.setTextureCube = setTextureCube;
28215	    this.rebindTextures = rebindTextures;
28216	    this.setupRenderTarget = setupRenderTarget;
28217	    this.updateRenderTargetMipmap = updateRenderTargetMipmap;
28218	    this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
28219	    this.setupDepthRenderbuffer = setupDepthRenderbuffer;
28220	    this.setupFrameBufferTexture = setupFrameBufferTexture;
28221	    this.useMultisampledRTT = useMultisampledRTT;
28222	}
28223	function WebGLUtils(gl, extensions) {
28224	    function convert(p, colorSpace = NoColorSpace) {
28225	        let extension;
28226	        const transfer = ColorManagement.getTransfer(colorSpace);
28227	        if (p === UnsignedByteType) return gl.UNSIGNED_BYTE;
28228	        if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4;
28229	        if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1;
28230	        if (p === UnsignedInt5999Type) return gl.UNSIGNED_INT_5_9_9_9_REV;
28231	        if (p === ByteType) return gl.BYTE;
28232	        if (p === ShortType) return gl.SHORT;
28233	        if (p === UnsignedShortType) return gl.UNSIGNED_SHORT;
28234	        if (p === IntType) return gl.INT;
28235	        if (p === UnsignedIntType) return gl.UNSIGNED_INT;
28236	        if (p === FloatType) return gl.FLOAT;
28237	        if (p === HalfFloatType) return gl.HALF_FLOAT;
28238	        if (p === AlphaFormat) return gl.ALPHA;
28239	        if (p === RGBFormat) return gl.RGB;
28240	        if (p === RGBAFormat) return gl.RGBA;
28241	        if (p === LuminanceFormat) return gl.LUMINANCE;
28242	        if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA;
28243	        if (p === DepthFormat) return gl.DEPTH_COMPONENT;
28244	        if (p === DepthStencilFormat) return gl.DEPTH_STENCIL;
28245	        // WebGL2 formats.
28246	        if (p === RedFormat) return gl.RED;
28247	        if (p === RedIntegerFormat) return gl.RED_INTEGER;
28248	        if (p === RGFormat) return gl.RG;
28249	        if (p === RGIntegerFormat) return gl.RG_INTEGER;
28250	        if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER;
28251	        // S3TC
28252	        if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {
28253	            if (transfer === SRGBTransfer) {
28254	                extension = extensions.get('WEBGL_compressed_texture_s3tc_srgb');
28255	                if (extension !== null) {
28256	                    if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;
28257	                    if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
28258	                    if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
28259	                    if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
28260	                } else {
28261	                    return null;
28262	                }
28263	            } else {
28264	                extension = extensions.get('WEBGL_compressed_texture_s3tc');
28265	                if (extension !== null) {
28266	                    if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
28267	                    if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
28268	                    if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
28269	                    if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
28270	                } else {
28271	                    return null;
28272	                }
28273	            }
28274	        }
28275	        // PVRTC
28276	        if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) {
28277	            extension = extensions.get('WEBGL_compressed_texture_pvrtc');
28278	            if (extension !== null) {
28279	                if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
28280	                if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
28281	                if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
28282	                if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
28283	            } else {
28284	                return null;
28285	            }
28286	        }
28287	        // ETC
28288	        if (p === RGB_ETC1_Format || p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) {
28289	            extension = extensions.get('WEBGL_compressed_texture_etc');
28290	            if (extension !== null) {
28291	                if (p === RGB_ETC1_Format || p === RGB_ETC2_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
28292	                if (p === RGBA_ETC2_EAC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;
28293	            } else {
28294	                return null;
28295	            }
28296	        }
28297	        // ASTC
28298	        if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format) {
28299	            extension = extensions.get('WEBGL_compressed_texture_astc');
28300	            if (extension !== null) {
28301	                if (p === RGBA_ASTC_4x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
28302	                if (p === RGBA_ASTC_5x4_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
28303	                if (p === RGBA_ASTC_5x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
28304	                if (p === RGBA_ASTC_6x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
28305	                if (p === RGBA_ASTC_6x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
28306	                if (p === RGBA_ASTC_8x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
28307	                if (p === RGBA_ASTC_8x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
28308	                if (p === RGBA_ASTC_8x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
28309	                if (p === RGBA_ASTC_10x5_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
28310	                if (p === RGBA_ASTC_10x6_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
28311	                if (p === RGBA_ASTC_10x8_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
28312	                if (p === RGBA_ASTC_10x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
28313	                if (p === RGBA_ASTC_12x10_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
28314	                if (p === RGBA_ASTC_12x12_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;
28315	            } else {
28316	                return null;
28317	            }
28318	        }
28319	        // BPTC
28320	        if (p === RGBA_BPTC_Format || p === RGB_BPTC_SIGNED_Format || p === RGB_BPTC_UNSIGNED_Format) {
28321	            extension = extensions.get('EXT_texture_compression_bptc');
28322	            if (extension !== null) {
28323	                if (p === RGBA_BPTC_Format) return transfer === SRGBTransfer ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
28324	                if (p === RGB_BPTC_SIGNED_Format) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
28325	                if (p === RGB_BPTC_UNSIGNED_Format) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
28326	            } else {
28327	                return null;
28328	            }
28329	        }
28330	        // RGTC
28331	        if (p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format) {
28332	            extension = extensions.get('EXT_texture_compression_rgtc');
28333	            if (extension !== null) {
28334	                if (p === RGBA_BPTC_Format) return extension.COMPRESSED_RED_RGTC1_EXT;
28335	                if (p === SIGNED_RED_RGTC1_Format) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT;
28336	                if (p === RED_GREEN_RGTC2_Format) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT;
28337	                if (p === SIGNED_RED_GREEN_RGTC2_Format) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
28338	            } else {
28339	                return null;
28340	            }
28341	        }
28342	        //
28343	        if (p === UnsignedInt248Type) return gl.UNSIGNED_INT_24_8;
28344	        // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)
28345	        return gl[p] !== undefined ? gl[p] : null;
28346	    }
28347	    return {
28348	        convert: convert
28349	    };
28350	}
28351	const _occlusion_vertex = `
28352void main() {
28353
28354	gl_Position = vec4( position, 1.0 );
28355
28356}`;
28357	const _occlusion_fragment = `
28358uniform sampler2DArray depthColor;
28359uniform float depthWidth;
28360uniform float depthHeight;
28361
28362void main() {
28363
28364	vec2 coord = vec2( gl_FragCoord.x / depthWidth, gl_FragCoord.y / depthHeight );
28365
28366	if ( coord.x >= 1.0 ) {
28367
28368		gl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;
28369
28370	} else {
28371
28372		gl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;
28373
28374	}
28375
28376}`;
28377	class WebXRDepthSensing {
28378	    init(renderer, depthData, renderState) {
28379	        if (this.texture === null) {
28380	            const texture = new Texture$1();
28381	            const texProps = renderer.properties.get(texture);
28382	            texProps.__webglTexture = depthData.texture;
28383	            if (depthData.depthNear !== renderState.depthNear || depthData.depthFar !== renderState.depthFar) {
28384	                this.depthNear = depthData.depthNear;
28385	                this.depthFar = depthData.depthFar;
28386	            }
28387	            this.texture = texture;
28388	        }
28389	    }
28390	    getMesh(cameraXR) {
28391	        if (this.texture !== null) {
28392	            if (this.mesh === null) {
28393	                const viewport = cameraXR.cameras[0].viewport;
28394	                const material = new ShaderMaterial({
28395	                    vertexShader: _occlusion_vertex,
28396	                    fragmentShader: _occlusion_fragment,
28397	                    uniforms: {
28398	                        depthColor: {
28399	                            value: this.texture
28400	                        },
28401	                        depthWidth: {
28402	                            value: viewport.z
28403	                        },
28404	                        depthHeight: {
28405	                            value: viewport.w
28406	                        }
28407	                    }
28408	                });
28409	                this.mesh = new Mesh(new PlaneGeometry(20, 20), material);
28410	            }
28411	        }
28412	        return this.mesh;
28413	    }
28414	    reset() {
28415	        this.texture = null;
28416	        this.mesh = null;
28417	    }
28418	    getDepthTexture() {
28419	        return this.texture;
28420	    }
28421	    constructor(){
28422	        this.texture = null;
28423	        this.mesh = null;
28424	        this.depthNear = 0;
28425	        this.depthFar = 0;
28426	    }
28427	}
28428	class WebXRManager extends EventDispatcher {
28429	    constructor(renderer, gl){
28430	        super();
28431	        const scope = this;
28432	        let session = null;
28433	        let framebufferScaleFactor = 1.0;
28434	        let referenceSpace = null;
28435	        let referenceSpaceType = 'local-floor';
28436	        // Set default foveation to maximum.
28437	        let foveation = 1.0;
28438	        let customReferenceSpace = null;
28439	        let pose = null;
28440	        let glBinding = null;
28441	        let glProjLayer = null;
28442	        let glBaseLayer = null;
28443	        let xrFrame = null;
28444	        const depthSensing = new WebXRDepthSensing();
28445	        const attributes = gl.getContextAttributes();
28446	        let initialRenderTarget = null;
28447	        let newRenderTarget = null;
28448	        const controllers = [];
28449	        const controllerInputSources = [];
28450	        const currentSize = new Vector2();
28451	        let currentPixelRatio = null;
28452	        //
28453	        const cameraL = new PerspectiveCamera();
28454	        cameraL.viewport = new Vector4();
28455	        const cameraR = new PerspectiveCamera();
28456	        cameraR.viewport = new Vector4();
28457	        const cameras = [
28458	            cameraL,
28459	            cameraR
28460	        ];
28461	        const cameraXR = new ArrayCamera();
28462	        let _currentDepthNear = null;
28463	        let _currentDepthFar = null;
28464	        //
28465	        this.cameraAutoUpdate = true;
28466	        this.enabled = false;
vendor: 4,305 bytes, lines 28467-28567
28467	        this.isPresenting = false;
28468	        this.getController = function(index) {
28469	            let controller = controllers[index];
28470	            if (controller === undefined) {
28471	                controller = new WebXRController();
28472	                controllers[index] = controller;
28473	            }
28474	            return controller.getTargetRaySpace();
28475	        };
28476	        this.getControllerGrip = function(index) {
28477	            let controller = controllers[index];
28478	            if (controller === undefined) {
28479	                controller = new WebXRController();
28480	                controllers[index] = controller;
28481	            }
28482	            return controller.getGripSpace();
28483	        };
28484	        this.getHand = function(index) {
28485	            let controller = controllers[index];
28486	            if (controller === undefined) {
28487	                controller = new WebXRController();
28488	                controllers[index] = controller;
28489	            }
28490	            return controller.getHandSpace();
28491	        };
28492	        //
28493	        function onSessionEvent(event) {
28494	            const controllerIndex = controllerInputSources.indexOf(event.inputSource);
28495	            if (controllerIndex === -1) {
28496	                return;
28497	            }
28498	            const controller = controllers[controllerIndex];
28499	            if (controller !== undefined) {
28500	                controller.update(event.inputSource, event.frame, customReferenceSpace || referenceSpace);
28501	                controller.dispatchEvent({
28502	                    type: event.type,
28503	                    data: event.inputSource
28504	                });
28505	            }
28506	        }
28507	        function onSessionEnd() {
28508	            session.removeEventListener('select', onSessionEvent);
28509	            session.removeEventListener('selectstart', onSessionEvent);
28510	            session.removeEventListener('selectend', onSessionEvent);
28511	            session.removeEventListener('squeeze', onSessionEvent);
28512	            session.removeEventListener('squeezestart', onSessionEvent);
28513	            session.removeEventListener('squeezeend', onSessionEvent);
28514	            session.removeEventListener('end', onSessionEnd);
28515	            session.removeEventListener('inputsourceschange', onInputSourcesChange);
28516	            for(let i = 0; i < controllers.length; i++){
28517	                const inputSource = controllerInputSources[i];
28518	                if (inputSource === null) continue;
28519	                controllerInputSources[i] = null;
28520	                controllers[i].disconnect(inputSource);
28521	            }
28522	            _currentDepthNear = null;
28523	            _currentDepthFar = null;
28524	            depthSensing.reset();
28525	            // restore framebuffer/rendering state
28526	            renderer.setRenderTarget(initialRenderTarget);
28527	            glBaseLayer = null;
28528	            glProjLayer = null;
28529	            glBinding = null;
28530	            session = null;
28531	            newRenderTarget = null;
28532	            //
28533	            animation.stop();
28534	            scope.isPresenting = false;
28535	            renderer.setPixelRatio(currentPixelRatio);
28536	            renderer.setSize(currentSize.width, currentSize.height, false);
28537	            scope.dispatchEvent({
28538	                type: 'sessionend'
28539	            });
28540	        }
28541	        this.setFramebufferScaleFactor = function(value) {
28542	            framebufferScaleFactor = value;
28543	            if (scope.isPresenting === true) {
28544	                console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.');
28545	            }
28546	        };
28547	        this.setReferenceSpaceType = function(value) {
28548	            referenceSpaceType = value;
28549	            if (scope.isPresenting === true) {
28550	                console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.');
28551	            }
28552	        };
28553	        this.getReferenceSpace = function() {
28554	            return customReferenceSpace || referenceSpace;
28555	        };
28556	        this.setReferenceSpace = function(space) {
28557	            customReferenceSpace = space;
28558	        };
28559	        this.getBaseLayer = function() {
28560	            return glProjLayer !== null ? glProjLayer : glBaseLayer;
28561	        };
28562	        this.getBinding = function() {
28563	            return glBinding;
28564	        };
28565	        this.getFrame = function() {
28566	            return xrFrame;
28567	        };
vendor: 14,856 bytes, lines 28568-28849
28568	        this.getSession = function() {
28569	            return session;
28570	        };
28571	        this.setSession = async function(value) {
28572	            session = value;
28573	            if (session !== null) {
28574	                initialRenderTarget = renderer.getRenderTarget();
28575	                session.addEventListener('select', onSessionEvent);
28576	                session.addEventListener('selectstart', onSessionEvent);
28577	                session.addEventListener('selectend', onSessionEvent);
28578	                session.addEventListener('squeeze', onSessionEvent);
28579	                session.addEventListener('squeezestart', onSessionEvent);
28580	                session.addEventListener('squeezeend', onSessionEvent);
28581	                session.addEventListener('end', onSessionEnd);
28582	                session.addEventListener('inputsourceschange', onInputSourcesChange);
28583	                if (attributes.xrCompatible !== true) {
28584	                    await gl.makeXRCompatible();
28585	                }
28586	                currentPixelRatio = renderer.getPixelRatio();
28587	                renderer.getSize(currentSize);
28588	                // Check that the browser implements the necessary APIs to use an
28589	                // XRProjectionLayer rather than an XRWebGLLayer
28590	                const useLayers = typeof XRWebGLBinding !== 'undefined' && 'createProjectionLayer' in XRWebGLBinding.prototype;
28591	                if (!useLayers) {
28592	                    const layerInit = {
28593	                        antialias: attributes.antialias,
28594	                        alpha: true,
28595	                        depth: attributes.depth,
28596	                        stencil: attributes.stencil,
28597	                        framebufferScaleFactor: framebufferScaleFactor
28598	                    };
28599	                    glBaseLayer = new XRWebGLLayer(session, gl, layerInit);
28600	                    session.updateRenderState({
28601	                        baseLayer: glBaseLayer
28602	                    });
28603	                    renderer.setPixelRatio(1);
28604	                    renderer.setSize(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, false);
28605	                    newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, {
28606	                        format: RGBAFormat,
28607	                        type: UnsignedByteType,
28608	                        colorSpace: renderer.outputColorSpace,
28609	                        stencilBuffer: attributes.stencil,
28610	                        resolveDepthBuffer: glBaseLayer.ignoreDepthValues === false,
28611	                        resolveStencilBuffer: glBaseLayer.ignoreDepthValues === false
28612	                    });
28613	                } else {
28614	                    let depthFormat = null;
28615	                    let depthType = null;
28616	                    let glDepthFormat = null;
28617	                    if (attributes.depth) {
28618	                        glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;
28619	                        depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat;
28620	                        depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType;
28621	                    }
28622	                    const projectionlayerInit = {
28623	                        colorFormat: gl.RGBA8,
28624	                        depthFormat: glDepthFormat,
28625	                        scaleFactor: framebufferScaleFactor
28626	                    };
28627	                    glBinding = new XRWebGLBinding(session, gl);
28628	                    glProjLayer = glBinding.createProjectionLayer(projectionlayerInit);
28629	                    session.updateRenderState({
28630	                        layers: [
28631	                            glProjLayer
28632	                        ]
28633	                    });
28634	                    renderer.setPixelRatio(1);
28635	                    renderer.setSize(glProjLayer.textureWidth, glProjLayer.textureHeight, false);
28636	                    newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, {
28637	                        format: RGBAFormat,
28638	                        type: UnsignedByteType,
28639	                        depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat),
28640	                        stencilBuffer: attributes.stencil,
28641	                        colorSpace: renderer.outputColorSpace,
28642	                        samples: attributes.antialias ? 4 : 0,
28643	                        resolveDepthBuffer: glProjLayer.ignoreDepthValues === false,
28644	                        resolveStencilBuffer: glProjLayer.ignoreDepthValues === false
28645	                    });
28646	                }
28647	                newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278
28648	                this.setFoveation(foveation);
28649	                customReferenceSpace = null;
28650	                referenceSpace = await session.requestReferenceSpace(referenceSpaceType);
28651	                animation.setContext(session);
28652	                animation.start();
28653	                scope.isPresenting = true;
28654	                scope.dispatchEvent({
28655	                    type: 'sessionstart'
28656	                });
28657	            }
28658	        };
28659	        this.getEnvironmentBlendMode = function() {
28660	            if (session !== null) {
28661	                return session.environmentBlendMode;
28662	            }
28663	        };
28664	        this.getDepthTexture = function() {
28665	            return depthSensing.getDepthTexture();
28666	        };
28667	        function onInputSourcesChange(event) {
28668	            // Notify disconnected
28669	            for(let i = 0; i < event.removed.length; i++){
28670	                const inputSource = event.removed[i];
28671	                const index = controllerInputSources.indexOf(inputSource);
28672	                if (index >= 0) {
28673	                    controllerInputSources[index] = null;
28674	                    controllers[index].disconnect(inputSource);
28675	                }
28676	            }
28677	            // Notify connected
28678	            for(let i = 0; i < event.added.length; i++){
28679	                const inputSource = event.added[i];
28680	                let controllerIndex = controllerInputSources.indexOf(inputSource);
28681	                if (controllerIndex === -1) {
28682	                    // Assign input source a controller that currently has no input source
28683	                    for(let i = 0; i < controllers.length; i++){
28684	                        if (i >= controllerInputSources.length) {
28685	                            controllerInputSources.push(inputSource);
28686	                            controllerIndex = i;
28687	                            break;
28688	                        } else if (controllerInputSources[i] === null) {
28689	                            controllerInputSources[i] = inputSource;
28690	                            controllerIndex = i;
28691	                            break;
28692	                        }
28693	                    }
28694	                    // If all controllers do currently receive input we ignore new ones
28695	                    if (controllerIndex === -1) break;
28696	                }
28697	                const controller = controllers[controllerIndex];
28698	                if (controller) {
28699	                    controller.connect(inputSource);
28700	                }
28701	            }
28702	        }
28703	        //
28704	        const cameraLPos = new Vector3();
28705	        const cameraRPos = new Vector3();
28706	        /**
28707			 * Assumes 2 cameras that are parallel and share an X-axis, and that
28708			 * the cameras' projection and world matrices have already been set.
28709			 * And that near and far planes are identical for both cameras.
28710			 * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
28711			 *
28712			 * @param {ArrayCamera} camera - The camera to update.
28713			 * @param {PerspectiveCamera} cameraL - The left camera.
28714			 * @param {PerspectiveCamera} cameraR - The right camera.
28715			 */ function setProjectionFromUnion(camera, cameraL, cameraR) {
28716	            cameraLPos.setFromMatrixPosition(cameraL.matrixWorld);
28717	            cameraRPos.setFromMatrixPosition(cameraR.matrixWorld);
28718	            const ipd = cameraLPos.distanceTo(cameraRPos);
28719	            const projL = cameraL.projectionMatrix.elements;
28720	            const projR = cameraR.projectionMatrix.elements;
28721	            // VR systems will have identical far and near planes, and
28722	            // most likely identical top and bottom frustum extents.
28723	            // Use the left camera for these values.
28724	            const near = projL[14] / (projL[10] - 1);
28725	            const far = projL[14] / (projL[10] + 1);
28726	            const topFov = (projL[9] + 1) / projL[5];
28727	            const bottomFov = (projL[9] - 1) / projL[5];
28728	            const leftFov = (projL[8] - 1) / projL[0];
28729	            const rightFov = (projR[8] + 1) / projR[0];
28730	            const left = near * leftFov;
28731	            const right = near * rightFov;
28732	            // Calculate the new camera's position offset from the
28733	            // left camera. xOffset should be roughly half `ipd`.
28734	            const zOffset = ipd / (-leftFov + rightFov);
28735	            const xOffset = zOffset * -leftFov;
28736	            // TODO: Better way to apply this offset?
28737	            cameraL.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale);
28738	            camera.translateX(xOffset);
28739	            camera.translateZ(zOffset);
28740	            camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale);
28741	            camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
28742	            // Check if the projection uses an infinite far plane.
28743	            if (projL[10] === -1) {
28744	                // Use the projection matrix from the left eye.
28745	                // The camera offset is sufficient to include the view volumes
28746	                // of both eyes (assuming symmetric projections).
28747	                camera.projectionMatrix.copy(cameraL.projectionMatrix);
28748	                camera.projectionMatrixInverse.copy(cameraL.projectionMatrixInverse);
28749	            } else {
28750	                // Find the union of the frustum values of the cameras and scale
28751	                // the values so that the near plane's position does not change in world space,
28752	                // although must now be relative to the new union camera.
28753	                const near2 = near + zOffset;
28754	                const far2 = far + zOffset;
28755	                const left2 = left - xOffset;
28756	                const right2 = right + (ipd - xOffset);
28757	                const top2 = topFov * far / far2 * near2;
28758	                const bottom2 = bottomFov * far / far2 * near2;
28759	                camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2);
28760	                camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
28761	            }
28762	        }
28763	        function updateCamera(camera, parent) {
28764	            if (parent === null) {
28765	                camera.matrixWorld.copy(camera.matrix);
28766	            } else {
28767	                camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix);
28768	            }
28769	            camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
28770	        }
28771	        this.updateCamera = function(camera) {
28772	            if (session === null) return;
28773	            let depthNear = camera.near;
28774	            let depthFar = camera.far;
28775	            if (depthSensing.texture !== null) {
28776	                if (depthSensing.depthNear > 0) depthNear = depthSensing.depthNear;
28777	                if (depthSensing.depthFar > 0) depthFar = depthSensing.depthFar;
28778	            }
28779	            cameraXR.near = cameraR.near = cameraL.near = depthNear;
28780	            cameraXR.far = cameraR.far = cameraL.far = depthFar;
28781	            if (_currentDepthNear !== cameraXR.near || _currentDepthFar !== cameraXR.far) {
28782	                // Note that the new renderState won't apply until the next frame. See #18320
28783	                session.updateRenderState({
28784	                    depthNear: cameraXR.near,
28785	                    depthFar: cameraXR.far
28786	                });
28787	                _currentDepthNear = cameraXR.near;
28788	                _currentDepthFar = cameraXR.far;
28789	            }
28790	            cameraL.layers.mask = camera.layers.mask | 0b010;
28791	            cameraR.layers.mask = camera.layers.mask | 0b100;
28792	            cameraXR.layers.mask = cameraL.layers.mask | cameraR.layers.mask;
28793	            const parent = camera.parent;
28794	            const cameras = cameraXR.cameras;
28795	            updateCamera(cameraXR, parent);
28796	            for(let i = 0; i < cameras.length; i++){
28797	                updateCamera(cameras[i], parent);
28798	            }
28799	            // update projection matrix for proper view frustum culling
28800	            if (cameras.length === 2) {
28801	                setProjectionFromUnion(cameraXR, cameraL, cameraR);
28802	            } else {
28803	                // assume single camera setup (AR)
28804	                cameraXR.projectionMatrix.copy(cameraL.projectionMatrix);
28805	            }
28806	            // update user camera and its children
28807	            updateUserCamera(camera, cameraXR, parent);
28808	        };
28809	        function updateUserCamera(camera, cameraXR, parent) {
28810	            if (parent === null) {
28811	                camera.matrix.copy(cameraXR.matrixWorld);
28812	            } else {
28813	                camera.matrix.copy(parent.matrixWorld);
28814	                camera.matrix.invert();
28815	                camera.matrix.multiply(cameraXR.matrixWorld);
28816	            }
28817	            camera.matrix.decompose(camera.position, camera.quaternion, camera.scale);
28818	            camera.updateMatrixWorld(true);
28819	            camera.projectionMatrix.copy(cameraXR.projectionMatrix);
28820	            camera.projectionMatrixInverse.copy(cameraXR.projectionMatrixInverse);
28821	            if (camera.isPerspectiveCamera) {
28822	                camera.fov = RAD2DEG * 2 * Math.atan(1 / camera.projectionMatrix.elements[5]);
28823	                camera.zoom = 1;
28824	            }
28825	        }
28826	        this.getCamera = function() {
28827	            return cameraXR;
28828	        };
28829	        this.getFoveation = function() {
28830	            if (glProjLayer === null && glBaseLayer === null) {
28831	                return undefined;
28832	            }
28833	            return foveation;
28834	        };
28835	        this.setFoveation = function(value) {
28836	            // 0 = no foveation = full resolution
28837	            // 1 = maximum foveation = the edges render at lower resolution
28838	            foveation = value;
28839	            if (glProjLayer !== null) {
28840	                glProjLayer.fixedFoveation = value;
28841	            }
28842	            if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) {
28843	                glBaseLayer.fixedFoveation = value;
28844	            }
28845	        };
28846	        this.hasDepthSensing = function() {
28847	            return depthSensing.texture !== null;
28848	        };
28849	        this.getDepthSensingMesh = function() {
vendor: 6,195 bytes, lines 28850-28973
28850	            return depthSensing.getMesh(cameraXR);
28851	        };
28852	        // Animation Loop
28853	        let onAnimationFrameCallback = null;
28854	        function onAnimationFrame(time, frame) {
28855	            pose = frame.getViewerPose(customReferenceSpace || referenceSpace);
28856	            xrFrame = frame;
28857	            if (pose !== null) {
28858	                const views = pose.views;
28859	                if (glBaseLayer !== null) {
28860	                    renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer);
28861	                    renderer.setRenderTarget(newRenderTarget);
28862	                }
28863	                let cameraXRNeedsUpdate = false;
28864	                // check if it's necessary to rebuild cameraXR's camera list
28865	                if (views.length !== cameraXR.cameras.length) {
28866	                    cameraXR.cameras.length = 0;
28867	                    cameraXRNeedsUpdate = true;
28868	                }
28869	                for(let i = 0; i < views.length; i++){
28870	                    const view = views[i];
28871	                    let viewport = null;
28872	                    if (glBaseLayer !== null) {
28873	                        viewport = glBaseLayer.getViewport(view);
28874	                    } else {
28875	                        const glSubImage = glBinding.getViewSubImage(glProjLayer, view);
28876	                        viewport = glSubImage.viewport;
28877	                        // For side-by-side projection, we only produce a single texture for both eyes.
28878	                        if (i === 0) {
28879	                            renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture);
28880	                            renderer.setRenderTarget(newRenderTarget);
28881	                        }
28882	                    }
28883	                    let camera = cameras[i];
28884	                    if (camera === undefined) {
28885	                        camera = new PerspectiveCamera();
28886	                        camera.layers.enable(i);
28887	                        camera.viewport = new Vector4();
28888	                        cameras[i] = camera;
28889	                    }
28890	                    camera.matrix.fromArray(view.transform.matrix);
28891	                    camera.matrix.decompose(camera.position, camera.quaternion, camera.scale);
28892	                    camera.projectionMatrix.fromArray(view.projectionMatrix);
28893	                    camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
28894	                    camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height);
28895	                    if (i === 0) {
28896	                        cameraXR.matrix.copy(camera.matrix);
28897	                        cameraXR.matrix.decompose(cameraXR.position, cameraXR.quaternion, cameraXR.scale);
28898	                    }
28899	                    if (cameraXRNeedsUpdate === true) {
28900	                        cameraXR.cameras.push(camera);
28901	                    }
28902	                }
28903	                //
28904	                const enabledFeatures = session.enabledFeatures;
28905	                const gpuDepthSensingEnabled = enabledFeatures && enabledFeatures.includes('depth-sensing') && session.depthUsage == 'gpu-optimized';
28906	                if (gpuDepthSensingEnabled && glBinding) {
28907	                    const depthData = glBinding.getDepthInformation(views[0]);
28908	                    if (depthData && depthData.isValid && depthData.texture) {
28909	                        depthSensing.init(renderer, depthData, session.renderState);
28910	                    }
28911	                }
28912	            }
28913	            //
28914	            for(let i = 0; i < controllers.length; i++){
28915	                const inputSource = controllerInputSources[i];
28916	                const controller = controllers[i];
28917	                if (inputSource !== null && controller !== undefined) {
28918	                    controller.update(inputSource, frame, customReferenceSpace || referenceSpace);
28919	                }
28920	            }
28921	            if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame);
28922	            if (frame.detectedPlanes) {
28923	                scope.dispatchEvent({
28924	                    type: 'planesdetected',
28925	                    data: frame
28926	                });
28927	            }
28928	            xrFrame = null;
28929	        }
28930	        const animation = new WebGLAnimation();
28931	        animation.setAnimationLoop(onAnimationFrame);
28932	        this.setAnimationLoop = function(callback) {
28933	            onAnimationFrameCallback = callback;
28934	        };
28935	        this.dispose = function() {};
28936	    }
28937	}
28938	const _e1 = /*@__PURE__*/ new Euler();
28939	const _m1 = /*@__PURE__*/ new Matrix4();
28940	function WebGLMaterials(renderer, properties) {
28941	    function refreshTransformUniform(map, uniform) {
28942	        if (map.matrixAutoUpdate === true) {
28943	            map.updateMatrix();
28944	        }
28945	        uniform.value.copy(map.matrix);
28946	    }
28947	    function refreshFogUniforms(uniforms, fog) {
28948	        fog.color.getRGB(uniforms.fogColor.value, getUnlitUniformColorSpace(renderer));
28949	        if (fog.isFog) {
28950	            uniforms.fogNear.value = fog.near;
28951	            uniforms.fogFar.value = fog.far;
28952	        } else if (fog.isFogExp2) {
28953	            uniforms.fogDensity.value = fog.density;
28954	        }
28955	    }
28956	    function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) {
28957	        if (material.isMeshBasicMaterial) {
28958	            refreshUniformsCommon(uniforms, material);
28959	        } else if (material.isMeshLambertMaterial) {
28960	            refreshUniformsCommon(uniforms, material);
28961	        } else if (material.isMeshToonMaterial) {
28962	            refreshUniformsCommon(uniforms, material);
28963	            refreshUniformsToon(uniforms, material);
28964	        } else if (material.isMeshPhongMaterial) {
28965	            refreshUniformsCommon(uniforms, material);
28966	            refreshUniformsPhong(uniforms, material);
28967	        } else if (material.isMeshStandardMaterial) {
28968	            refreshUniformsCommon(uniforms, material);
28969	            refreshUniformsStandard(uniforms, material);
28970	            if (material.isMeshPhysicalMaterial) {
28971	                refreshUniformsPhysical(uniforms, material, transmissionRenderTarget);
28972	            }
28973	        }
vendor: 34,388 bytes, lines 28973-29695
28973 else if (material.isMeshMatcapMaterial) {
28974	            refreshUniformsCommon(uniforms, material);
28975	            refreshUniformsMatcap(uniforms, material);
28976	        } else if (material.isMeshDepthMaterial) {
28977	            refreshUniformsCommon(uniforms, material);
28978	        } else if (material.isMeshDistanceMaterial) {
28979	            refreshUniformsCommon(uniforms, material);
28980	            refreshUniformsDistance(uniforms, material);
28981	        } else if (material.isMeshNormalMaterial) {
28982	            refreshUniformsCommon(uniforms, material);
28983	        } else if (material.isLineBasicMaterial) {
28984	            refreshUniformsLine(uniforms, material);
28985	            if (material.isLineDashedMaterial) {
28986	                refreshUniformsDash(uniforms, material);
28987	            }
28988	        } else if (material.isPointsMaterial) {
28989	            refreshUniformsPoints(uniforms, material, pixelRatio, height);
28990	        } else if (material.isSpriteMaterial) {
28991	            refreshUniformsSprites(uniforms, material);
28992	        } else if (material.isShadowMaterial) {
28993	            uniforms.color.value.copy(material.color);
28994	            uniforms.opacity.value = material.opacity;
28995	        } else if (material.isShaderMaterial) {
28996	            material.uniformsNeedUpdate = false; // #15581
28997	        }
28998	    }
28999	    function refreshUniformsCommon(uniforms, material) {
29000	        uniforms.opacity.value = material.opacity;
29001	        if (material.color) {
29002	            uniforms.diffuse.value.copy(material.color);
29003	        }
29004	        if (material.emissive) {
29005	            uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity);
29006	        }
29007	        if (material.map) {
29008	            uniforms.map.value = material.map;
29009	            refreshTransformUniform(material.map, uniforms.mapTransform);
29010	        }
29011	        if (material.alphaMap) {
29012	            uniforms.alphaMap.value = material.alphaMap;
29013	            refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform);
29014	        }
29015	        if (material.bumpMap) {
29016	            uniforms.bumpMap.value = material.bumpMap;
29017	            refreshTransformUniform(material.bumpMap, uniforms.bumpMapTransform);
29018	            uniforms.bumpScale.value = material.bumpScale;
29019	            if (material.side === BackSide) {
29020	                uniforms.bumpScale.value *= -1;
29021	            }
29022	        }
29023	        if (material.normalMap) {
29024	            uniforms.normalMap.value = material.normalMap;
29025	            refreshTransformUniform(material.normalMap, uniforms.normalMapTransform);
29026	            uniforms.normalScale.value.copy(material.normalScale);
29027	            if (material.side === BackSide) {
29028	                uniforms.normalScale.value.negate();
29029	            }
29030	        }
29031	        if (material.displacementMap) {
29032	            uniforms.displacementMap.value = material.displacementMap;
29033	            refreshTransformUniform(material.displacementMap, uniforms.displacementMapTransform);
29034	            uniforms.displacementScale.value = material.displacementScale;
29035	            uniforms.displacementBias.value = material.displacementBias;
29036	        }
29037	        if (material.emissiveMap) {
29038	            uniforms.emissiveMap.value = material.emissiveMap;
29039	            refreshTransformUniform(material.emissiveMap, uniforms.emissiveMapTransform);
29040	        }
29041	        if (material.specularMap) {
29042	            uniforms.specularMap.value = material.specularMap;
29043	            refreshTransformUniform(material.specularMap, uniforms.specularMapTransform);
29044	        }
29045	        if (material.alphaTest > 0) {
29046	            uniforms.alphaTest.value = material.alphaTest;
29047	        }
29048	        const materialProperties = properties.get(material);
29049	        const envMap = materialProperties.envMap;
29050	        const envMapRotation = materialProperties.envMapRotation;
29051	        if (envMap) {
29052	            uniforms.envMap.value = envMap;
29053	            _e1.copy(envMapRotation);
29054	            // accommodate left-handed frame
29055	            _e1.x *= -1;
29056	            _e1.y *= -1;
29057	            _e1.z *= -1;
29058	            if (envMap.isCubeTexture && envMap.isRenderTargetTexture === false) {
29059	                // environment maps which are not cube render targets or PMREMs follow a different convention
29060	                _e1.y *= -1;
29061	                _e1.z *= -1;
29062	            }
29063	            uniforms.envMapRotation.value.setFromMatrix4(_m1.makeRotationFromEuler(_e1));
29064	            uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
29065	            uniforms.reflectivity.value = material.reflectivity;
29066	            uniforms.ior.value = material.ior;
29067	            uniforms.refractionRatio.value = material.refractionRatio;
29068	        }
29069	        if (material.lightMap) {
29070	            uniforms.lightMap.value = material.lightMap;
29071	            uniforms.lightMapIntensity.value = material.lightMapIntensity;
29072	            refreshTransformUniform(material.lightMap, uniforms.lightMapTransform);
29073	        }
29074	        if (material.aoMap) {
29075	            uniforms.aoMap.value = material.aoMap;
29076	            uniforms.aoMapIntensity.value = material.aoMapIntensity;
29077	            refreshTransformUniform(material.aoMap, uniforms.aoMapTransform);
29078	        }
29079	    }
29080	    function refreshUniformsLine(uniforms, material) {
29081	        uniforms.diffuse.value.copy(material.color);
29082	        uniforms.opacity.value = material.opacity;
29083	        if (material.map) {
29084	            uniforms.map.value = material.map;
29085	            refreshTransformUniform(material.map, uniforms.mapTransform);
29086	        }
29087	    }
29088	    function refreshUniformsDash(uniforms, material) {
29089	        uniforms.dashSize.value = material.dashSize;
29090	        uniforms.totalSize.value = material.dashSize + material.gapSize;
29091	        uniforms.scale.value = material.scale;
29092	    }
29093	    function refreshUniformsPoints(uniforms, material, pixelRatio, height) {
29094	        uniforms.diffuse.value.copy(material.color);
29095	        uniforms.opacity.value = material.opacity;
29096	        uniforms.size.value = material.size * pixelRatio;
29097	        uniforms.scale.value = height * 0.5;
29098	        if (material.map) {
29099	            uniforms.map.value = material.map;
29100	            refreshTransformUniform(material.map, uniforms.uvTransform);
29101	        }
29102	        if (material.alphaMap) {
29103	            uniforms.alphaMap.value = material.alphaMap;
29104	            refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform);
29105	        }
29106	        if (material.alphaTest > 0) {
29107	            uniforms.alphaTest.value = material.alphaTest;
29108	        }
29109	    }
29110	    function refreshUniformsSprites(uniforms, material) {
29111	        uniforms.diffuse.value.copy(material.color);
29112	        uniforms.opacity.value = material.opacity;
29113	        uniforms.rotation.value = material.rotation;
29114	        if (material.map) {
29115	            uniforms.map.value = material.map;
29116	            refreshTransformUniform(material.map, uniforms.mapTransform);
29117	        }
29118	        if (material.alphaMap) {
29119	            uniforms.alphaMap.value = material.alphaMap;
29120	            refreshTransformUniform(material.alphaMap, uniforms.alphaMapTransform);
29121	        }
29122	        if (material.alphaTest > 0) {
29123	            uniforms.alphaTest.value = material.alphaTest;
29124	        }
29125	    }
29126	    function refreshUniformsPhong(uniforms, material) {
29127	        uniforms.specular.value.copy(material.specular);
29128	        uniforms.shininess.value = Math.max(material.shininess, 1e-4); // to prevent pow( 0.0, 0.0 )
29129	    }
29130	    function refreshUniformsToon(uniforms, material) {
29131	        if (material.gradientMap) {
29132	            uniforms.gradientMap.value = material.gradientMap;
29133	        }
29134	    }
29135	    function refreshUniformsStandard(uniforms, material) {
29136	        uniforms.metalness.value = material.metalness;
29137	        if (material.metalnessMap) {
29138	            uniforms.metalnessMap.value = material.metalnessMap;
29139	            refreshTransformUniform(material.metalnessMap, uniforms.metalnessMapTransform);
29140	        }
29141	        uniforms.roughness.value = material.roughness;
29142	        if (material.roughnessMap) {
29143	            uniforms.roughnessMap.value = material.roughnessMap;
29144	            refreshTransformUniform(material.roughnessMap, uniforms.roughnessMapTransform);
29145	        }
29146	        if (material.envMap) {
29147	            //uniforms.envMap.value = material.envMap; // part of uniforms common
29148	            uniforms.envMapIntensity.value = material.envMapIntensity;
29149	        }
29150	    }
29151	    function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) {
29152	        uniforms.ior.value = material.ior; // also part of uniforms common
29153	        if (material.sheen > 0) {
29154	            uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen);
29155	            uniforms.sheenRoughness.value = material.sheenRoughness;
29156	            if (material.sheenColorMap) {
29157	                uniforms.sheenColorMap.value = material.sheenColorMap;
29158	                refreshTransformUniform(material.sheenColorMap, uniforms.sheenColorMapTransform);
29159	            }
29160	            if (material.sheenRoughnessMap) {
29161	                uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap;
29162	                refreshTransformUniform(material.sheenRoughnessMap, uniforms.sheenRoughnessMapTransform);
29163	            }
29164	        }
29165	        if (material.clearcoat > 0) {
29166	            uniforms.clearcoat.value = material.clearcoat;
29167	            uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
29168	            if (material.clearcoatMap) {
29169	                uniforms.clearcoatMap.value = material.clearcoatMap;
29170	                refreshTransformUniform(material.clearcoatMap, uniforms.clearcoatMapTransform);
29171	            }
29172	            if (material.clearcoatRoughnessMap) {
29173	                uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
29174	                refreshTransformUniform(material.clearcoatRoughnessMap, uniforms.clearcoatRoughnessMapTransform);
29175	            }
29176	            if (material.clearcoatNormalMap) {
29177	                uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
29178	                refreshTransformUniform(material.clearcoatNormalMap, uniforms.clearcoatNormalMapTransform);
29179	                uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale);
29180	                if (material.side === BackSide) {
29181	                    uniforms.clearcoatNormalScale.value.negate();
29182	                }
29183	            }
29184	        }
29185	        if (material.dispersion > 0) {
29186	            uniforms.dispersion.value = material.dispersion;
29187	        }
29188	        if (material.iridescence > 0) {
29189	            uniforms.iridescence.value = material.iridescence;
29190	            uniforms.iridescenceIOR.value = material.iridescenceIOR;
29191	            uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0];
29192	            uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1];
29193	            if (material.iridescenceMap) {
29194	                uniforms.iridescenceMap.value = material.iridescenceMap;
29195	                refreshTransformUniform(material.iridescenceMap, uniforms.iridescenceMapTransform);
29196	            }
29197	            if (material.iridescenceThicknessMap) {
29198	                uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap;
29199	                refreshTransformUniform(material.iridescenceThicknessMap, uniforms.iridescenceThicknessMapTransform);
29200	            }
29201	        }
29202	        if (material.transmission > 0) {
29203	            uniforms.transmission.value = material.transmission;
29204	            uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;
29205	            uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height);
29206	            if (material.transmissionMap) {
29207	                uniforms.transmissionMap.value = material.transmissionMap;
29208	                refreshTransformUniform(material.transmissionMap, uniforms.transmissionMapTransform);
29209	            }
29210	            uniforms.thickness.value = material.thickness;
29211	            if (material.thicknessMap) {
29212	                uniforms.thicknessMap.value = material.thicknessMap;
29213	                refreshTransformUniform(material.thicknessMap, uniforms.thicknessMapTransform);
29214	            }
29215	            uniforms.attenuationDistance.value = material.attenuationDistance;
29216	            uniforms.attenuationColor.value.copy(material.attenuationColor);
29217	        }
29218	        if (material.anisotropy > 0) {
29219	            uniforms.anisotropyVector.value.set(material.anisotropy * Math.cos(material.anisotropyRotation), material.anisotropy * Math.sin(material.anisotropyRotation));
29220	            if (material.anisotropyMap) {
29221	                uniforms.anisotropyMap.value = material.anisotropyMap;
29222	                refreshTransformUniform(material.anisotropyMap, uniforms.anisotropyMapTransform);
29223	            }
29224	        }
29225	        uniforms.specularIntensity.value = material.specularIntensity;
29226	        uniforms.specularColor.value.copy(material.specularColor);
29227	        if (material.specularColorMap) {
29228	            uniforms.specularColorMap.value = material.specularColorMap;
29229	            refreshTransformUniform(material.specularColorMap, uniforms.specularColorMapTransform);
29230	        }
29231	        if (material.specularIntensityMap) {
29232	            uniforms.specularIntensityMap.value = material.specularIntensityMap;
29233	            refreshTransformUniform(material.specularIntensityMap, uniforms.specularIntensityMapTransform);
29234	        }
29235	    }
29236	    function refreshUniformsMatcap(uniforms, material) {
29237	        if (material.matcap) {
29238	            uniforms.matcap.value = material.matcap;
29239	        }
29240	    }
29241	    function refreshUniformsDistance(uniforms, material) {
29242	        const light = properties.get(material).light;
29243	        uniforms.referencePosition.value.setFromMatrixPosition(light.matrixWorld);
29244	        uniforms.nearDistance.value = light.shadow.camera.near;
29245	        uniforms.farDistance.value = light.shadow.camera.far;
29246	    }
29247	    return {
29248	        refreshFogUniforms: refreshFogUniforms,
29249	        refreshMaterialUniforms: refreshMaterialUniforms
29250	    };
29251	}
29252	function WebGLUniformsGroups(gl, info, capabilities, state) {
29253	    let buffers = {};
29254	    let updateList = {};
29255	    let allocatedBindingPoints = [];
29256	    const maxBindingPoints = gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS); // binding points are global whereas block indices are per shader program
29257	    function bind(uniformsGroup, program) {
29258	        const webglProgram = program.program;
29259	        state.uniformBlockBinding(uniformsGroup, webglProgram);
29260	    }
29261	    function update(uniformsGroup, program) {
29262	        let buffer = buffers[uniformsGroup.id];
29263	        if (buffer === undefined) {
29264	            prepareUniformsGroup(uniformsGroup);
29265	            buffer = createBuffer(uniformsGroup);
29266	            buffers[uniformsGroup.id] = buffer;
29267	            uniformsGroup.addEventListener('dispose', onUniformsGroupsDispose);
29268	        }
29269	        // ensure to update the binding points/block indices mapping for this program
29270	        const webglProgram = program.program;
29271	        state.updateUBOMapping(uniformsGroup, webglProgram);
29272	        // update UBO once per frame
29273	        const frame = info.render.frame;
29274	        if (updateList[uniformsGroup.id] !== frame) {
29275	            updateBufferData(uniformsGroup);
29276	            updateList[uniformsGroup.id] = frame;
29277	        }
29278	    }
29279	    function createBuffer(uniformsGroup) {
29280	        // the setup of an UBO is independent of a particular shader program but global
29281	        const bindingPointIndex = allocateBindingPointIndex();
29282	        uniformsGroup.__bindingPointIndex = bindingPointIndex;
29283	        const buffer = gl.createBuffer();
29284	        const size = uniformsGroup.__size;
29285	        const usage = uniformsGroup.usage;
29286	        gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
29287	        gl.bufferData(gl.UNIFORM_BUFFER, size, usage);
29288	        gl.bindBuffer(gl.UNIFORM_BUFFER, null);
29289	        gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer);
29290	        return buffer;
29291	    }
29292	    function allocateBindingPointIndex() {
29293	        for(let i = 0; i < maxBindingPoints; i++){
29294	            if (allocatedBindingPoints.indexOf(i) === -1) {
29295	                allocatedBindingPoints.push(i);
29296	                return i;
29297	            }
29298	        }
29299	        console.error('THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.');
29300	        return 0;
29301	    }
29302	    function updateBufferData(uniformsGroup) {
29303	        const buffer = buffers[uniformsGroup.id];
29304	        const uniforms = uniformsGroup.uniforms;
29305	        const cache = uniformsGroup.__cache;
29306	        gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
29307	        for(let i = 0, il = uniforms.length; i < il; i++){
29308	            const uniformArray = Array.isArray(uniforms[i]) ? uniforms[i] : [
29309	                uniforms[i]
29310	            ];
29311	            for(let j = 0, jl = uniformArray.length; j < jl; j++){
29312	                const uniform = uniformArray[j];
29313	                if (hasUniformChanged(uniform, i, j, cache) === true) {
29314	                    const offset = uniform.__offset;
29315	                    const values = Array.isArray(uniform.value) ? uniform.value : [
29316	                        uniform.value
29317	                    ];
29318	                    let arrayOffset = 0;
29319	                    for(let k = 0; k < values.length; k++){
29320	                        const value = values[k];
29321	                        const info = getUniformSize(value);
29322	                        // TODO add integer and struct support
29323	                        if (typeof value === 'number' || typeof value === 'boolean') {
29324	                            uniform.__data[0] = value;
29325	                            gl.bufferSubData(gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data);
29326	                        } else if (value.isMatrix3) {
29327	                            // manually converting 3x3 to 3x4
29328	                            uniform.__data[0] = value.elements[0];
29329	                            uniform.__data[1] = value.elements[1];
29330	                            uniform.__data[2] = value.elements[2];
29331	                            uniform.__data[3] = 0;
29332	                            uniform.__data[4] = value.elements[3];
29333	                            uniform.__data[5] = value.elements[4];
29334	                            uniform.__data[6] = value.elements[5];
29335	                            uniform.__data[7] = 0;
29336	                            uniform.__data[8] = value.elements[6];
29337	                            uniform.__data[9] = value.elements[7];
29338	                            uniform.__data[10] = value.elements[8];
29339	                            uniform.__data[11] = 0;
29340	                        } else {
29341	                            value.toArray(uniform.__data, arrayOffset);
29342	                            arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
29343	                        }
29344	                    }
29345	                    gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data);
29346	                }
29347	            }
29348	        }
29349	        gl.bindBuffer(gl.UNIFORM_BUFFER, null);
29350	    }
29351	    function hasUniformChanged(uniform, index, indexArray, cache) {
29352	        const value = uniform.value;
29353	        const indexString = index + '_' + indexArray;
29354	        if (cache[indexString] === undefined) {
29355	            // cache entry does not exist so far
29356	            if (typeof value === 'number' || typeof value === 'boolean') {
29357	                cache[indexString] = value;
29358	            } else {
29359	                cache[indexString] = value.clone();
29360	            }
29361	            return true;
29362	        } else {
29363	            const cachedObject = cache[indexString];
29364	            // compare current value with cached entry
29365	            if (typeof value === 'number' || typeof value === 'boolean') {
29366	                if (cachedObject !== value) {
29367	                    cache[indexString] = value;
29368	                    return true;
29369	                }
29370	            } else {
29371	                if (cachedObject.equals(value) === false) {
29372	                    cachedObject.copy(value);
29373	                    return true;
29374	                }
29375	            }
29376	        }
29377	        return false;
29378	    }
29379	    function prepareUniformsGroup(uniformsGroup) {
29380	        // determine total buffer size according to the STD140 layout
29381	        // Hint: STD140 is the only supported layout in WebGL 2
29382	        const uniforms = uniformsGroup.uniforms;
29383	        let offset = 0; // global buffer offset in bytes
29384	        const chunkSize = 16; // size of a chunk in bytes
29385	        for(let i = 0, l = uniforms.length; i < l; i++){
29386	            const uniformArray = Array.isArray(uniforms[i]) ? uniforms[i] : [
29387	                uniforms[i]
29388	            ];
29389	            for(let j = 0, jl = uniformArray.length; j < jl; j++){
29390	                const uniform = uniformArray[j];
29391	                const values = Array.isArray(uniform.value) ? uniform.value : [
29392	                    uniform.value
29393	                ];
29394	                for(let k = 0, kl = values.length; k < kl; k++){
29395	                    const value = values[k];
29396	                    const info = getUniformSize(value);
29397	                    const chunkOffset = offset % chunkSize; // offset in the current chunk
29398	                    const chunkPadding = chunkOffset % info.boundary; // required padding to match boundary
29399	                    const chunkStart = chunkOffset + chunkPadding; // the start position in the current chunk for the data
29400	                    offset += chunkPadding;
29401	                    // Check for chunk overflow
29402	                    if (chunkStart !== 0 && chunkSize - chunkStart < info.storage) {
29403	                        // Add padding and adjust offset
29404	                        offset += chunkSize - chunkStart;
29405	                    }
29406	                    // the following two properties will be used for partial buffer updates
29407	                    uniform.__data = new Float32Array(info.storage / Float32Array.BYTES_PER_ELEMENT);
29408	                    uniform.__offset = offset;
29409	                    // Update the global offset
29410	                    offset += info.storage;
29411	                }
29412	            }
29413	        }
29414	        // ensure correct final padding
29415	        const chunkOffset = offset % chunkSize;
29416	        if (chunkOffset > 0) offset += chunkSize - chunkOffset;
29417	        //
29418	        uniformsGroup.__size = offset;
29419	        uniformsGroup.__cache = {};
29420	        return this;
29421	    }
29422	    function getUniformSize(value) {
29423	        const info = {
29424	            boundary: 0,
29425	            storage: 0 // bytes
29426	        };
29427	        // determine sizes according to STD140
29428	        if (typeof value === 'number' || typeof value === 'boolean') {
29429	            // float/int/bool
29430	            info.boundary = 4;
29431	            info.storage = 4;
29432	        } else if (value.isVector2) {
29433	            // vec2
29434	            info.boundary = 8;
29435	            info.storage = 8;
29436	        } else if (value.isVector3 || value.isColor) {
29437	            // vec3
29438	            info.boundary = 16;
29439	            info.storage = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes
29440	        } else if (value.isVector4) {
29441	            // vec4
29442	            info.boundary = 16;
29443	            info.storage = 16;
29444	        } else if (value.isMatrix3) {
29445	            // mat3 (in STD140 a 3x3 matrix is represented as 3x4)
29446	            info.boundary = 48;
29447	            info.storage = 48;
29448	        } else if (value.isMatrix4) {
29449	            // mat4
29450	            info.boundary = 64;
29451	            info.storage = 64;
29452	        } else if (value.isTexture) {
29453	            console.warn('THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.');
29454	        } else {
29455	            console.warn('THREE.WebGLRenderer: Unsupported uniform value type.', value);
29456	        }
29457	        return info;
29458	    }
29459	    function onUniformsGroupsDispose(event) {
29460	        const uniformsGroup = event.target;
29461	        uniformsGroup.removeEventListener('dispose', onUniformsGroupsDispose);
29462	        const index = allocatedBindingPoints.indexOf(uniformsGroup.__bindingPointIndex);
29463	        allocatedBindingPoints.splice(index, 1);
29464	        gl.deleteBuffer(buffers[uniformsGroup.id]);
29465	        delete buffers[uniformsGroup.id];
29466	        delete updateList[uniformsGroup.id];
29467	    }
29468	    function dispose() {
29469	        for(const id in buffers){
29470	            gl.deleteBuffer(buffers[id]);
29471	        }
29472	        allocatedBindingPoints = [];
29473	        buffers = {};
29474	        updateList = {};
29475	    }
29476	    return {
29477	        bind: bind,
29478	        update: update,
29479	        dispose: dispose
29480	    };
29481	}
29482	class WebGLRenderer {
29483	    get coordinateSystem() {
29484	        return WebGLCoordinateSystem;
29485	    }
29486	    get outputColorSpace() {
29487	        return this._outputColorSpace;
29488	    }
29489	    set outputColorSpace(colorSpace) {
29490	        this._outputColorSpace = colorSpace;
29491	        const gl = this.getContext();
29492	        gl.drawingBufferColorspace = ColorManagement._getDrawingBufferColorSpace(colorSpace);
29493	        gl.unpackColorSpace = ColorManagement._getUnpackColorSpace();
29494	    }
29495	    constructor(parameters = {}){
29496	        const { canvas = createCanvasElement(), context = null, depth = true, stencil = false, alpha = false, antialias = false, premultipliedAlpha = true, preserveDrawingBuffer = false, powerPreference = 'default', failIfMajorPerformanceCaveat = false, reverseDepthBuffer = false } = parameters;
29497	        this.isWebGLRenderer = true;
29498	        let _alpha;
29499	        if (context !== null) {
29500	            if (typeof WebGLRenderingContext !== 'undefined' && context instanceof WebGLRenderingContext) {
29501	                throw new Error('THREE.WebGLRenderer: WebGL 1 is not supported since r163.');
29502	            }
29503	            _alpha = context.getContextAttributes().alpha;
29504	        } else {
29505	            _alpha = alpha;
29506	        }
29507	        const uintClearColor = new Uint32Array(4);
29508	        const intClearColor = new Int32Array(4);
29509	        let currentRenderList = null;
29510	        let currentRenderState = null;
29511	        // render() can be called from within a callback triggered by another render.
29512	        // We track this so that the nested render call gets its list and state isolated from the parent render call.
29513	        const renderListStack = [];
29514	        const renderStateStack = [];
29515	        // public properties
29516	        this.domElement = canvas;
29517	        // Debug configuration container
29518	        this.debug = {
29519	            /**
29520				 * Enables error checking and reporting when shader programs are being compiled
29521				 * @type {boolean}
29522				 */ checkShaderErrors: true,
29523	            /**
29524				 * Callback for custom error reporting.
29525				 * @type {?Function}
29526				 */ onShaderError: null
29527	        };
29528	        // clearing
29529	        this.autoClear = true;
29530	        this.autoClearColor = true;
29531	        this.autoClearDepth = true;
29532	        this.autoClearStencil = true;
29533	        // scene graph
29534	        this.sortObjects = true;
29535	        // user-defined clipping
29536	        this.clippingPlanes = [];
29537	        this.localClippingEnabled = false;
29538	        // physically based shading
29539	        this._outputColorSpace = SRGBColorSpace;
29540	        // tone mapping
29541	        this.toneMapping = NoToneMapping;
29542	        this.toneMappingExposure = 1.0;
29543	        // internal properties
29544	        const _this = this;
29545	        let _isContextLost = false;
29546	        // internal state cache
29547	        let _currentActiveCubeFace = 0;
29548	        let _currentActiveMipmapLevel = 0;
29549	        let _currentRenderTarget = null;
29550	        let _currentMaterialId = -1;
29551	        let _currentCamera = null;
29552	        const _currentViewport = new Vector4();
29553	        const _currentScissor = new Vector4();
29554	        let _currentScissorTest = null;
29555	        const _currentClearColor = new Color(0x000000);
29556	        let _currentClearAlpha = 0;
29557	        //
29558	        let _width = canvas.width;
29559	        let _height = canvas.height;
29560	        let _pixelRatio = 1;
29561	        let _opaqueSort = null;
29562	        let _transparentSort = null;
29563	        const _viewport = new Vector4(0, 0, _width, _height);
29564	        const _scissor = new Vector4(0, 0, _width, _height);
29565	        let _scissorTest = false;
29566	        // frustum
29567	        const _frustum = new Frustum();
29568	        // clipping
29569	        let _clippingEnabled = false;
29570	        let _localClippingEnabled = false;
29571	        // transmission render target scale
29572	        this.transmissionResolutionScale = 1.0;
29573	        // camera matrices cache
29574	        const _currentProjectionMatrix = new Matrix4();
29575	        const _projScreenMatrix = new Matrix4();
29576	        const _vector3 = new Vector3();
29577	        const _vector4 = new Vector4();
29578	        const _emptyScene = {
29579	            background: null,
29580	            fog: null,
29581	            environment: null,
29582	            overrideMaterial: null,
29583	            isScene: true
29584	        };
29585	        let _renderBackground = false;
29586	        function getTargetPixelRatio() {
29587	            return _currentRenderTarget === null ? _pixelRatio : 1;
29588	        }
29589	        // initialize
29590	        let _gl = context;
29591	        function getContext(contextName, contextAttributes) {
29592	            return canvas.getContext(contextName, contextAttributes);
29593	        }
29594	        try {
29595	            const contextAttributes = {
29596	                alpha: true,
29597	                depth,
29598	                stencil,
29599	                antialias,
29600	                premultipliedAlpha,
29601	                preserveDrawingBuffer,
29602	                powerPreference,
29603	                failIfMajorPerformanceCaveat
29604	            };
29605	            // OffscreenCanvas does not have setAttribute, see #22811
29606	            if ('setAttribute' in canvas) canvas.setAttribute('data-engine', `three.js r${REVISION}`);
29607	            // event listeners must be registered before WebGL context is created, see #12753
29608	            canvas.addEventListener('webglcontextlost', onContextLost, false);
29609	            canvas.addEventListener('webglcontextrestored', onContextRestore, false);
29610	            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
29611	            if (_gl === null) {
29612	                const contextName = 'webgl2';
29613	                _gl = getContext(contextName, contextAttributes);
29614	                if (_gl === null) {
29615	                    if (getContext(contextName)) {
29616	                        throw new Error('Error creating WebGL context with your selected attributes.');
29617	                    } else {
29618	                        throw new Error('Error creating WebGL context.');
29619	                    }
29620	                }
29621	            }
29622	        } catch (error) {
29623	            console.error('THREE.WebGLRenderer: ' + error.message);
29624	            throw error;
29625	        }
29626	        let extensions, capabilities, state, info;
29627	        let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
29628	        let programCache, materials, renderLists, renderStates, clipping, shadowMap;
29629	        let background, morphtargets, bufferRenderer, indexedBufferRenderer;
29630	        let utils, bindingStates, uniformsGroups;
29631	        function initGLContext() {
29632	            extensions = new WebGLExtensions(_gl);
29633	            extensions.init();
29634	            utils = new WebGLUtils(_gl, extensions);
29635	            capabilities = new WebGLCapabilities(_gl, extensions, parameters, utils);
29636	            state = new WebGLState(_gl, extensions);
29637	            if (capabilities.reverseDepthBuffer && reverseDepthBuffer) {
29638	                state.buffers.depth.setReversed(true);
29639	            }
29640	            info = new WebGLInfo(_gl);
29641	            properties = new WebGLProperties();
29642	            textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info);
29643	            cubemaps = new WebGLCubeMaps(_this);
29644	            cubeuvmaps = new WebGLCubeUVMaps(_this);
29645	            attributes = new WebGLAttributes(_gl);
29646	            bindingStates = new WebGLBindingStates(_gl, attributes);
29647	            geometries = new WebGLGeometries(_gl, attributes, info, bindingStates);
29648	            objects = new WebGLObjects(_gl, geometries, attributes, info);
29649	            morphtargets = new WebGLMorphtargets(_gl, capabilities, textures);
29650	            clipping = new WebGLClipping(properties);
29651	            programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping);
29652	            materials = new WebGLMaterials(_this, properties);
29653	            renderLists = new WebGLRenderLists();
29654	            renderStates = new WebGLRenderStates(extensions);
29655	            background = new WebGLBackground(_this, cubemaps, cubeuvmaps, state, objects, _alpha, premultipliedAlpha);
29656	            shadowMap = new WebGLShadowMap(_this, objects, capabilities);
29657	            uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state);
29658	            bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info);
29659	            indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info);
29660	            info.programs = programCache.programs;
29661	            _this.capabilities = capabilities;
29662	            _this.extensions = extensions;
29663	            _this.properties = properties;
29664	            _this.renderLists = renderLists;
29665	            _this.shadowMap = shadowMap;
29666	            _this.state = state;
29667	            _this.info = info;
29668	        }
29669	        initGLContext();
29670	        // xr
29671	        const xr = new WebXRManager(_this, _gl);
29672	        this.xr = xr;
29673	        // API
29674	        this.getContext = function() {
29675	            return _gl;
29676	        };
29677	        this.getContextAttributes = function() {
29678	            return _gl.getContextAttributes();
29679	        };
29680	        this.forceContextLoss = function() {
29681	            const extension = extensions.get('WEBGL_lose_context');
29682	            if (extension) extension.loseContext();
29683	        };
29684	        this.forceContextRestore = function() {
29685	            const extension = extensions.get('WEBGL_lose_context');
29686	            if (extension) extension.restoreContext();
29687	        };
29688	        this.getPixelRatio = function() {
29689	            return _pixelRatio;
29690	        };
29691	        this.setPixelRatio = function(value) {
29692	            if (value === undefined) return;
29693	            _pixelRatio = value;
29694	            this.setSize(_width, _height, false);
29695	        };
vendor: 7,040 bytes, lines 29696-29857
29696	        this.getSize = function(target) {
29697	            return target.set(_width, _height);
29698	        };
29699	        this.setSize = function(width, height, updateStyle = true) {
29700	            if (xr.isPresenting) {
29701	                console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.');
29702	                return;
29703	            }
29704	            _width = width;
29705	            _height = height;
29706	            canvas.width = Math.floor(width * _pixelRatio);
29707	            canvas.height = Math.floor(height * _pixelRatio);
29708	            if (updateStyle === true) {
29709	                canvas.style.width = width + 'px';
29710	                canvas.style.height = height + 'px';
29711	            }
29712	            this.setViewport(0, 0, width, height);
29713	        };
29714	        this.getDrawingBufferSize = function(target) {
29715	            return target.set(_width * _pixelRatio, _height * _pixelRatio).floor();
29716	        };
29717	        this.setDrawingBufferSize = function(width, height, pixelRatio) {
29718	            _width = width;
29719	            _height = height;
29720	            _pixelRatio = pixelRatio;
29721	            canvas.width = Math.floor(width * pixelRatio);
29722	            canvas.height = Math.floor(height * pixelRatio);
29723	            this.setViewport(0, 0, width, height);
29724	        };
29725	        this.getCurrentViewport = function(target) {
29726	            return target.copy(_currentViewport);
29727	        };
29728	        this.getViewport = function(target) {
29729	            return target.copy(_viewport);
29730	        };
29731	        this.setViewport = function(x, y, width, height) {
29732	            if (x.isVector4) {
29733	                _viewport.set(x.x, x.y, x.z, x.w);
29734	            } else {
29735	                _viewport.set(x, y, width, height);
29736	            }
29737	            state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).round());
29738	        };
29739	        this.getScissor = function(target) {
29740	            return target.copy(_scissor);
29741	        };
29742	        this.setScissor = function(x, y, width, height) {
29743	            if (x.isVector4) {
29744	                _scissor.set(x.x, x.y, x.z, x.w);
29745	            } else {
29746	                _scissor.set(x, y, width, height);
29747	            }
29748	            state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).round());
29749	        };
29750	        this.getScissorTest = function() {
29751	            return _scissorTest;
29752	        };
29753	        this.setScissorTest = function(boolean) {
29754	            state.setScissorTest(_scissorTest = boolean);
29755	        };
29756	        this.setOpaqueSort = function(method) {
29757	            _opaqueSort = method;
29758	        };
29759	        this.setTransparentSort = function(method) {
29760	            _transparentSort = method;
29761	        };
29762	        // Clearing
29763	        this.getClearColor = function(target) {
29764	            return target.copy(background.getClearColor());
29765	        };
29766	        this.setClearColor = function() {
29767	            background.setClearColor(...arguments);
29768	        };
29769	        this.getClearAlpha = function() {
29770	            return background.getClearAlpha();
29771	        };
29772	        this.setClearAlpha = function() {
29773	            background.setClearAlpha(...arguments);
29774	        };
29775	        this.clear = function(color = true, depth = true, stencil = true) {
29776	            let bits = 0;
29777	            if (color) {
29778	                // check if we're trying to clear an integer target
29779	                let isIntegerFormat = false;
29780	                if (_currentRenderTarget !== null) {
29781	                    const targetFormat = _currentRenderTarget.texture.format;
29782	                    isIntegerFormat = targetFormat === RGBAIntegerFormat || targetFormat === RGIntegerFormat || targetFormat === RedIntegerFormat;
29783	                }
29784	                // use the appropriate clear functions to clear the target if it's a signed
29785	                // or unsigned integer target
29786	                if (isIntegerFormat) {
29787	                    const targetType = _currentRenderTarget.texture.type;
29788	                    const isUnsignedType = targetType === UnsignedByteType || targetType === UnsignedIntType || targetType === UnsignedShortType || targetType === UnsignedInt248Type || targetType === UnsignedShort4444Type || targetType === UnsignedShort5551Type;
29789	                    const clearColor = background.getClearColor();
29790	                    const a = background.getClearAlpha();
29791	                    const r = clearColor.r;
29792	                    const g = clearColor.g;
29793	                    const b = clearColor.b;
29794	                    if (isUnsignedType) {
29795	                        uintClearColor[0] = r;
29796	                        uintClearColor[1] = g;
29797	                        uintClearColor[2] = b;
29798	                        uintClearColor[3] = a;
29799	                        _gl.clearBufferuiv(_gl.COLOR, 0, uintClearColor);
29800	                    } else {
29801	                        intClearColor[0] = r;
29802	                        intClearColor[1] = g;
29803	                        intClearColor[2] = b;
29804	                        intClearColor[3] = a;
29805	                        _gl.clearBufferiv(_gl.COLOR, 0, intClearColor);
29806	                    }
29807	                } else {
29808	                    bits |= _gl.COLOR_BUFFER_BIT;
29809	                }
29810	            }
29811	            if (depth) {
29812	                bits |= _gl.DEPTH_BUFFER_BIT;
29813	            }
29814	            if (stencil) {
29815	                bits |= _gl.STENCIL_BUFFER_BIT;
29816	                this.state.buffers.stencil.setMask(0xffffffff);
29817	            }
29818	            _gl.clear(bits);
29819	        };
29820	        this.clearColor = function() {
29821	            this.clear(true, false, false);
29822	        };
29823	        this.clearDepth = function() {
29824	            this.clear(false, true, false);
29825	        };
29826	        this.clearStencil = function() {
29827	            this.clear(false, false, true);
29828	        };
29829	        //
29830	        this.dispose = function() {
29831	            canvas.removeEventListener('webglcontextlost', onContextLost, false);
29832	            canvas.removeEventListener('webglcontextrestored', onContextRestore, false);
29833	            canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
29834	            background.dispose();
29835	            renderLists.dispose();
29836	            renderStates.dispose();
29837	            properties.dispose();
29838	            cubemaps.dispose();
29839	            cubeuvmaps.dispose();
29840	            objects.dispose();
29841	            bindingStates.dispose();
29842	            uniformsGroups.dispose();
29843	            programCache.dispose();
29844	            xr.dispose();
29845	            xr.removeEventListener('sessionstart', onXRSessionStart);
29846	            xr.removeEventListener('sessionend', onXRSessionEnd);
29847	            animation.stop();
29848	        };
29849	        // Events
29850	        function onContextLost(event) {
29851	            event.preventDefault();
29852	            console.log('THREE.WebGLRenderer: Context Lost.');
29853	            _isContextLost = true;
29854	        }
29855	        function onContextRestore() {
29856	            console.log('THREE.WebGLRenderer: Context Restored.');
29857	            _isContextLost = false;
vendor: 14,715 bytes, lines 29858-30143
29858	            const infoAutoReset = info.autoReset;
29859	            const shadowMapEnabled = shadowMap.enabled;
29860	            const shadowMapAutoUpdate = shadowMap.autoUpdate;
29861	            const shadowMapNeedsUpdate = shadowMap.needsUpdate;
29862	            const shadowMapType = shadowMap.type;
29863	            initGLContext();
29864	            info.autoReset = infoAutoReset;
29865	            shadowMap.enabled = shadowMapEnabled;
29866	            shadowMap.autoUpdate = shadowMapAutoUpdate;
29867	            shadowMap.needsUpdate = shadowMapNeedsUpdate;
29868	            shadowMap.type = shadowMapType;
29869	        }
29870	        function onContextCreationError(event) {
29871	            console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage);
29872	        }
29873	        function onMaterialDispose(event) {
29874	            const material = event.target;
29875	            material.removeEventListener('dispose', onMaterialDispose);
29876	            deallocateMaterial(material);
29877	        }
29878	        // Buffer deallocation
29879	        function deallocateMaterial(material) {
29880	            releaseMaterialProgramReferences(material);
29881	            properties.remove(material);
29882	        }
29883	        function releaseMaterialProgramReferences(material) {
29884	            const programs = properties.get(material).programs;
29885	            if (programs !== undefined) {
29886	                programs.forEach(function(program) {
29887	                    programCache.releaseProgram(program);
29888	                });
29889	                if (material.isShaderMaterial) {
29890	                    programCache.releaseShaderCache(material);
29891	                }
29892	            }
29893	        }
29894	        // Buffer rendering
29895	        this.renderBufferDirect = function(camera, scene, geometry, material, object, group) {
29896	            if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null)
29897	            const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0;
29898	            const program = setProgram(camera, scene, geometry, material, object);
29899	            state.setMaterial(material, frontFaceCW);
29900	            //
29901	            let index = geometry.index;
29902	            let rangeFactor = 1;
29903	            if (material.wireframe === true) {
29904	                index = geometries.getWireframeAttribute(geometry);
29905	                if (index === undefined) return;
29906	                rangeFactor = 2;
29907	            }
29908	            //
29909	            const drawRange = geometry.drawRange;
29910	            const position = geometry.attributes.position;
29911	            let drawStart = drawRange.start * rangeFactor;
29912	            let drawEnd = (drawRange.start + drawRange.count) * rangeFactor;
29913	            if (group !== null) {
29914	                drawStart = Math.max(drawStart, group.start * rangeFactor);
29915	                drawEnd = Math.min(drawEnd, (group.start + group.count) * rangeFactor);
29916	            }
29917	            if (index !== null) {
29918	                drawStart = Math.max(drawStart, 0);
29919	                drawEnd = Math.min(drawEnd, index.count);
29920	            } else if (position !== undefined && position !== null) {
29921	                drawStart = Math.max(drawStart, 0);
29922	                drawEnd = Math.min(drawEnd, position.count);
29923	            }
29924	            const drawCount = drawEnd - drawStart;
29925	            if (drawCount < 0 || drawCount === Infinity) return;
29926	            //
29927	            bindingStates.setup(object, material, program, geometry, index);
29928	            let attribute;
29929	            let renderer = bufferRenderer;
29930	            if (index !== null) {
29931	                attribute = attributes.get(index);
29932	                renderer = indexedBufferRenderer;
29933	                renderer.setIndex(attribute);
29934	            }
29935	            //
29936	            if (object.isMesh) {
29937	                if (material.wireframe === true) {
29938	                    state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio());
29939	                    renderer.setMode(_gl.LINES);
29940	                } else {
29941	                    renderer.setMode(_gl.TRIANGLES);
29942	                }
29943	            } else if (object.isLine) {
29944	                let lineWidth = material.linewidth;
29945	                if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material
29946	                state.setLineWidth(lineWidth * getTargetPixelRatio());
29947	                if (object.isLineSegments) {
29948	                    renderer.setMode(_gl.LINES);
29949	                } else if (object.isLineLoop) {
29950	                    renderer.setMode(_gl.LINE_LOOP);
29951	                } else {
29952	                    renderer.setMode(_gl.LINE_STRIP);
29953	                }
29954	            } else if (object.isPoints) {
29955	                renderer.setMode(_gl.POINTS);
29956	            } else if (object.isSprite) {
29957	                renderer.setMode(_gl.TRIANGLES);
29958	            }
29959	            if (object.isBatchedMesh) {
29960	                if (object._multiDrawInstances !== null) {
29961	                    // @deprecated, r174
29962	                    warnOnce('THREE.WebGLRenderer: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.');
29963	                    renderer.renderMultiDrawInstances(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount, object._multiDrawInstances);
29964	                } else {
29965	                    if (!extensions.get('WEBGL_multi_draw')) {
29966	                        const starts = object._multiDrawStarts;
29967	                        const counts = object._multiDrawCounts;
29968	                        const drawCount = object._multiDrawCount;
29969	                        const bytesPerElement = index ? attributes.get(index).bytesPerElement : 1;
29970	                        const uniforms = properties.get(material).currentProgram.getUniforms();
29971	                        for(let i = 0; i < drawCount; i++){
29972	                            uniforms.setValue(_gl, '_gl_DrawID', i);
29973	                            renderer.render(starts[i] / bytesPerElement, counts[i]);
29974	                        }
29975	                    } else {
29976	                        renderer.renderMultiDraw(object._multiDrawStarts, object._multiDrawCounts, object._multiDrawCount);
29977	                    }
29978	                }
29979	            } else if (object.isInstancedMesh) {
29980	                renderer.renderInstances(drawStart, drawCount, object.count);
29981	            } else if (geometry.isInstancedBufferGeometry) {
29982	                const maxInstanceCount = geometry._maxInstanceCount !== undefined ? geometry._maxInstanceCount : Infinity;
29983	                const instanceCount = Math.min(geometry.instanceCount, maxInstanceCount);
29984	                renderer.renderInstances(drawStart, drawCount, instanceCount);
29985	            } else {
29986	                renderer.render(drawStart, drawCount);
29987	            }
29988	        };
29989	        // Compile
29990	        function prepareMaterial(material, scene, object) {
29991	            if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) {
29992	                material.side = BackSide;
29993	                material.needsUpdate = true;
29994	                getProgram(material, scene, object);
29995	                material.side = FrontSide;
29996	                material.needsUpdate = true;
29997	                getProgram(material, scene, object);
29998	                material.side = DoubleSide;
29999	            } else {
30000	                getProgram(material, scene, object);
30001	            }
30002	        }
30003	        this.compile = function(scene, camera, targetScene = null) {
30004	            if (targetScene === null) targetScene = scene;
30005	            currentRenderState = renderStates.get(targetScene);
30006	            currentRenderState.init(camera);
30007	            renderStateStack.push(currentRenderState);
30008	            // gather lights from both the target scene and the new object that will be added to the scene.
30009	            targetScene.traverseVisible(function(object) {
30010	                if (object.isLight && object.layers.test(camera.layers)) {
30011	                    currentRenderState.pushLight(object);
30012	                    if (object.castShadow) {
30013	                        currentRenderState.pushShadow(object);
30014	                    }
30015	                }
30016	            });
30017	            if (scene !== targetScene) {
30018	                scene.traverseVisible(function(object) {
30019	                    if (object.isLight && object.layers.test(camera.layers)) {
30020	                        currentRenderState.pushLight(object);
30021	                        if (object.castShadow) {
30022	                            currentRenderState.pushShadow(object);
30023	                        }
30024	                    }
30025	                });
30026	            }
30027	            currentRenderState.setupLights();
30028	            // Only initialize materials in the new scene, not the targetScene.
30029	            const materials = new Set();
30030	            scene.traverse(function(object) {
30031	                if (!(object.isMesh || object.isPoints || object.isLine || object.isSprite)) {
30032	                    return;
30033	                }
30034	                const material = object.material;
30035	                if (material) {
30036	                    if (Array.isArray(material)) {
30037	                        for(let i = 0; i < material.length; i++){
30038	                            const material2 = material[i];
30039	                            prepareMaterial(material2, targetScene, object);
30040	                            materials.add(material2);
30041	                        }
30042	                    } else {
30043	                        prepareMaterial(material, targetScene, object);
30044	                        materials.add(material);
30045	                    }
30046	                }
30047	            });
30048	            currentRenderState = renderStateStack.pop();
30049	            return materials;
30050	        };
30051	        // compileAsync
30052	        this.compileAsync = function(scene, camera, targetScene = null) {
30053	            const materials = this.compile(scene, camera, targetScene);
30054	            // Wait for all the materials in the new object to indicate that they're
30055	            // ready to be used before resolving the promise.
30056	            return new Promise((resolve)=>{
30057	                function checkMaterialsReady() {
30058	                    materials.forEach(function(material) {
30059	                        const materialProperties = properties.get(material);
30060	                        const program = materialProperties.currentProgram;
30061	                        if (program.isReady()) {
30062	                            // remove any programs that report they're ready to use from the list
30063	                            materials.delete(material);
30064	                        }
30065	                    });
30066	                    // once the list of compiling materials is empty, call the callback
30067	                    if (materials.size === 0) {
30068	                        resolve(scene);
30069	                        return;
30070	                    }
30071	                    // if some materials are still not ready, wait a bit and check again
30072	                    setTimeout(checkMaterialsReady, 10);
30073	                }
30074	                if (extensions.get('KHR_parallel_shader_compile') !== null) {
30075	                    // If we can check the compilation status of the materials without
30076	                    // blocking then do so right away.
30077	                    checkMaterialsReady();
30078	                } else {
30079	                    // Otherwise start by waiting a bit to give the materials we just
30080	                    // initialized a chance to finish.
30081	                    setTimeout(checkMaterialsReady, 10);
30082	                }
30083	            });
30084	        };
30085	        // Animation Loop
30086	        let onAnimationFrameCallback = null;
30087	        function onAnimationFrame(time) {
30088	            if (onAnimationFrameCallback) onAnimationFrameCallback(time);
30089	        }
30090	        function onXRSessionStart() {
30091	            animation.stop();
30092	        }
30093	        function onXRSessionEnd() {
30094	            animation.start();
30095	        }
30096	        const animation = new WebGLAnimation();
30097	        animation.setAnimationLoop(onAnimationFrame);
30098	        if (typeof self !== 'undefined') animation.setContext(self);
30099	        this.setAnimationLoop = function(callback) {
30100	            onAnimationFrameCallback = callback;
30101	            xr.setAnimationLoop(callback);
30102	            callback === null ? animation.stop() : animation.start();
30103	        };
30104	        xr.addEventListener('sessionstart', onXRSessionStart);
30105	        xr.addEventListener('sessionend', onXRSessionEnd);
30106	        // Rendering
30107	        this.render = function(scene, camera) {
30108	            if (camera !== undefined && camera.isCamera !== true) {
30109	                console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.');
30110	                return;
30111	            }
30112	            if (_isContextLost === true) return;
30113	            // update scene graph
30114	            if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld();
30115	            // update camera matrices and frustum
30116	            if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld();
30117	            if (xr.enabled === true && xr.isPresenting === true) {
30118	                if (xr.cameraAutoUpdate === true) xr.updateCamera(camera);
30119	                camera = xr.getCamera(); // use XR camera for rendering
30120	            }
30121	            //
30122	            if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget);
30123	            currentRenderState = renderStates.get(scene, renderStateStack.length);
30124	            currentRenderState.init(camera);
30125	            renderStateStack.push(currentRenderState);
30126	            _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
30127	            _frustum.setFromProjectionMatrix(_projScreenMatrix);
30128	            _localClippingEnabled = this.localClippingEnabled;
30129	            _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled);
30130	            currentRenderList = renderLists.get(scene, renderListStack.length);
30131	            currentRenderList.init();
30132	            renderListStack.push(currentRenderList);
30133	            if (xr.enabled === true && xr.isPresenting === true) {
30134	                const depthSensingMesh = _this.xr.getDepthSensingMesh();
30135	                if (depthSensingMesh !== null) {
30136	                    projectObject(depthSensingMesh, camera, -Infinity, _this.sortObjects);
30137	                }
30138	            }
30139	            projectObject(scene, camera, 0, _this.sortObjects);
30140	            currentRenderList.finish();
30141	            if (_this.sortObjects === true) {
30142	                currentRenderList.sort(_opaqueSort, _transparentSort);
30143	            }
vendor: 5,344 bytes, lines 30144-30240
30144	            _renderBackground = xr.enabled === false || xr.isPresenting === false || xr.hasDepthSensing() === false;
30145	            if (_renderBackground) {
30146	                background.addToRenderList(currentRenderList, scene);
30147	            }
30148	            //
30149	            this.info.render.frame++;
30150	            if (_clippingEnabled === true) clipping.beginShadows();
30151	            const shadowsArray = currentRenderState.state.shadowsArray;
30152	            shadowMap.render(shadowsArray, scene, camera);
30153	            if (_clippingEnabled === true) clipping.endShadows();
30154	            //
30155	            if (this.info.autoReset === true) this.info.reset();
30156	            // render scene
30157	            const opaqueObjects = currentRenderList.opaque;
30158	            const transmissiveObjects = currentRenderList.transmissive;
30159	            currentRenderState.setupLights();
30160	            if (camera.isArrayCamera) {
30161	                const cameras = camera.cameras;
30162	                if (transmissiveObjects.length > 0) {
30163	                    for(let i = 0, l = cameras.length; i < l; i++){
30164	                        const camera2 = cameras[i];
30165	                        renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera2);
30166	                    }
30167	                }
30168	                if (_renderBackground) background.render(scene);
30169	                for(let i = 0, l = cameras.length; i < l; i++){
30170	                    const camera2 = cameras[i];
30171	                    renderScene(currentRenderList, scene, camera2, camera2.viewport);
30172	                }
30173	            } else {
30174	                if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera);
30175	                if (_renderBackground) background.render(scene);
30176	                renderScene(currentRenderList, scene, camera);
30177	            }
30178	            //
30179	            if (_currentRenderTarget !== null && _currentActiveMipmapLevel === 0) {
30180	                // resolve multisample renderbuffers to a single-sample texture if necessary
30181	                textures.updateMultisampleRenderTarget(_currentRenderTarget);
30182	                // Generate mipmap if we're using any kind of mipmap filtering
30183	                textures.updateRenderTargetMipmap(_currentRenderTarget);
30184	            }
30185	            //
30186	            if (scene.isScene === true) scene.onAfterRender(_this, scene, camera);
30187	            // _gl.finish();
30188	            bindingStates.resetDefaultState();
30189	            _currentMaterialId = -1;
30190	            _currentCamera = null;
30191	            renderStateStack.pop();
30192	            if (renderStateStack.length > 0) {
30193	                currentRenderState = renderStateStack[renderStateStack.length - 1];
30194	                if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, currentRenderState.state.camera);
30195	            } else {
30196	                currentRenderState = null;
30197	            }
30198	            renderListStack.pop();
30199	            if (renderListStack.length > 0) {
30200	                currentRenderList = renderListStack[renderListStack.length - 1];
30201	            } else {
30202	                currentRenderList = null;
30203	            }
30204	        };
30205	        function projectObject(object, camera, groupOrder, sortObjects) {
30206	            if (object.visible === false) return;
30207	            const visible = object.layers.test(camera.layers);
30208	            if (visible) {
30209	                if (object.isGroup) {
30210	                    groupOrder = object.renderOrder;
30211	                } else if (object.isLOD) {
30212	                    if (object.autoUpdate === true) object.update(camera);
30213	                } else if (object.isLight) {
30214	                    currentRenderState.pushLight(object);
30215	                    if (object.castShadow) {
30216	                        currentRenderState.pushShadow(object);
30217	                    }
30218	                } else if (object.isSprite) {
30219	                    if (!object.frustumCulled || _frustum.intersectsSprite(object)) {
30220	                        if (sortObjects) {
30221	                            _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix);
30222	                        }
30223	                        const geometry = objects.update(object);
30224	                        const material = object.material;
30225	                        if (material.visible) {
30226	                            currentRenderList.push(object, geometry, material, groupOrder, _vector4.z, null);
30227	                        }
30228	                    }
30229	                } else if (object.isMesh || object.isLine || object.isPoints) {
30230	                    if (!object.frustumCulled || _frustum.intersectsObject(object)) {
30231	                        const geometry = objects.update(object);
30232	                        const material = object.material;
30233	                        if (sortObjects) {
30234	                            if (object.boundingSphere !== undefined) {
30235	                                if (object.boundingSphere === null) object.computeBoundingSphere();
30236	                                _vector4.copy(object.boundingSphere.center);
30237	                            } else {
30238	                                if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
30239	                                _vector4.copy(geometry.boundingSphere.center);
30240	                            }
30241	                            _vector4.applyMatrix4(object.matrixWorld).applyMatrix4(_projScreenMatrix);
30242	                        }
30243	                        if (Array.isArray(material)) {
30244	                            const groups = geometry.groups;
30245	                            for(let i = 0, l = groups.length; i < l; i++){
30246	                                const group = groups[i];
30247	                                const groupMaterial = material[group.materialIndex];
30248	                                if (groupMaterial && groupMaterial.visible) {
30249	                                    currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group);
30250	                                }
30251	                            }
30252	                        } else if (material.visible) {
30253	                            currentRenderList.push(object, geometry, material, groupOrder, _vector4.z, null);
30254	                        }
30255	                    }
30256	                }
30257	            }
30258	            const children = object.children;
30259	            for(let i = 0, l = children.length; i < l; i++){
30260	                projectObject(children[i], camera, groupOrder, sortObjects);
30261	            }
30262	        }
vendor: 27,326 bytes, lines 30263-30677
30263	        function renderScene(currentRenderList, scene, camera, viewport) {
30264	            const opaqueObjects = currentRenderList.opaque;
30265	            const transmissiveObjects = currentRenderList.transmissive;
30266	            const transparentObjects = currentRenderList.transparent;
30267	            currentRenderState.setupLightsView(camera);
30268	            if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, camera);
30269	            if (viewport) state.viewport(_currentViewport.copy(viewport));
30270	            if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera);
30271	            if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera);
30272	            if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera);
30273	            // Ensure depth buffer writing is enabled so it can be cleared on next render
30274	            state.buffers.depth.setTest(true);
30275	            state.buffers.depth.setMask(true);
30276	            state.buffers.color.setMask(true);
30277	            state.setPolygonOffset(false);
30278	        }
30279	        function renderTransmissionPass(opaqueObjects, transmissiveObjects, scene, camera) {
30280	            const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
30281	            if (overrideMaterial !== null) {
30282	                return;
30283	            }
30284	            if (currentRenderState.state.transmissionRenderTarget[camera.id] === undefined) {
30285	                currentRenderState.state.transmissionRenderTarget[camera.id] = new WebGLRenderTarget(1, 1, {
30286	                    generateMipmaps: true,
30287	                    type: extensions.has('EXT_color_buffer_half_float') || extensions.has('EXT_color_buffer_float') ? HalfFloatType : UnsignedByteType,
30288	                    minFilter: LinearMipmapLinearFilter,
30289	                    samples: 4,
30290	                    stencilBuffer: stencil,
30291	                    resolveDepthBuffer: false,
30292	                    resolveStencilBuffer: false,
30293	                    colorSpace: ColorManagement.workingColorSpace
30294	                });
30295	            // debug
30296	            /*
30297					const geometry = new PlaneGeometry();
30298					const material = new MeshBasicMaterial( { map: _transmissionRenderTarget.texture } );
30299
30300					const mesh = new Mesh( geometry, material );
30301					scene.add( mesh );
30302					*/ }
30303	            const transmissionRenderTarget = currentRenderState.state.transmissionRenderTarget[camera.id];
30304	            const activeViewport = camera.viewport || _currentViewport;
30305	            transmissionRenderTarget.setSize(activeViewport.z * _this.transmissionResolutionScale, activeViewport.w * _this.transmissionResolutionScale);
30306	            //
30307	            const currentRenderTarget = _this.getRenderTarget();
30308	            _this.setRenderTarget(transmissionRenderTarget);
30309	            _this.getClearColor(_currentClearColor);
30310	            _currentClearAlpha = _this.getClearAlpha();
30311	            if (_currentClearAlpha < 1) _this.setClearColor(0xffffff, 0.5);
30312	            _this.clear();
30313	            if (_renderBackground) background.render(scene);
30314	            // Turn off the features which can affect the frag color for opaque objects pass.
30315	            // Otherwise they are applied twice in opaque objects pass and transmission objects pass.
30316	            const currentToneMapping = _this.toneMapping;
30317	            _this.toneMapping = NoToneMapping;
30318	            // Remove viewport from camera to avoid nested render calls resetting viewport to it (e.g Reflector).
30319	            // Transmission render pass requires viewport to match the transmissionRenderTarget.
30320	            const currentCameraViewport = camera.viewport;
30321	            if (camera.viewport !== undefined) camera.viewport = undefined;
30322	            currentRenderState.setupLightsView(camera);
30323	            if (_clippingEnabled === true) clipping.setGlobalState(_this.clippingPlanes, camera);
30324	            renderObjects(opaqueObjects, scene, camera);
30325	            textures.updateMultisampleRenderTarget(transmissionRenderTarget);
30326	            textures.updateRenderTargetMipmap(transmissionRenderTarget);
30327	            if (extensions.has('WEBGL_multisampled_render_to_texture') === false) {
30328	                let renderTargetNeedsUpdate = false;
30329	                for(let i = 0, l = transmissiveObjects.length; i < l; i++){
30330	                    const renderItem = transmissiveObjects[i];
30331	                    const object = renderItem.object;
30332	                    const geometry = renderItem.geometry;
30333	                    const material = renderItem.material;
30334	                    const group = renderItem.group;
30335	                    if (material.side === DoubleSide && object.layers.test(camera.layers)) {
30336	                        const currentSide = material.side;
30337	                        material.side = BackSide;
30338	                        material.needsUpdate = true;
30339	                        renderObject(object, scene, camera, geometry, material, group);
30340	                        material.side = currentSide;
30341	                        material.needsUpdate = true;
30342	                        renderTargetNeedsUpdate = true;
30343	                    }
30344	                }
30345	                if (renderTargetNeedsUpdate === true) {
30346	                    textures.updateMultisampleRenderTarget(transmissionRenderTarget);
30347	                    textures.updateRenderTargetMipmap(transmissionRenderTarget);
30348	                }
30349	            }
30350	            _this.setRenderTarget(currentRenderTarget);
30351	            _this.setClearColor(_currentClearColor, _currentClearAlpha);
30352	            if (currentCameraViewport !== undefined) camera.viewport = currentCameraViewport;
30353	            _this.toneMapping = currentToneMapping;
30354	        }
30355	        function renderObjects(renderList, scene, camera) {
30356	            const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
30357	            for(let i = 0, l = renderList.length; i < l; i++){
30358	                const renderItem = renderList[i];
30359	                const object = renderItem.object;
30360	                const geometry = renderItem.geometry;
30361	                const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
30362	                const group = renderItem.group;
30363	                if (object.layers.test(camera.layers)) {
30364	                    renderObject(object, scene, camera, geometry, material, group);
30365	                }
30366	            }
30367	        }
30368	        function renderObject(object, scene, camera, geometry, material, group) {
30369	            object.onBeforeRender(_this, scene, camera, geometry, material, group);
30370	            object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld);
30371	            object.normalMatrix.getNormalMatrix(object.modelViewMatrix);
30372	            material.onBeforeRender(_this, scene, camera, geometry, object, group);
30373	            if (material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false) {
30374	                material.side = BackSide;
30375	                material.needsUpdate = true;
30376	                _this.renderBufferDirect(camera, scene, geometry, material, object, group);
30377	                material.side = FrontSide;
30378	                material.needsUpdate = true;
30379	                _this.renderBufferDirect(camera, scene, geometry, material, object, group);
30380	                material.side = DoubleSide;
30381	            } else {
30382	                _this.renderBufferDirect(camera, scene, geometry, material, object, group);
30383	            }
30384	            object.onAfterRender(_this, scene, camera, geometry, material, group);
30385	        }
30386	        function getProgram(material, scene, object) {
30387	            if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
30388	            const materialProperties = properties.get(material);
30389	            const lights = currentRenderState.state.lights;
30390	            const shadowsArray = currentRenderState.state.shadowsArray;
30391	            const lightsStateVersion = lights.state.version;
30392	            const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object);
30393	            const programCacheKey = programCache.getProgramCacheKey(parameters);
30394	            let programs = materialProperties.programs;
30395	            // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change
30396	            materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
30397	            materialProperties.fog = scene.fog;
30398	            materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment);
30399	            materialProperties.envMapRotation = materialProperties.environment !== null && material.envMap === null ? scene.environmentRotation : material.envMapRotation;
30400	            if (programs === undefined) {
30401	                // new material
30402	                material.addEventListener('dispose', onMaterialDispose);
30403	                programs = new Map();
30404	                materialProperties.programs = programs;
30405	            }
30406	            let program = programs.get(programCacheKey);
30407	            if (program !== undefined) {
30408	                // early out if program and light state is identical
30409	                if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) {
30410	                    updateCommonMaterialProperties(material, parameters);
30411	                    return program;
30412	                }
30413	            } else {
30414	                parameters.uniforms = programCache.getUniforms(material);
30415	                material.onBeforeCompile(parameters, _this);
30416	                program = programCache.acquireProgram(parameters, programCacheKey);
30417	                programs.set(programCacheKey, program);
30418	                materialProperties.uniforms = parameters.uniforms;
30419	            }
30420	            const uniforms = materialProperties.uniforms;
30421	            if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) {
30422	                uniforms.clippingPlanes = clipping.uniform;
30423	            }
30424	            updateCommonMaterialProperties(material, parameters);
30425	            // store the light setup it was created for
30426	            materialProperties.needsLights = materialNeedsLights(material);
30427	            materialProperties.lightsStateVersion = lightsStateVersion;
30428	            if (materialProperties.needsLights) {
30429	                // wire up the material to this renderer's lighting state
30430	                uniforms.ambientLightColor.value = lights.state.ambient;
30431	                uniforms.lightProbe.value = lights.state.probe;
30432	                uniforms.directionalLights.value = lights.state.directional;
30433	                uniforms.directionalLightShadows.value = lights.state.directionalShadow;
30434	                uniforms.spotLights.value = lights.state.spot;
30435	                uniforms.spotLightShadows.value = lights.state.spotShadow;
30436	                uniforms.rectAreaLights.value = lights.state.rectArea;
30437	                uniforms.ltc_1.value = lights.state.rectAreaLTC1;
30438	                uniforms.ltc_2.value = lights.state.rectAreaLTC2;
30439	                uniforms.pointLights.value = lights.state.point;
30440	                uniforms.pointLightShadows.value = lights.state.pointShadow;
30441	                uniforms.hemisphereLights.value = lights.state.hemi;
30442	                uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
30443	                uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
30444	                uniforms.spotShadowMap.value = lights.state.spotShadowMap;
30445	                uniforms.spotLightMatrix.value = lights.state.spotLightMatrix;
30446	                uniforms.spotLightMap.value = lights.state.spotLightMap;
30447	                uniforms.pointShadowMap.value = lights.state.pointShadowMap;
30448	                uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix;
30449	            // TODO (abelnation): add area lights shadow info to uniforms
30450	            }
30451	            materialProperties.currentProgram = program;
30452	            materialProperties.uniformsList = null;
30453	            return program;
30454	        }
30455	        function getUniformList(materialProperties) {
30456	            if (materialProperties.uniformsList === null) {
30457	                const progUniforms = materialProperties.currentProgram.getUniforms();
30458	                materialProperties.uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, materialProperties.uniforms);
30459	            }
30460	            return materialProperties.uniformsList;
30461	        }
30462	        function updateCommonMaterialProperties(material, parameters) {
30463	            const materialProperties = properties.get(material);
30464	            materialProperties.outputColorSpace = parameters.outputColorSpace;
30465	            materialProperties.batching = parameters.batching;
30466	            materialProperties.batchingColor = parameters.batchingColor;
30467	            materialProperties.instancing = parameters.instancing;
30468	            materialProperties.instancingColor = parameters.instancingColor;
30469	            materialProperties.instancingMorph = parameters.instancingMorph;
30470	            materialProperties.skinning = parameters.skinning;
30471	            materialProperties.morphTargets = parameters.morphTargets;
30472	            materialProperties.morphNormals = parameters.morphNormals;
30473	            materialProperties.morphColors = parameters.morphColors;
30474	            materialProperties.morphTargetsCount = parameters.morphTargetsCount;
30475	            materialProperties.numClippingPlanes = parameters.numClippingPlanes;
30476	            materialProperties.numIntersection = parameters.numClipIntersection;
30477	            materialProperties.vertexAlphas = parameters.vertexAlphas;
30478	            materialProperties.vertexTangents = parameters.vertexTangents;
30479	            materialProperties.toneMapping = parameters.toneMapping;
30480	        }
30481	        function setProgram(camera, scene, geometry, material, object) {
30482	            if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
30483	            textures.resetTextureUnits();
30484	            const fog = scene.fog;
30485	            const environment = material.isMeshStandardMaterial ? scene.environment : null;
30486	            const colorSpace = _currentRenderTarget === null ? _this.outputColorSpace : _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace;
30487	            const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
30488	            const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4;
30489	            const vertexTangents = !!geometry.attributes.tangent && (!!material.normalMap || material.anisotropy > 0);
30490	            const morphTargets = !!geometry.morphAttributes.position;
30491	            const morphNormals = !!geometry.morphAttributes.normal;
30492	            const morphColors = !!geometry.morphAttributes.color;
30493	            let toneMapping = NoToneMapping;
30494	            if (material.toneMapped) {
30495	                if (_currentRenderTarget === null || _currentRenderTarget.isXRRenderTarget === true) {
30496	                    toneMapping = _this.toneMapping;
30497	                }
30498	            }
30499	            const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
30500	            const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
30501	            const materialProperties = properties.get(material);
30502	            const lights = currentRenderState.state.lights;
30503	            if (_clippingEnabled === true) {
30504	                if (_localClippingEnabled === true || camera !== _currentCamera) {
30505	                    const useCache = camera === _currentCamera && material.id === _currentMaterialId;
30506	                    // we might want to call this function with some ClippingGroup
30507	                    // object instead of the material, once it becomes feasible
30508	                    // (#8465, #8379)
30509	                    clipping.setState(material, camera, useCache);
30510	                }
30511	            }
30512	            //
30513	            let needsProgramChange = false;
30514	            if (material.version === materialProperties.__version) {
30515	                if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) {
30516	                    needsProgramChange = true;
30517	                } else if (materialProperties.outputColorSpace !== colorSpace) {
30518	                    needsProgramChange = true;
30519	                } else if (object.isBatchedMesh && materialProperties.batching === false) {
30520	                    needsProgramChange = true;
30521	                } else if (!object.isBatchedMesh && materialProperties.batching === true) {
30522	                    needsProgramChange = true;
30523	                } else if (object.isBatchedMesh && materialProperties.batchingColor === true && object.colorTexture === null) {
30524	                    needsProgramChange = true;
30525	                } else if (object.isBatchedMesh && materialProperties.batchingColor === false && object.colorTexture !== null) {
30526	                    needsProgramChange = true;
30527	                } else if (object.isInstancedMesh && materialProperties.instancing === false) {
30528	                    needsProgramChange = true;
30529	                } else if (!object.isInstancedMesh && materialProperties.instancing === true) {
30530	                    needsProgramChange = true;
30531	                } else if (object.isSkinnedMesh && materialProperties.skinning === false) {
30532	                    needsProgramChange = true;
30533	                } else if (!object.isSkinnedMesh && materialProperties.skinning === true) {
30534	                    needsProgramChange = true;
30535	                } else if (object.isInstancedMesh && materialProperties.instancingColor === true && object.instanceColor === null) {
30536	                    needsProgramChange = true;
30537	                } else if (object.isInstancedMesh && materialProperties.instancingColor === false && object.instanceColor !== null) {
30538	                    needsProgramChange = true;
30539	                } else if (object.isInstancedMesh && materialProperties.instancingMorph === true && object.morphTexture === null) {
30540	                    needsProgramChange = true;
30541	                } else if (object.isInstancedMesh && materialProperties.instancingMorph === false && object.morphTexture !== null) {
30542	                    needsProgramChange = true;
30543	                } else if (materialProperties.envMap !== envMap) {
30544	                    needsProgramChange = true;
30545	                } else if (material.fog === true && materialProperties.fog !== fog) {
30546	                    needsProgramChange = true;
30547	                } else if (materialProperties.numClippingPlanes !== undefined && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) {
30548	                    needsProgramChange = true;
30549	                } else if (materialProperties.vertexAlphas !== vertexAlphas) {
30550	                    needsProgramChange = true;
30551	                } else if (materialProperties.vertexTangents !== vertexTangents) {
30552	                    needsProgramChange = true;
30553	                } else if (materialProperties.morphTargets !== morphTargets) {
30554	                    needsProgramChange = true;
30555	                } else if (materialProperties.morphNormals !== morphNormals) {
30556	                    needsProgramChange = true;
30557	                } else if (materialProperties.morphColors !== morphColors) {
30558	                    needsProgramChange = true;
30559	                } else if (materialProperties.toneMapping !== toneMapping) {
30560	                    needsProgramChange = true;
30561	                } else if (materialProperties.morphTargetsCount !== morphTargetsCount) {
30562	                    needsProgramChange = true;
30563	                }
30564	            } else {
30565	                needsProgramChange = true;
30566	                materialProperties.__version = material.version;
30567	            }
30568	            //
30569	            let program = materialProperties.currentProgram;
30570	            if (needsProgramChange === true) {
30571	                program = getProgram(material, scene, object);
30572	            }
30573	            let refreshProgram = false;
30574	            let refreshMaterial = false;
30575	            let refreshLights = false;
30576	            const p_uniforms = program.getUniforms(), m_uniforms = materialProperties.uniforms;
30577	            if (state.useProgram(program.program)) {
30578	                refreshProgram = true;
30579	                refreshMaterial = true;
30580	                refreshLights = true;
30581	            }
30582	            if (material.id !== _currentMaterialId) {
30583	                _currentMaterialId = material.id;
30584	                refreshMaterial = true;
30585	            }
30586	            if (refreshProgram || _currentCamera !== camera) {
30587	                // common camera uniforms
30588	                const reverseDepthBuffer = state.buffers.depth.getReversed();
30589	                if (reverseDepthBuffer) {
30590	                    _currentProjectionMatrix.copy(camera.projectionMatrix);
30591	                    toNormalizedProjectionMatrix(_currentProjectionMatrix);
30592	                    toReversedProjectionMatrix(_currentProjectionMatrix);
30593	                    p_uniforms.setValue(_gl, 'projectionMatrix', _currentProjectionMatrix);
30594	                } else {
30595	                    p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix);
30596	                }
30597	                p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse);
30598	                const uCamPos = p_uniforms.map.cameraPosition;
30599	                if (uCamPos !== undefined) {
30600	                    uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld));
30601	                }
30602	                if (capabilities.logarithmicDepthBuffer) {
30603	                    p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2));
30604	                }
30605	                // consider moving isOrthographic to UniformLib and WebGLMaterials, see https://github.com/mrdoob/three.js/pull/26467#issuecomment-1645185067
30606	                if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) {
30607	                    p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true);
30608	                }
30609	                if (_currentCamera !== camera) {
30610	                    _currentCamera = camera;
30611	                    // lighting uniforms depend on the camera so enforce an update
30612	                    // now, in case this material supports lights - or later, when
30613	                    // the next material that does gets activated:
30614	                    refreshMaterial = true; // set to true on material change
30615	                    refreshLights = true; // remains set until update done
30616	                }
30617	            }
30618	            // skinning and morph target uniforms must be set even if material didn't change
30619	            // auto-setting of texture unit for bone and morph texture must go before other textures
30620	            // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures
30621	            if (object.isSkinnedMesh) {
30622	                p_uniforms.setOptional(_gl, object, 'bindMatrix');
30623	                p_uniforms.setOptional(_gl, object, 'bindMatrixInverse');
30624	                const skeleton = object.skeleton;
30625	                if (skeleton) {
30626	                    if (skeleton.boneTexture === null) skeleton.computeBoneTexture();
30627	                    p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures);
30628	                }
30629	            }
30630	            if (object.isBatchedMesh) {
30631	                p_uniforms.setOptional(_gl, object, 'batchingTexture');
30632	                p_uniforms.setValue(_gl, 'batchingTexture', object._matricesTexture, textures);
30633	                p_uniforms.setOptional(_gl, object, 'batchingIdTexture');
30634	                p_uniforms.setValue(_gl, 'batchingIdTexture', object._indirectTexture, textures);
30635	                p_uniforms.setOptional(_gl, object, 'batchingColorTexture');
30636	                if (object._colorsTexture !== null) {
30637	                    p_uniforms.setValue(_gl, 'batchingColorTexture', object._colorsTexture, textures);
30638	                }
30639	            }
30640	            const morphAttributes = geometry.morphAttributes;
30641	            if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined) {
30642	                morphtargets.update(object, geometry, program);
30643	            }
30644	            if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) {
30645	                materialProperties.receiveShadow = object.receiveShadow;
30646	                p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow);
30647	            }
30648	            // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512
30649	            if (material.isMeshGouraudMaterial && material.envMap !== null) {
30650	                m_uniforms.envMap.value = envMap;
30651	                m_uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
30652	            }
30653	            if (material.isMeshStandardMaterial && material.envMap === null && scene.environment !== null) {
30654	                m_uniforms.envMapIntensity.value = scene.environmentIntensity;
30655	            }
30656	            if (refreshMaterial) {
30657	                p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure);
30658	                if (materialProperties.needsLights) {
30659	                    // the current material requires lighting info
30660	                    // note: all lighting uniforms are always set correctly
30661	                    // they simply reference the renderer's state for their
30662	                    // values
30663	                    //
30664	                    // use the current material's .needsUpdate flags to set
30665	                    // the GL state when required
30666	                    markUniformsLightsNeedsUpdate(m_uniforms, refreshLights);
30667	                }
30668	                // refresh uniforms common to several materials
30669	                if (fog && material.fog === true) {
30670	                    materials.refreshFogUniforms(m_uniforms, fog);
30671	                }
30672	                materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, currentRenderState.state.transmissionRenderTarget[camera.id]);
30673	                WebGLUniforms.upload(_gl, getUniformList(materialProperties), m_uniforms, textures);
30674	            }
30675	            if (material.isShaderMaterial && material.uniformsNeedUpdate === true) {
30676	                WebGLUniforms.upload(_gl, getUniformList(materialProperties), m_uniforms, textures);
30677	                material.uniformsNeedUpdate = false;
vendor: 4,126 bytes, lines 30678-30749
30678	            }
30679	            if (material.isSpriteMaterial) {
30680	                p_uniforms.setValue(_gl, 'center', object.center);
30681	            }
30682	            // common matrices
30683	            p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix);
30684	            p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix);
30685	            p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld);
30686	            // UBOs
30687	            if (material.isShaderMaterial || material.isRawShaderMaterial) {
30688	                const groups = material.uniformsGroups;
30689	                for(let i = 0, l = groups.length; i < l; i++){
30690	                    const group = groups[i];
30691	                    uniformsGroups.update(group, program);
30692	                    uniformsGroups.bind(group, program);
30693	                }
30694	            }
30695	            return program;
30696	        }
30697	        // If uniforms are marked as clean, they don't need to be loaded to the GPU.
30698	        function markUniformsLightsNeedsUpdate(uniforms, value) {
30699	            uniforms.ambientLightColor.needsUpdate = value;
30700	            uniforms.lightProbe.needsUpdate = value;
30701	            uniforms.directionalLights.needsUpdate = value;
30702	            uniforms.directionalLightShadows.needsUpdate = value;
30703	            uniforms.pointLights.needsUpdate = value;
30704	            uniforms.pointLightShadows.needsUpdate = value;
30705	            uniforms.spotLights.needsUpdate = value;
30706	            uniforms.spotLightShadows.needsUpdate = value;
30707	            uniforms.rectAreaLights.needsUpdate = value;
30708	            uniforms.hemisphereLights.needsUpdate = value;
30709	        }
30710	        function materialNeedsLights(material) {
30711	            return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true;
30712	        }
30713	        this.getActiveCubeFace = function() {
30714	            return _currentActiveCubeFace;
30715	        };
30716	        this.getActiveMipmapLevel = function() {
30717	            return _currentActiveMipmapLevel;
30718	        };
30719	        this.getRenderTarget = function() {
30720	            return _currentRenderTarget;
30721	        };
30722	        this.setRenderTargetTextures = function(renderTarget, colorTexture, depthTexture) {
30723	            properties.get(renderTarget.texture).__webglTexture = colorTexture;
30724	            properties.get(renderTarget.depthTexture).__webglTexture = depthTexture;
30725	            const renderTargetProperties = properties.get(renderTarget);
30726	            renderTargetProperties.__hasExternalTextures = true;
30727	            renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
30728	            if (!renderTargetProperties.__autoAllocateDepthBuffer) {
30729	                // The multisample_render_to_texture extension doesn't work properly if there
30730	                // are midframe flushes and an external depth buffer. Disable use of the extension.
30731	                if (extensions.has('WEBGL_multisampled_render_to_texture') === true) {
30732	                    console.warn('THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided');
30733	                    renderTargetProperties.__useRenderToTexture = false;
30734	                }
30735	            }
30736	        };
30737	        this.setRenderTargetFramebuffer = function(renderTarget, defaultFramebuffer) {
30738	            const renderTargetProperties = properties.get(renderTarget);
30739	            renderTargetProperties.__webglFramebuffer = defaultFramebuffer;
30740	            renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined;
30741	        };
30742	        const _scratchFrameBuffer = _gl.createFramebuffer();
30743	        this.setRenderTarget = function(renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) {
30744	            _currentRenderTarget = renderTarget;
30745	            _currentActiveCubeFace = activeCubeFace;
30746	            _currentActiveMipmapLevel = activeMipmapLevel;
30747	            let useDefaultFramebuffer = true;
30748	            let framebuffer = null;
30749	            let isCube = false;
vendor: 14,373 bytes, lines 30750-30977
30750	            let isRenderTarget3D = false;
30751	            if (renderTarget) {
30752	                const renderTargetProperties = properties.get(renderTarget);
30753	                if (renderTargetProperties.__useDefaultFramebuffer !== undefined) {
30754	                    // We need to make sure to rebind the framebuffer.
30755	                    state.bindFramebuffer(_gl.FRAMEBUFFER, null);
30756	                    useDefaultFramebuffer = false;
30757	                } else if (renderTargetProperties.__webglFramebuffer === undefined) {
30758	                    textures.setupRenderTarget(renderTarget);
30759	                } else if (renderTargetProperties.__hasExternalTextures) {
30760	                    // Color and depth texture must be rebound in order for the swapchain to update.
30761	                    textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture);
30762	                } else if (renderTarget.depthBuffer) {
30763	                    // check if the depth texture is already bound to the frame buffer and that it's been initialized
30764	                    const depthTexture = renderTarget.depthTexture;
30765	                    if (renderTargetProperties.__boundDepthTexture !== depthTexture) {
30766	                        // check if the depth texture is compatible
30767	                        if (depthTexture !== null && properties.has(depthTexture) && (renderTarget.width !== depthTexture.image.width || renderTarget.height !== depthTexture.image.height)) {
30768	                            throw new Error('WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.');
30769	                        }
30770	                        // Swap the depth buffer to the currently attached one
30771	                        textures.setupDepthRenderbuffer(renderTarget);
30772	                    }
30773	                }
30774	                const texture = renderTarget.texture;
30775	                if (texture.isData3DTexture || texture.isDataArrayTexture || texture.isCompressedArrayTexture) {
30776	                    isRenderTarget3D = true;
30777	                }
30778	                const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer;
30779	                if (renderTarget.isWebGLCubeRenderTarget) {
30780	                    if (Array.isArray(__webglFramebuffer[activeCubeFace])) {
30781	                        framebuffer = __webglFramebuffer[activeCubeFace][activeMipmapLevel];
30782	                    } else {
30783	                        framebuffer = __webglFramebuffer[activeCubeFace];
30784	                    }
30785	                    isCube = true;
30786	                } else if (renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) {
30787	                    framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer;
30788	                } else {
30789	                    if (Array.isArray(__webglFramebuffer)) {
30790	                        framebuffer = __webglFramebuffer[activeMipmapLevel];
30791	                    } else {
30792	                        framebuffer = __webglFramebuffer;
30793	                    }
30794	                }
30795	                _currentViewport.copy(renderTarget.viewport);
30796	                _currentScissor.copy(renderTarget.scissor);
30797	                _currentScissorTest = renderTarget.scissorTest;
30798	            } else {
30799	                _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor();
30800	                _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor();
30801	                _currentScissorTest = _scissorTest;
30802	            }
30803	            // Use a scratch frame buffer if rendering to a mip level to avoid depth buffers
30804	            // being bound that are different sizes.
30805	            if (activeMipmapLevel !== 0) {
30806	                framebuffer = _scratchFrameBuffer;
30807	            }
30808	            const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
30809	            if (framebufferBound && useDefaultFramebuffer) {
30810	                state.drawBuffers(renderTarget, framebuffer);
30811	            }
30812	            state.viewport(_currentViewport);
30813	            state.scissor(_currentScissor);
30814	            state.setScissorTest(_currentScissorTest);
30815	            if (isCube) {
30816	                const textureProperties = properties.get(renderTarget.texture);
30817	                _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel);
30818	            } else if (isRenderTarget3D) {
30819	                const textureProperties = properties.get(renderTarget.texture);
30820	                const layer = activeCubeFace;
30821	                _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel, layer);
30822	            } else if (renderTarget !== null && activeMipmapLevel !== 0) {
30823	                // Only bind the frame buffer if we are using a scratch frame buffer to render to a mipmap.
30824	                // If we rebind the texture when using a multi sample buffer then an error about inconsistent samples will be thrown.
30825	                const textureProperties = properties.get(renderTarget.texture);
30826	                _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, textureProperties.__webglTexture, activeMipmapLevel);
30827	            }
30828	            _currentMaterialId = -1; // reset current material to ensure correct uniform bindings
30829	        };
30830	        this.readRenderTargetPixels = function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) {
30831	            if (!(renderTarget && renderTarget.isWebGLRenderTarget)) {
30832	                console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.');
30833	                return;
30834	            }
30835	            let framebuffer = properties.get(renderTarget).__webglFramebuffer;
30836	            if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) {
30837	                framebuffer = framebuffer[activeCubeFaceIndex];
30838	            }
30839	            if (framebuffer) {
30840	                state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
30841	                try {
30842	                    const texture = renderTarget.texture;
30843	                    const textureFormat = texture.format;
30844	                    const textureType = texture.type;
30845	                    if (!capabilities.textureFormatReadable(textureFormat)) {
30846	                        console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.');
30847	                        return;
30848	                    }
30849	                    if (!capabilities.textureTypeReadable(textureType)) {
30850	                        console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.');
30851	                        return;
30852	                    }
30853	                    // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
30854	                    if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) {
30855	                        _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer);
30856	                    }
30857	                } finally{
30858	                    // restore framebuffer of current render target if necessary
30859	                    const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
30860	                    state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
30861	                }
30862	            }
30863	        };
30864	        this.readRenderTargetPixelsAsync = async function(renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) {
30865	            if (!(renderTarget && renderTarget.isWebGLRenderTarget)) {
30866	                throw new Error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.');
30867	            }
30868	            let framebuffer = properties.get(renderTarget).__webglFramebuffer;
30869	            if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) {
30870	                framebuffer = framebuffer[activeCubeFaceIndex];
30871	            }
30872	            if (framebuffer) {
30873	                const texture = renderTarget.texture;
30874	                const textureFormat = texture.format;
30875	                const textureType = texture.type;
30876	                if (!capabilities.textureFormatReadable(textureFormat)) {
30877	                    throw new Error('THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.');
30878	                }
30879	                if (!capabilities.textureTypeReadable(textureType)) {
30880	                    throw new Error('THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.');
30881	                }
30882	                // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
30883	                if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) {
30884	                    // set the active frame buffer to the one we want to read
30885	                    state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
30886	                    const glBuffer = _gl.createBuffer();
30887	                    _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer);
30888	                    _gl.bufferData(_gl.PIXEL_PACK_BUFFER, buffer.byteLength, _gl.STREAM_READ);
30889	                    _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), 0);
30890	                    // reset the frame buffer to the currently set buffer before waiting
30891	                    const currFramebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
30892	                    state.bindFramebuffer(_gl.FRAMEBUFFER, currFramebuffer);
30893	                    // check if the commands have finished every 8 ms
30894	                    const sync = _gl.fenceSync(_gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
30895	                    _gl.flush();
30896	                    await probeAsync(_gl, sync, 4);
30897	                    // read the data and delete the buffer
30898	                    _gl.bindBuffer(_gl.PIXEL_PACK_BUFFER, glBuffer);
30899	                    _gl.getBufferSubData(_gl.PIXEL_PACK_BUFFER, 0, buffer);
30900	                    _gl.deleteBuffer(glBuffer);
30901	                    _gl.deleteSync(sync);
30902	                    return buffer;
30903	                } else {
30904	                    throw new Error('THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.');
30905	                }
30906	            }
30907	        };
30908	        this.copyFramebufferToTexture = function(texture, position = null, level = 0) {
30909	            // support previous signature with position first
30910	            if (texture.isTexture !== true) {
30911	                // @deprecated, r165
30912	                warnOnce('WebGLRenderer: copyFramebufferToTexture function signature has changed.');
30913	                position = arguments[0] || null;
30914	                texture = arguments[1];
30915	            }
30916	            const levelScale = Math.pow(2, -level);
30917	            const width = Math.floor(texture.image.width * levelScale);
30918	            const height = Math.floor(texture.image.height * levelScale);
30919	            const x = position !== null ? position.x : 0;
30920	            const y = position !== null ? position.y : 0;
30921	            textures.setTexture2D(texture, 0);
30922	            _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, x, y, width, height);
30923	            state.unbindTexture();
30924	        };
30925	        const _srcFramebuffer = _gl.createFramebuffer();
30926	        const _dstFramebuffer = _gl.createFramebuffer();
30927	        this.copyTextureToTexture = function(srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = null) {
30928	            // support previous signature with dstPosition first
30929	            if (srcTexture.isTexture !== true) {
30930	                // @deprecated, r165
30931	                warnOnce('WebGLRenderer: copyTextureToTexture function signature has changed.');
30932	                dstPosition = arguments[0] || null;
30933	                srcTexture = arguments[1];
30934	                dstTexture = arguments[2];
30935	                dstLevel = arguments[3] || 0;
30936	                srcRegion = null;
30937	            }
30938	            // support the previous signature with just a single dst mipmap level
30939	            if (dstLevel === null) {
30940	                if (srcLevel !== 0) {
30941	                    // @deprecated, r171
30942	                    warnOnce('WebGLRenderer: copyTextureToTexture function signature has changed to support src and dst mipmap levels.');
30943	                    dstLevel = srcLevel;
30944	                    srcLevel = 0;
30945	                } else {
30946	                    dstLevel = 0;
30947	                }
30948	            }
30949	            // gather the necessary dimensions to copy
30950	            let width, height, depth, minX, minY, minZ;
30951	            let dstX, dstY, dstZ;
30952	            const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[dstLevel] : srcTexture.image;
30953	            if (srcRegion !== null) {
30954	                width = srcRegion.max.x - srcRegion.min.x;
30955	                height = srcRegion.max.y - srcRegion.min.y;
30956	                depth = srcRegion.isBox3 ? srcRegion.max.z - srcRegion.min.z : 1;
30957	                minX = srcRegion.min.x;
30958	                minY = srcRegion.min.y;
30959	                minZ = srcRegion.isBox3 ? srcRegion.min.z : 0;
30960	            } else {
30961	                const levelScale = Math.pow(2, -srcLevel);
30962	                width = Math.floor(image.width * levelScale);
30963	                height = Math.floor(image.height * levelScale);
30964	                if (srcTexture.isDataArrayTexture) {
30965	                    depth = image.depth;
30966	                } else if (srcTexture.isData3DTexture) {
30967	                    depth = Math.floor(image.depth * levelScale);
30968	                } else {
30969	                    depth = 1;
30970	                }
30971	                minX = 0;
30972	                minY = 0;
30973	                minZ = 0;
30974	            }
30975	            if (dstPosition !== null) {
30976	                dstX = dstPosition.x;
30977	                dstY = dstPosition.y;
vendor: 9,913 bytes, lines 30978-31142
30978	                dstZ = dstPosition.z;
30979	            } else {
30980	                dstX = 0;
30981	                dstY = 0;
30982	                dstZ = 0;
30983	            }
30984	            // Set up the destination target
30985	            const glFormat = utils.convert(dstTexture.format);
30986	            const glType = utils.convert(dstTexture.type);
30987	            let glTarget;
30988	            if (dstTexture.isData3DTexture) {
30989	                textures.setTexture3D(dstTexture, 0);
30990	                glTarget = _gl.TEXTURE_3D;
30991	            } else if (dstTexture.isDataArrayTexture || dstTexture.isCompressedArrayTexture) {
30992	                textures.setTexture2DArray(dstTexture, 0);
30993	                glTarget = _gl.TEXTURE_2D_ARRAY;
30994	            } else {
30995	                textures.setTexture2D(dstTexture, 0);
30996	                glTarget = _gl.TEXTURE_2D;
30997	            }
30998	            _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY);
30999	            _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha);
31000	            _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment);
31001	            // used for copying data from cpu
31002	            const currentUnpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH);
31003	            const currentUnpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT);
31004	            const currentUnpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS);
31005	            const currentUnpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS);
31006	            const currentUnpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES);
31007	            _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width);
31008	            _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height);
31009	            _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, minX);
31010	            _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, minY);
31011	            _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, minZ);
31012	            // set up the src texture
31013	            const isSrc3D = srcTexture.isDataArrayTexture || srcTexture.isData3DTexture;
31014	            const isDst3D = dstTexture.isDataArrayTexture || dstTexture.isData3DTexture;
31015	            if (srcTexture.isDepthTexture) {
31016	                const srcTextureProperties = properties.get(srcTexture);
31017	                const dstTextureProperties = properties.get(dstTexture);
31018	                const srcRenderTargetProperties = properties.get(srcTextureProperties.__renderTarget);
31019	                const dstRenderTargetProperties = properties.get(dstTextureProperties.__renderTarget);
31020	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, srcRenderTargetProperties.__webglFramebuffer);
31021	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, dstRenderTargetProperties.__webglFramebuffer);
31022	                for(let i = 0; i < depth; i++){
31023	                    // if the source or destination are a 3d target then a layer needs to be bound
31024	                    if (isSrc3D) {
31025	                        _gl.framebufferTextureLayer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(srcTexture).__webglTexture, srcLevel, minZ + i);
31026	                        _gl.framebufferTextureLayer(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, properties.get(dstTexture).__webglTexture, dstLevel, dstZ + i);
31027	                    }
31028	                    _gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, _gl.DEPTH_BUFFER_BIT, _gl.NEAREST);
31029	                }
31030	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null);
31031	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null);
31032	            } else if (srcLevel !== 0 || srcTexture.isRenderTargetTexture || properties.has(srcTexture)) {
31033	                // get the appropriate frame buffers
31034	                const srcTextureProperties = properties.get(srcTexture);
31035	                const dstTextureProperties = properties.get(dstTexture);
31036	                // bind the frame buffer targets
31037	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, _srcFramebuffer);
31038	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, _dstFramebuffer);
31039	                for(let i = 0; i < depth; i++){
31040	                    // assign the correct layers and mip maps to the frame buffers
31041	                    if (isSrc3D) {
31042	                        _gl.framebufferTextureLayer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, srcTextureProperties.__webglTexture, srcLevel, minZ + i);
31043	                    } else {
31044	                        _gl.framebufferTexture2D(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, srcTextureProperties.__webglTexture, srcLevel);
31045	                    }
31046	                    if (isDst3D) {
31047	                        _gl.framebufferTextureLayer(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, dstTextureProperties.__webglTexture, dstLevel, dstZ + i);
31048	                    } else {
31049	                        _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, dstTextureProperties.__webglTexture, dstLevel);
31050	                    }
31051	                    // copy the data using the fastest function that can achieve the copy
31052	                    if (srcLevel !== 0) {
31053	                        _gl.blitFramebuffer(minX, minY, width, height, dstX, dstY, width, height, _gl.COLOR_BUFFER_BIT, _gl.NEAREST);
31054	                    } else if (isDst3D) {
31055	                        _gl.copyTexSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ + i, minX, minY, width, height);
31056	                    } else {
31057	                        _gl.copyTexSubImage2D(glTarget, dstLevel, dstX, dstY, minX, minY, width, height);
31058	                    }
31059	                }
31060	                // unbind read, draw buffers
31061	                state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null);
31062	                state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null);
31063	            } else {
31064	                if (isDst3D) {
31065	                    // copy data into the 3d texture
31066	                    if (srcTexture.isDataTexture || srcTexture.isData3DTexture) {
31067	                        _gl.texSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data);
31068	                    } else if (dstTexture.isCompressedArrayTexture) {
31069	                        _gl.compressedTexSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, image.data);
31070	                    } else {
31071	                        _gl.texSubImage3D(glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image);
31072	                    }
31073	                } else {
31074	                    // copy data into the 2d texture
31075	                    if (srcTexture.isDataTexture) {
31076	                        _gl.texSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image.data);
31077	                    } else if (srcTexture.isCompressedTexture) {
31078	                        _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, image.width, image.height, glFormat, image.data);
31079	                    } else {
31080	                        _gl.texSubImage2D(_gl.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image);
31081	                    }
31082	                }
31083	            }
31084	            // reset values
31085	            _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, currentUnpackRowLen);
31086	            _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight);
31087	            _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels);
31088	            _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, currentUnpackSkipRows);
31089	            _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, currentUnpackSkipImages);
31090	            // Generate mipmaps only when copying level 0
31091	            if (dstLevel === 0 && dstTexture.generateMipmaps) {
31092	                _gl.generateMipmap(glTarget);
31093	            }
31094	            state.unbindTexture();
31095	        };
31096	        this.copyTextureToTexture3D = function(srcTexture, dstTexture, srcRegion = null, dstPosition = null, level = 0) {
31097	            // support previous signature with source box first
31098	            if (srcTexture.isTexture !== true) {
31099	                // @deprecated, r165
31100	                warnOnce('WebGLRenderer: copyTextureToTexture3D function signature has changed.');
31101	                srcRegion = arguments[0] || null;
31102	                dstPosition = arguments[1] || null;
31103	                srcTexture = arguments[2];
31104	                dstTexture = arguments[3];
31105	                level = arguments[4] || 0;
31106	            }
31107	            // @deprecated, r170
31108	            warnOnce('WebGLRenderer: copyTextureToTexture3D function has been deprecated. Use "copyTextureToTexture" instead.');
31109	            return this.copyTextureToTexture(srcTexture, dstTexture, srcRegion, dstPosition, level);
31110	        };
31111	        this.initRenderTarget = function(target) {
31112	            if (properties.get(target).__webglFramebuffer === undefined) {
31113	                textures.setupRenderTarget(target);
31114	            }
31115	        };
31116	        this.initTexture = function(texture) {
31117	            if (texture.isCubeTexture) {
31118	                textures.setTextureCube(texture, 0);
31119	            } else if (texture.isData3DTexture) {
31120	                textures.setTexture3D(texture, 0);
31121	            } else if (texture.isDataArrayTexture || texture.isCompressedArrayTexture) {
31122	                textures.setTexture2DArray(texture, 0);
31123	            } else {
31124	                textures.setTexture2D(texture, 0);
31125	            }
31126	            state.unbindTexture();
31127	        };
31128	        this.resetState = function() {
31129	            _currentActiveCubeFace = 0;
31130	            _currentActiveMipmapLevel = 0;
31131	            _currentRenderTarget = null;
31132	            state.reset();
31133	            bindingStates.reset();
31134	        };
31135	        if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
31136	            __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
31137	                detail: this
31138	            }));
31139	        }
31140	    }
31141	}
31142
vendor: 11,446 bytes, lines 31143-31409
31143	/**
31144	 * @license
31145	 * Copyright 2017 Google LLC
31146	 * SPDX-License-Identifier: BSD-3-Clause
31147	 */ var _t;
31148	const t$1 = globalThis, i$2 = t$1.trustedTypes, s = i$2 ? i$2.createPolicy("lit-html", {
31149	    createHTML: (t)=>t
31150	}) : void 0, e = "$lit$", h = `lit$${Math.random().toFixed(9).slice(2)}$`, o = "?" + h, n$1 = `<${o}>`, r$1 = document, l = ()=>r$1.createComment(""), c$1 = (t)=>null === t || "object" != typeof t && "function" != typeof t, a$1 = Array.isArray, u$1 = (t)=>a$1(t) || "function" == typeof t?.[Symbol.iterator], d = "[ \t\n\f\r]", f = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, v = /-->/g, _ = />/g, m = RegExp(`>|${d}(?:([^\\s"'>=/]+)(${d}*=${d}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`, "g"), p = /'/g, g$2 = /"/g, $ = /^(?:script|style|textarea|title)$/i, y = (t)=>(i, ...s)=>({
31151	            _$litType$: t,
31152	            strings: i,
31153	            values: s
31154	        }), x$1 = y(1), T$1 = Symbol.for("lit-noChange"), E = Symbol.for("lit-nothing"), A$1 = new WeakMap, C$2 = r$1.createTreeWalker(r$1, 129);
31155	function P(t, i) {
31156	    if (!a$1(t) || !t.hasOwnProperty("raw")) throw Error("invalid template strings array");
31157	    return void 0 !== s ? s.createHTML(i) : i;
31158	}
31159	const V = (t, i)=>{
31160	    const s = t.length - 1, o = [];
31161	    let r, l = 2 === i ? "<svg>" : 3 === i ? "<math>" : "", c = f;
31162	    for(let i = 0; i < s; i++){
31163	        const s = t[i];
31164	        let a, u, d = -1, y = 0;
31165	        for(; y < s.length && (c.lastIndex = y, u = c.exec(s), null !== u);)y = c.lastIndex, c === f ? "!--" === u[1] ? c = v : void 0 !== u[1] ? c = _ : void 0 !== u[2] ? ($.test(u[2]) && (r = RegExp("</" + u[2], "g")), c = m) : void 0 !== u[3] && (c = m) : c === m ? ">" === u[0] ? (c = r ?? f, d = -1) : void 0 === u[1] ? d = -2 : (d = c.lastIndex - u[2].length, a = u[1], c = void 0 === u[3] ? m : '"' === u[3] ? g$2 : p) : c === g$2 || c === p ? c = m : c === v || c === _ ? c = f : (c = m, r = void 0);
31166	        const x = c === m && t[i + 1].startsWith("/>") ? " " : "";
31167	        l += c === f ? s + n$1 : d >= 0 ? (o.push(a), s.slice(0, d) + e + s.slice(d) + h + x) : s + h + (-2 === d ? i : x);
31168	    }
31169	    return [
31170	        P(t, l + (t[s] || "<?>") + (2 === i ? "</svg>" : 3 === i ? "</math>" : "")),
31171	        o
31172	    ];
31173	};
31174	class N {
31175	    static createElement(t, i) {
31176	        const s = r$1.createElement("template");
31177	        return s.innerHTML = t, s;
31178	    }
31179	    constructor({ strings: t, _$litType$: s }, n){
31180	        let r;
31181	        this.parts = [];
31182	        let c = 0, a = 0;
31183	        const u = t.length - 1, d = this.parts, [f, v] = V(t, s);
31184	        if (this.el = N.createElement(f, n), C$2.currentNode = this.el.content, 2 === s || 3 === s) {
31185	            const t = this.el.content.firstChild;
31186	            t.replaceWith(...t.childNodes);
31187	        }
31188	        for(; null !== (r = C$2.nextNode()) && d.length < u;){
31189	            if (1 === r.nodeType) {
31190	                if (r.hasAttributes()) for (const t of r.getAttributeNames())if (t.endsWith(e)) {
31191	                    const i = v[a++], s = r.getAttribute(t).split(h), e = /([.?@])?(.*)/.exec(i);
31192	                    d.push({
31193	                        type: 1,
31194	                        index: c,
31195	                        name: e[2],
31196	                        strings: s,
31197	                        ctor: "." === e[1] ? H : "?" === e[1] ? I$1 : "@" === e[1] ? L : k
31198	                    }), r.removeAttribute(t);
31199	                } else t.startsWith(h) && (d.push({
31200	                    type: 6,
31201	                    index: c
31202	                }), r.removeAttribute(t));
31203	                if ($.test(r.tagName)) {
31204	                    const t = r.textContent.split(h), s = t.length - 1;
31205	                    if (s > 0) {
31206	                        r.textContent = i$2 ? i$2.emptyScript : "";
31207	                        for(let i = 0; i < s; i++)r.append(t[i], l()), C$2.nextNode(), d.push({
31208	                            type: 2,
31209	                            index: ++c
31210	                        });
31211	                        r.append(t[s], l());
31212	                    }
31213	                }
31214	            } else if (8 === r.nodeType) if (r.data === o) d.push({
31215	                type: 2,
31216	                index: c
31217	            });
31218	            else {
31219	                let t = -1;
31220	                for(; -1 !== (t = r.data.indexOf(h, t + 1));)d.push({
31221	                    type: 7,
31222	                    index: c
31223	                }), t += h.length - 1;
31224	            }
31225	            c++;
31226	        }
31227	    }
31228	}
31229	function S(t, i, s = t, e) {
31230	    var _s;
31231	    if (i === T$1) return i;
31232	    let h = void 0 !== e ? s._$Co?.[e] : s._$Cl;
31233	    const o = c$1(i) ? void 0 : i._$litDirective$;
31234	    return h?.constructor !== o && (h?._$AO?.(false), void 0 === o ? h = void 0 : (h = new o(t), h._$AT(t, s, e)), void 0 !== e ? ((_s = s)._$Co ?? (_s._$Co = []))[e] = h : s._$Cl = h), void 0 !== h && (i = S(t, h._$AS(t, i.values), h, e)), i;
31235	}
31236	class M {
31237	    get parentNode() {
31238	        return this._$AM.parentNode;
31239	    }
31240	    get _$AU() {
31241	        return this._$AM._$AU;
31242	    }
31243	    u(t) {
31244	        const { el: { content: i }, parts: s } = this._$AD, e = (t?.creationScope ?? r$1).importNode(i, true);
31245	        C$2.currentNode = e;
31246	        let h = C$2.nextNode(), o = 0, n = 0, l = s[0];
31247	        for(; void 0 !== l;){
31248	            if (o === l.index) {
31249	                let i;
31250	                2 === l.type ? i = new R$1(h, h.nextSibling, this, t) : 1 === l.type ? i = new l.ctor(h, l.name, l.strings, this, t) : 6 === l.type && (i = new z(h, this, t)), this._$AV.push(i), l = s[++n];
31251	            }
31252	            o !== l?.index && (h = C$2.nextNode(), o++);
31253	        }
31254	        return C$2.currentNode = r$1, e;
31255	    }
31256	    p(t) {
31257	        let i = 0;
31258	        for (const s of this._$AV) void 0 !== s && (void 0 !== s.strings ? (s._$AI(t, s, i), i += s.strings.length - 2) : s._$AI(t[i])), i++;
31259	    }
31260	    constructor(t, i){
31261	        this._$AV = [], this._$AN = void 0, this._$AD = t, this._$AM = i;
31262	    }
31263	}
31264	let R$1 = class R {
31265	    get _$AU() {
31266	        return this._$AM?._$AU ?? this._$Cv;
31267	    }
31268	    get parentNode() {
31269	        let t = this._$AA.parentNode;
31270	        const i = this._$AM;
31271	        return void 0 !== i && 11 === t?.nodeType && (t = i.parentNode), t;
31272	    }
31273	    get startNode() {
31274	        return this._$AA;
31275	    }
31276	    get endNode() {
31277	        return this._$AB;
31278	    }
31279	    _$AI(t, i = this) {
31280	        t = S(this, t, i), c$1(t) ? t === E || null == t || "" === t ? (this._$AH !== E && this._$AR(), this._$AH = E) : t !== this._$AH && t !== T$1 && this._(t) : void 0 !== t._$litType$ ? this.$(t) : void 0 !== t.nodeType ? this.T(t) : u$1(t) ? this.k(t) : this._(t);
31281	    }
31282	    O(t) {
31283	        return this._$AA.parentNode.insertBefore(t, this._$AB);
31284	    }
31285	    T(t) {
31286	        this._$AH !== t && (this._$AR(), this._$AH = this.O(t));
31287	    }
31288	    _(t) {
31289	        this._$AH !== E && c$1(this._$AH) ? this._$AA.nextSibling.data = t : this.T(r$1.createTextNode(t)), this._$AH = t;
31290	    }
31291	    $(t) {
31292	        const { values: i, _$litType$: s } = t, e = "number" == typeof s ? this._$AC(t) : (void 0 === s.el && (s.el = N.createElement(P(s.h, s.h[0]), this.options)), s);
31293	        if (this._$AH?._$AD === e) this._$AH.p(i);
31294	        else {
31295	            const t = new M(e, this), s = t.u(this.options);
31296	            t.p(i), this.T(s), this._$AH = t;
31297	        }
31298	    }
31299	    _$AC(t) {
31300	        let i = A$1.get(t.strings);
31301	        return void 0 === i && A$1.set(t.strings, i = new N(t)), i;
31302	    }
31303	    k(t) {
31304	        a$1(this._$AH) || (this._$AH = [], this._$AR());
31305	        const i = this._$AH;
31306	        let s, e = 0;
31307	        for (const h of t)e === i.length ? i.push(s = new R(this.O(l()), this.O(l()), this, this.options)) : s = i[e], s._$AI(h), e++;
31308	        e < i.length && (this._$AR(s && s._$AB.nextSibling, e), i.length = e);
31309	    }
31310	    _$AR(t = this._$AA.nextSibling, i) {
31311	        for(this._$AP?.(false, true, i); t && t !== this._$AB;){
31312	            const i = t.nextSibling;
31313	            t.remove(), t = i;
31314	        }
31315	    }
31316	    setConnected(t) {
31317	        void 0 === this._$AM && (this._$Cv = t, this._$AP?.(t));
31318	    }
31319	    constructor(t, i, s, e){
31320	        this.type = 2, this._$AH = E, this._$AN = void 0, this._$AA = t, this._$AB = i, this._$AM = s, this.options = e, this._$Cv = e?.isConnected ?? true;
31321	    }
31322	};
31323	class k {
31324	    get tagName() {
31325	        return this.element.tagName;
31326	    }
31327	    get _$AU() {
31328	        return this._$AM._$AU;
31329	    }
31330	    _$AI(t, i = this, s, e) {
31331	        const h = this.strings;
31332	        let o = false;
31333	        if (void 0 === h) t = S(this, t, i, 0), o = !c$1(t) || t !== this._$AH && t !== T$1, o && (this._$AH = t);
31334	        else {
31335	            const e = t;
31336	            let n, r;
31337	            for(t = h[0], n = 0; n < h.length - 1; n++)r = S(this, e[s + n], i, n), r === T$1 && (r = this._$AH[n]), o || (o = !c$1(r) || r !== this._$AH[n]), r === E ? t = E : t !== E && (t += (r ?? "") + h[n + 1]), this._$AH[n] = r;
31338	        }
31339	        o && !e && this.j(t);
31340	    }
31341	    j(t) {
31342	        t === E ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t ?? "");
31343	    }
31344	    constructor(t, i, s, e, h){
31345	        this.type = 1, this._$AH = E, this._$AN = void 0, this.element = t, this.name = i, this._$AM = e, this.options = h, s.length > 2 || "" !== s[0] || "" !== s[1] ? (this._$AH = Array(s.length - 1).fill(new String), this.strings = s) : this._$AH = E;
31346	    }
31347	}
31348	class H extends k {
31349	    j(t) {
31350	        this.element[this.name] = t === E ? void 0 : t;
31351	    }
31352	    constructor(){
31353	        super(...arguments), this.type = 3;
31354	    }
31355	}
31356	let I$1 = class I extends k {
31357	    j(t) {
31358	        this.element.toggleAttribute(this.name, !!t && t !== E);
31359	    }
31360	    constructor(){
31361	        super(...arguments), this.type = 4;
31362	    }
31363	};
31364	class L extends k {
31365	    _$AI(t, i = this) {
31366	        if ((t = S(this, t, i, 0) ?? E) === T$1) return;
31367	        const s = this._$AH, e = t === E && s !== E || t.capture !== s.capture || t.once !== s.once || t.passive !== s.passive, h = t !== E && (s === E || e);
31368	        e && this.element.removeEventListener(this.name, this, s), h && this.element.addEventListener(this.name, this, t), this._$AH = t;
31369	    }
31370	    handleEvent(t) {
31371	        "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t) : this._$AH.handleEvent(t);
31372	    }
31373	    constructor(t, i, s, e, h){
31374	        super(t, i, s, e, h), this.type = 5;
31375	    }
31376	}
31377	class z {
31378	    get _$AU() {
31379	        return this._$AM._$AU;
31380	    }
31381	    _$AI(t) {
31382	        S(this, t);
31383	    }
31384	    constructor(t, i, s){
31385	        this.element = t, this.type = 6, this._$AN = void 0, this._$AM = i, this.options = s;
31386	    }
31387	}
31388	const j = t$1.litHtmlPolyfillSupport;
31389	j?.(N, R$1), ((_t = t$1).litHtmlVersions ?? (_t.litHtmlVersions = [])).push("3.2.1");
31390	const B$1 = (t, i, s)=>{
31391	    const e = s?.renderBefore ?? i;
31392	    let h = e._$litPart$;
31393	    if (void 0 === h) {
31394	        const t = s?.renderBefore ?? null;
31395	        e._$litPart$ = h = new R$1(i.insertBefore(l(), t), t, void 0, s ?? {});
31396	    }
31397	    return h._$AI(t), h;
31398	};
31399
31400	var _globalThis;
31401	/**
31402	 * @license
31403	 * Copyright 2017 Google LLC
31404	 * SPDX-License-Identifier: BSD-3-Clause
31405	 */ class r extends b$1 {
31406	    createRenderRoot() {
31407	        var _this_renderOptions;
31408	        const t = super.createRenderRoot();
31409	        return (_this_renderOptions = this.renderOptions).renderBefore ?? (_this_renderOptions.renderBefore = t.firstChild), t;
vendor: 4,398 bytes, lines 31410-31467
31410	    }
31411	    update(t) {
31412	        const s = this.render();
31413	        this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t), this._$Do = B$1(s, this.renderRoot, this.renderOptions);
31414	    }
31415	    connectedCallback() {
31416	        super.connectedCallback(), this._$Do?.setConnected(true);
31417	    }
31418	    disconnectedCallback() {
31419	        super.disconnectedCallback(), this._$Do?.setConnected(false);
31420	    }
31421	    render() {
31422	        return T$1;
31423	    }
31424	    constructor(){
31425	        super(...arguments), this.renderOptions = {
31426	            host: this
31427	        }, this._$Do = void 0;
31428	    }
31429	}
31430	r._$litElement$ = true, r["finalized"] = true, globalThis.litElementHydrateSupport?.({
31431	    LitElement: r
31432	});
31433	const i$1 = globalThis.litElementPolyfillSupport;
31434	i$1?.({
31435	    LitElement: r
31436	});
31437	((_globalThis = globalThis).litElementVersions ?? (_globalThis.litElementVersions = [])).push("4.1.1");
31438
31439	const HAS_WEBXR_DEVICE_API = navigator.xr != null && self.XRSession != null && navigator.xr.isSessionSupported != null;
31440	const HAS_WEBXR_HIT_TEST_API = HAS_WEBXR_DEVICE_API && self.XRSession.prototype.requestHitTestSource != null;
31441	const HAS_RESIZE_OBSERVER = self.ResizeObserver != null;
31442	const HAS_INTERSECTION_OBSERVER = self.IntersectionObserver != null;
31443	const IS_WEBXR_AR_CANDIDATE = HAS_WEBXR_HIT_TEST_API;
31444	(()=>{
31445	    const userAgent = navigator.userAgent || navigator.vendor || self.opera;
31446	    let check = false;
31447	    if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4))) {
31448	        check = true;
31449	    }
31450	    return check;
31451	})();
31452	const IS_ANDROID = /android/i.test(navigator.userAgent);
31453	const IS_IOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !self.MSStream || navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1;
31454	const IS_FIREFOX = /firefox/i.test(navigator.userAgent);
31455	const IS_OCULUS = /OculusBrowser/.test(navigator.userAgent);
31456	const IS_SCENEVIEWER_CANDIDATE = IS_ANDROID && !IS_FIREFOX && !IS_OCULUS;
31457	const IS_WKWEBVIEW = Boolean(window.webkit && window.webkit.messageHandlers);
31458	const IS_AR_QUICKLOOK_CANDIDATE = (()=>{
31459	    if (IS_IOS) {
31460	        if (!IS_WKWEBVIEW) {
31461	            const tempAnchor = document.createElement('a');
31462	            return Boolean(tempAnchor.relList && tempAnchor.relList.supports && tempAnchor.relList.supports('ar'));
31463	        } else {
31464	            return Boolean(/CriOS\/|EdgiOS\/|FxiOS\/|GSA\/|DuckDuckGo\//.test(navigator.userAgent));
31465	        }
31466	    } else {
31467	        return false;
vendor: 4,727 bytes, lines 31468-31577
31468	    }
31469	})();
31470
31471	const deserializeUrl = (url)=>!!url && url !== 'null' ? toFullUrl(url) : null;
31472	const assertIsArCandidate = ()=>{
31473	    if (IS_WEBXR_AR_CANDIDATE) {
31474	        return;
31475	    }
31476	    const missingApis = [];
31477	    if (!HAS_WEBXR_DEVICE_API) {
31478	        missingApis.push('WebXR Device API');
31479	    }
31480	    if (!HAS_WEBXR_HIT_TEST_API) {
31481	        missingApis.push('WebXR Hit Test API');
31482	    }
31483	    throw new Error(`The following APIs are required for AR, but are missing in this browser: ${missingApis.join(', ')}`);
31484	};
31485	 const toFullUrl = (partialUrl)=>{
31486	    const url = new URL(partialUrl, window.location.toString());
31487	    return url.toString();
31488	};
31489	 const throttle = (fn, ms)=>{
31490	    let timer = null;
31491	    const throttled = (...args)=>{
31492	        if (timer != null) {
31493	            return;
31494	        }
31495	        fn(...args);
31496	        timer = self.setTimeout(()=>timer = null, ms);
31497	    };
31498	    throttled.flush = ()=>{
31499	        if (timer != null) {
31500	            self.clearTimeout(timer);
31501	            timer = null;
31502	        }
31503	    };
31504	    return throttled;
31505	};
31506	const debounce = (fn, ms)=>{
31507	    let timer = null;
31508	    return (...args)=>{
31509	        if (timer != null) {
31510	            self.clearTimeout(timer);
31511	        }
31512	        timer = self.setTimeout(()=>{
31513	            timer = null;
31514	            fn(...args);
31515	        }, ms);
31516	    };
31517	};
31518	 const clamp = (value, lowerLimit, upperLimit)=>Math.max(lowerLimit, Math.min(upperLimit, value));
31519	 const isDebugMode = (()=>{
31520	    const debugQueryParameterName = 'model-viewer-debug-mode';
31521	    const debugQueryParameter = new RegExp(`[?&]${debugQueryParameterName}(&|$)`);
31522	    return ()=>self.ModelViewerElement && self.ModelViewerElement.debugMode || self.location && self.location.search && self.location.search.match(debugQueryParameter);
31523	})();
31524	const timePasses = (ms = 0)=>new Promise((resolve)=>setTimeout(resolve, ms));
31525	 const waitForEvent = (target, eventName, predicate = null)=>new Promise((resolve)=>{
31526	        function handler(event) {
31527	            if (!predicate || predicate(event)) {
31528	                resolve(event);
31529	                target.removeEventListener(eventName, handler);
31530	            }
31531	        }
31532	        target.addEventListener(eventName, handler);
31533	    });
31534
31535	var __decorate$7 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
31536	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
31537	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
31538	    return c > 3 && r && Object.defineProperty(target, key, r), r;
31539	};
31540	const BASE_OPACITY = 0.5;
31541	const DEFAULT_SHADOW_INTENSITY = 0.0;
31542	const DEFAULT_SHADOW_SOFTNESS = 1.0;
31543	const DEFAULT_EXPOSURE = 1.0;
31544	const $currentEnvironmentMap = Symbol('currentEnvironmentMap');
31545	const $currentBackground = Symbol('currentBackground');
31546	const $updateEnvironment = Symbol('updateEnvironment');
31547	const $cancelEnvironmentUpdate = Symbol('cancelEnvironmentUpdate');
31548	const EnvironmentMixin = (ModelViewerElement)=>{
31549	    var _a, _b, _c;
31550	    class EnvironmentModelViewerElement extends ModelViewerElement {
31551	        updated(changedProperties) {
31552	            super.updated(changedProperties);
31553	            if (changedProperties.has('shadowIntensity')) {
31554	                this[$scene].setShadowIntensity(this.shadowIntensity * BASE_OPACITY);
31555	                this[$needsRender]();
31556	            }
31557	            if (changedProperties.has('shadowSoftness')) {
31558	                this[$scene].setShadowSoftness(this.shadowSoftness);
31559	                this[$needsRender]();
31560	            }
31561	            if (changedProperties.has('exposure')) {
31562	                this[$scene].exposure = this.exposure;
31563	                this[$needsRender]();
31564	            }
31565	            if (changedProperties.has('toneMapping')) {
31566	                this[$scene].toneMapping = this.toneMapping === 'aces' ? ACESFilmicToneMapping : this.toneMapping === 'agx' ? AgXToneMapping : this.toneMapping === 'reinhard' ? ReinhardToneMapping : this.toneMapping === 'cineon' ? CineonToneMapping : this.toneMapping === 'linear' ? LinearToneMapping : this.toneMapping === 'none' ? NoToneMapping : NeutralToneMapping;
31567	                this[$needsRender]();
31568	            }
31569	            if ((changedProperties.has('environmentImage') || changedProperties.has('skyboxImage')) && this[$shouldAttemptPreload]()) {
31570	                this[$updateEnvironment]();
31571	            }
31572	            if (changedProperties.has('skyboxHeight')) {
31573	                this[$scene].setGroundedSkybox();
31574	                this[$needsRender]();
31575	            }
31576	        }
31577	        hasBakedShadow() {
vendor: 4,358 bytes, lines 31578-31685
31578	            return this[$scene].bakedShadows.size > 0;
31579	        }
31580	        async [(_a = $currentEnvironmentMap, _b = $currentBackground, _c = $cancelEnvironmentUpdate, $updateEnvironment)]() {
31581	            const { skyboxImage, environmentImage } = this;
31582	            if (this[$cancelEnvironmentUpdate] != null) {
31583	                this[$cancelEnvironmentUpdate]();
31584	                this[$cancelEnvironmentUpdate] = null;
31585	            }
31586	            const { textureUtils } = this[$renderer];
31587	            if (textureUtils == null) {
31588	                return;
31589	            }
31590	            const updateEnvProgress = this[$progressTracker].beginActivity('environment-update');
31591	            try {
31592	                const { environmentMap, skybox } = await textureUtils.generateEnvironmentMapAndSkybox(deserializeUrl(skyboxImage), environmentImage, (progress)=>updateEnvProgress(clamp(progress, 0, 1)), this.withCredentials);
31593	                if (this[$currentEnvironmentMap] !== environmentMap) {
31594	                    this[$currentEnvironmentMap] = environmentMap;
31595	                    this.dispatchEvent(new CustomEvent('environment-change'));
31596	                }
31597	                if (skybox != null) {
31598	                    this[$currentBackground] = skybox.name === environmentMap.name ? environmentMap : skybox;
31599	                } else {
31600	                    this[$currentBackground] = null;
31601	                }
31602	                this[$scene].setEnvironmentAndSkybox(this[$currentEnvironmentMap], this[$currentBackground]);
31603	            } catch (errorOrPromise) {
31604	                if (errorOrPromise instanceof Error) {
31605	                    this[$scene].setEnvironmentAndSkybox(null, null);
31606	                    throw errorOrPromise;
31607	                }
31608	            } finally{
31609	                updateEnvProgress(1.0);
31610	            }
31611	        }
31612	        constructor(){
31613	            super(...arguments);
31614	            this.environmentImage = null;
31615	            this.skyboxImage = null;
31616	            this.shadowIntensity = DEFAULT_SHADOW_INTENSITY;
31617	            this.shadowSoftness = DEFAULT_SHADOW_SOFTNESS;
31618	            this.exposure = DEFAULT_EXPOSURE;
31619	            this.toneMapping = 'auto';
31620	            this.skyboxHeight = '0';
31621	            this[_a] = null;
31622	            this[_b] = null;
31623	            this[_c] = null;
31624	        }
31625	    }
31626	    __decorate$7([
31627	        n$2({
31628	            type: String,
31629	            attribute: 'environment-image'
31630	        })
31631	    ], EnvironmentModelViewerElement.prototype, "environmentImage", void 0);
31632	    __decorate$7([
31633	        n$2({
31634	            type: String,
31635	            attribute: 'skybox-image'
31636	        })
31637	    ], EnvironmentModelViewerElement.prototype, "skyboxImage", void 0);
31638	    __decorate$7([
31639	        n$2({
31640	            type: Number,
31641	            attribute: 'shadow-intensity'
31642	        })
31643	    ], EnvironmentModelViewerElement.prototype, "shadowIntensity", void 0);
31644	    __decorate$7([
31645	        n$2({
31646	            type: Number,
31647	            attribute: 'shadow-softness'
31648	        })
31649	    ], EnvironmentModelViewerElement.prototype, "shadowSoftness", void 0);
31650	    __decorate$7([
31651	        n$2({
31652	            type: Number
31653	        })
31654	    ], EnvironmentModelViewerElement.prototype, "exposure", void 0);
31655	    __decorate$7([
31656	        n$2({
31657	            type: String,
31658	            attribute: 'tone-mapping'
31659	        })
31660	    ], EnvironmentModelViewerElement.prototype, "toneMapping", void 0);
31661	    __decorate$7([
31662	        n$2({
31663	            type: String,
31664	            attribute: 'skybox-height'
31665	        })
31666	    ], EnvironmentModelViewerElement.prototype, "skyboxHeight", void 0);
31667	    return EnvironmentModelViewerElement;
31668	};
31669
31670	var CloseIcon = x$1`
31671<svg xmlns="http://www.w3.org/2000/svg" width="24px" height="24px" viewBox="0 0 24 24" fill="#000000">
31672    <!-- NOTE(cdata): This SVG filter is a stop-gap until we can implement
31673         support for dynamic re-coloring of UI components -->
31674    <defs>
31675      <filter id="drop-shadow" x="-100%" y="-100%" width="300%" height="300%">
31676        <feGaussianBlur in="SourceAlpha" stdDeviation="1"/>
31677        <feOffset dx="0" dy="0" result="offsetblur"/>
31678        <feFlood flood-color="#000000"/>
31679        <feComposite in2="offsetblur" operator="in"/>
31680        <feMerge>
31681          <feMergeNode/>
31682          <feMergeNode in="SourceGraphic"/>
31683        </feMerge>
31684      </filter>
31685    </defs>
31686    <path filter="url(#drop-shadow)" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
31687    <path d="M0 0h24v24H0z" fill="none"/>
31688</svg>`;
31689
31690	var ControlsPrompt = x$1`
31691<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="36">
31692    <defs>
31693        <path id="A" d="M.001.232h24.997V36H.001z" />
31694    </defs>
31695    <g transform="translate(-11 -4)" fill="none" fill-rule="evenodd">
31696        <path fill-opacity="0" fill="#fff" d="M0 0h44v44H0z" />
31697        <g transform="translate(11 3)">
31698            <path d="M8.733 11.165c.04-1.108.766-2.027 1.743-2.307a2.54 2.54 0 0 1 .628-.089c.16 0 .314.017.463.044 1.088.2 1.9 1.092 1.9 2.16v8.88h1.26c2.943-1.39 5-4.45 5-8.025a9.01 9.01 0 0 0-1.9-5.56l-.43-.5c-.765-.838-1.683-1.522-2.712-2-1.057-.49-2.226-.77-3.46-.77s-2.4.278-3.46.77c-1.03.478-1.947 1.162-2.71 2l-.43.5a9.01 9.01 0 0 0-1.9 5.56 9.04 9.04 0 0 0 .094 1.305c.03.21.088.41.13.617l.136.624c.083.286.196.56.305.832l.124.333a8.78 8.78 0 0 0 .509.953l.065.122a8.69 8.69 0 0 0 3.521 3.191l1.11.537v-9.178z" fill-opacity=".5" fill="#e4e4e4" />
31699            <path d="M22.94 26.218l-2.76 7.74c-.172.485-.676.8-1.253.8H12.24c-1.606 0-3.092-.68-3.98-1.82-1.592-2.048-3.647-3.822-6.11-5.27-.095-.055-.15-.137-.152-.23-.004-.1.046-.196.193-.297.56-.393 1.234-.6 1.926-.6a3.43 3.43 0 0 1 .691.069l4.922.994V10.972c0-.663.615-1.203 1.37-1.203s1.373.54 1.373 1.203v9.882h2.953c.273 0 .533.073.757.21l6.257 3.874c.027.017.045.042.07.06.41.296.586.77.426 1.22M4.1 16.614c-.024-.04-.042-.083-.065-.122a8.69 8.69 0 0 1-.509-.953c-.048-.107-.08-.223-.124-.333l-.305-.832c-.058-.202-.09-.416-.136-.624l-.13-.617a9.03 9.03 0 0 1-.094-1.305c0-2.107.714-4.04 1.9-5.56l.43-.5c.764-.84 1.682-1.523 2.71-2 1.058-.49 2.226-.77 3.46-.77s2.402.28 3.46.77c1.03.477 1.947 1.16 2.712 2l.428.5a9 9 0 0 1 1.901 5.559c0 3.577-2.056 6.636-5 8.026h-1.26v-8.882c0-1.067-.822-1.96-1.9-2.16-.15-.028-.304-.044-.463-.044-.22 0-.427.037-.628.09-.977.28-1.703 1.198-1.743 2.306v9.178l-1.11-.537C6.18 19.098 4.96 18 4.1 16.614M22.97 24.09l-6.256-3.874c-.102-.063-.218-.098-.33-.144 2.683-1.8 4.354-4.855 4.354-8.243 0-.486-.037-.964-.104-1.43a9.97 9.97 0 0 0-1.57-4.128l-.295-.408-.066-.092a10.05 10.05 0 0 0-.949-1.078c-.342-.334-.708-.643-1.094-.922-1.155-.834-2.492-1.412-3.94-1.65l-.732-.088-.748-.03a9.29 9.29 0 0 0-1.482.119c-1.447.238-2.786.816-3.94 1.65a9.33 9.33 0 0 0-.813.686 9.59 9.59 0 0 0-.845.877l-.385.437-.36.5-.288.468-.418.778-.04.09c-.593 1.28-.93 2.71-.93 4.222 0 3.832 2.182 7.342 5.56 8.938l1.437.68v4.946L5 25.64a4.44 4.44 0 0 0-.888-.086c-.017 0-.034.003-.05.003-.252.004-.503.033-.75.08a5.08 5.08 0 0 0-.237.056c-.193.046-.382.107-.568.18-.075.03-.15.057-.225.1-.25.114-.494.244-.723.405a1.31 1.31 0 0 0-.566 1.122 1.28 1.28 0 0 0 .645 1.051C4 29.925 5.96 31.614 7.473 33.563a5.06 5.06 0 0 0 .434.491c1.086 1.082 2.656 1.713 4.326 1.715h6.697c.748-.001 1.43-.333 1.858-.872.142-.18.256-.38.336-.602l2.757-7.74c.094-.26.13-.53.112-.794s-.088-.52-.203-.76a2.19 2.19 0 0 0-.821-.91" fill-opacity=".6" fill="#000" />
31700            <path d="M22.444 24.94l-6.257-3.874a1.45 1.45 0 0 0-.757-.211h-2.953v-9.88c0-.663-.616-1.203-1.373-1.203s-1.37.54-1.37 1.203v16.643l-4.922-.994a3.44 3.44 0 0 0-.692-.069 3.35 3.35 0 0 0-1.925.598c-.147.102-.198.198-.194.298.004.094.058.176.153.23 2.462 1.448 4.517 3.22 6.11 5.27.887 1.14 2.373 1.82 3.98 1.82h6.686c.577 0 1.08-.326 1.253-.8l2.76-7.74c.16-.448-.017-.923-.426-1.22-.025-.02-.043-.043-.07-.06z" fill="#fff" />
31701            <g transform="translate(0 .769)">
31702                <mask id="B" fill="#fff">
31703                    <use xlink:href="#A" />
31704                </mask>
31705                <path d="M23.993 24.992a1.96 1.96 0 0 1-.111.794l-2.758 7.74c-.08.22-.194.423-.336.602-.427.54-1.11.87-1.857.872h-6.698c-1.67-.002-3.24-.633-4.326-1.715-.154-.154-.3-.318-.434-.49C5.96 30.846 4 29.157 1.646 27.773c-.385-.225-.626-.618-.645-1.05a1.31 1.31 0 0 1 .566-1.122 4.56 4.56 0 0 1 .723-.405l.225-.1a4.3 4.3 0 0 1 .568-.18l.237-.056c.248-.046.5-.075.75-.08.018 0 .034-.003.05-.003.303-.001.597.027.89.086l3.722.752V20.68l-1.436-.68c-3.377-1.596-5.56-5.106-5.56-8.938 0-1.51.336-2.94.93-4.222.015-.03.025-.06.
3170504-.09.127-.267.268-.525.418-.778.093-.16.186-.316.288-.468.063-.095.133-.186.2-.277L3.773 5c.118-.155.26-.29.385-.437.266-.3.544-.604.845-.877a9.33 9.33 0 0 1 .813-.686C6.97 2.167 8.31 1.59 9.757 1.35a9.27 9.27 0 0 1 1.481-.119 8.82 8.82 0 0 1 .748.031c.247.02.49.05.733.088 1.448.238 2.786.816 3.94 1.65.387.28.752.588 1.094.922a9.94 9.94 0 0 1 .949 1.078l.066.092c.102.133.203.268.295.408a9.97 9.97 0 0 1 1.571 4.128c.066.467.103.945.103 1.43 0 3.388-1.67 6.453-4.353 8.243.11.046.227.08.33.144l6.256 3.874c.37.23.645.55.82.9.115.24.185.498.203.76m.697-1.195c-.265-.55-.677-1.007-1.194-1.326l-5.323-3.297c2.255-2.037 3.564-4.97 3.564-8.114 0-2.19-.637-4.304-1.84-6.114-.126-.188-.26-.37-.4-.552-.645-.848-1.402-1.6-2.252-2.204C15.472.91 13.393.232 11.238.232A10.21 10.21 0 0 0 5.23 2.19c-.848.614-1.606 1.356-2.253 2.205-.136.18-.272.363-.398.55C1.374 6.756.737 8.87.737 11.06c0 4.218 2.407 8.08 6.133 9.842l.863.41v3.092l-2.525-.51c-.356-.07-.717-.106-1.076-.106a5.45 5.45 0 0 0-3.14.996c-.653.46-1.022 1.202-.99 1.983a2.28 2.28 0 0 0 1.138 1.872c2.24 1.318 4.106 2.923 5.543 4.772 1.26 1.62 3.333 2.59 5.55 2.592h6.698c1.42-.001 2.68-.86 3.134-2.138l2.76-7.74c.272-.757.224-1.584-.134-2.325" fill-opacity=".05" fill="#000" mask="url(#B)" />
31706            </g>
31707        </g>
31708    </g>
31709</svg>`;
31710
31711	var ARGlyph = x$1`
31712<svg version="1.1" id="view_x5F_in_x5F_AR_x5F_icon"
31713	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="24px"
31714	 viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
31715<rect id="Bounding_Box" x="0" y="0" fill="none" width="24" height="24"/>
31716<g id="Art_layer">
31717	<path d="M3,4c0-0.55,0.45-1,1-1h2V1H4C2.35,1,1,2.35,1,4v2h2V4z"/>
31718	<path d="M20,3c0.55,0,1,0.45,1,1v2h2V4c0-1.65-1.35-3-3-3h-2v2H20z"/>
31719	<path d="M4,21c-0.55,0-1-0.45-1-1v-2H1v2c0,1.65,1.35,3,3,3h2v-2H4z"/>
31720	<path d="M20,21c0.55,0,1-0.45,1-1v-2h2v2c0,1.65-1.35,3-3,3h-2v-2H20z"/>
31721	<g>
31722		<path d="M18.25,7.6l-5.5-3.18c-0.46-0.27-1.04-0.27-1.5,0L5.75,7.6C5.29,7.87,5,8.36,5,8.9v6.35c0,0.54,0.29,1.03,0.75,1.3
31723			l5.5,3.18c0.46,0.27,1.04,0.27,1.5,0l5.5-3.18c0.46-0.27,0.75-0.76,0.75-1.3V8.9C19,8.36,18.71,7.87,18.25,7.6z M7,14.96v-4.62
31724			l4,2.32v4.61L7,14.96z M12,10.93L8,8.61l4-2.31l4,2.31L12,10.93z M13,17.27v-4.61l4-2.32v4.62L13,17.27z"/>
31725	</g>
31726</g>
31727</svg>`;
31728
31729	const templateResult = x$1`
31730<style>
31731:host {
31732  display: block;
31733  position: relative;
31734  contain: strict;
31735  width: 300px;
31736  height: 150px;
31737}
31738
31739.container {
31740  position: relative;
31741  overflow: hidden;
31742}
31743
31744.userInput {
31745  width: 100%;
31746  height: 100%;
31747  display: none;
31748  position: relative;
31749  outline-offset: -1px;
31750  outline-width: 1px;
31751}
31752
31753canvas {
31754  position: absolute;
31755  display: none;
31756  pointer-events: none;
31757  /* NOTE(cdata): Chrome 76 and below apparently have a bug
31758   * that causes our canvas not to display pixels unless it is
31759   * on its own render layer
31760   * @see https://github.com/google/model-viewer/pull/755#issuecomment-536597893
31761   */
31762  transform: translateZ(0);
31763}
31764
31765.show {
31766  display: block;
31767}
31768
31769/* Adapted from HTML5 Boilerplate
31770 *
31771 * @see https://github.com/h5bp/html5-boilerplate/blob/ceb4620c78fc82e13534fc44202a3f168754873f/dist/css/main.css#L122-L133 */
31772.screen-reader-only {
31773  border: 0;
31774  left: 0;
31775  top: 0;
31776  clip: rect(0, 0, 0, 0);
31777  height: 1px;
31778  margin: -1px;
31779  overflow: hidden;
31780  padding: 0;
31781  position: absolute;
31782  white-space: nowrap;
31783  width: 1px;
31784  pointer-events: none;
31785}
31786
31787.slot {
31788  position: absolute;
31789  pointer-events: none;
31790  top: 0;
31791  left: 0;
31792  width: 100%;
31793  height: 100%;
31794}
31795
31796.slot > * {
31797  pointer-events: initial;
31798}
31799
31800.annotation-wrapper ::slotted(*) {
31801  opacity: var(--max-hotspot-opacity, 1);
31802  transition: opacity 0.3s;
31803}
31804
31805.pointer-tumbling .annotation-wrapper ::slotted(*) {
31806  pointer-events: none;
31807}
31808
31809.annotation-wrapper ::slotted(*) {
31810  pointer-events: initial;
31811}
31812
31813.annotation-wrapper.hide ::slotted(*) {
31814  opacity: var(--min-hotspot-opacity, 0.25);
31815}
31816
31817.slot.poster {
31818  display: none;
31819  background-color: inherit;
31820}
31821
31822.slot.poster.show {
31823  display: inherit;
31824}
31825
31826.slot.poster > * {
31827  pointer-events: initial;
31828}
31829
31830.slot.poster:not(.show) > * {
31831  pointer-events: none;
31832}
31833
31834#default-poster {
31835  width: 100%;
31836  height: 100%;
31837  /* The default poster is a <button> so we need to set display
31838   * to prevent it from being affected by text-align: */
31839  display: block;
31840  position: absolute;
31841  border: none;
31842  padding: 0;
31843  background-size: contain;
31844  background-repeat: no-repeat;
31845  background-position: center;
31846  background-color: #fff0;
31847}
31848
31849#default-progress-bar {
31850  display: block;
31851  position: relative;
31852  width: 100%;
31853  height: 100%;
31854  pointer-events: none;
31855  overflow: hidden;
31856}
31857
31858#default-progress-bar > .bar {
31859  position: absolute;
31860  top: 0;
31861  left: 0;
31862  width: 100%;
31863  height: var(--progress-bar-height, 5px);
31864  background-color: var(--progress-bar-color, rgba(0, 0, 0, 0.4));
31865  transition: transform 0.09s;
31866  transform-origin: top left;
31867  transform: scaleX(0);
31868  overflow: hidden;
31869}
31870
31871#default-progress-bar > .bar.hide {
31872  transition: opacity 0.3s 1s;
31873  opacity: 0;
31874}
31875
31876.centered {
31877  align-items: center;
31878  justify-content: center;
31879}
31880
31881.cover {
31882  position: absolute;
31883  top: 0;
31884  left: 0;
31885  width: 100%;
31886  height: 100%;
31887  pointer-events: none;
31888}
31889
31890.slot.interaction-prompt {
31891  display: var(--interaction-prompt-display, flex);
31892  overflow: hidden;
31893  opacity: 0;
31894  will-change: opacity;
31895  transition: opacity 0.3s;
31896}
31897
31898.slot.interaction-prompt.visible {
31899  opacity: 1;
31900}
31901
31902.animated-container {
31903  will-change: transform, opacity;
31904  opacity: 0;
31905  transition: opacity 0.3s;
31906}
31907
31908.slot.interaction-prompt > * {
31909  pointer-events: none;
31910}
31911
31912.slot.ar-button {
31913  -moz-user-select: none;
31914  -webkit-tap-highlight-color: transparent;
31915  user-select: none;
31916
31917  display: var(--ar-button-display, block);
31918}
31919
31920.slot.ar-button:not(.enabled) {
31921  display: none;
31922}
31923
31924.fab {
31925  display: flex;
31926  align-items: center;
31927  justify-content: center;
31928  box-sizing: border-box;
31929  width: 40px;
31930  height: 40px;
31931  cursor: pointer;
31932  background-color: #fff;
31933  box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.15);
31934  border-radius: 100px;
31935}
31936
31937.fab > * {
31938  opacity: 0.87;
31939}
31940
31941#default-ar-button {
31942  position: absolute;
31943  bottom: 16px;
31944  right: 16px;
31945  transform: scale(var(--ar-button-scale, 1));
31946  transform-origin: bottom right;
31947}
31948
31949.slot.pan-target {
31950  display: block;
31951  position: absolute;
31952  width: 0;
31953  height: 0;
31954  left: 50%;
31955  top: 50%;
31956  transform: translate3d(-50%, -50%, 0);
31957  background-color: transparent;
31958  opacity: 0;
31959  transition: opacity 0.3s;
31960}
31961
31962#default-pan-target {
31963  width: 6px;
31964  height: 6px;
31965  border-radius: 6px;
31966  border: 1px solid white;
31967  box-shadow: 0px 0px 2px 1px rgba(0, 0, 0, 0.8);
31968}
31969
31970.slot.default {
31971  pointer-events: none;
31972}
31973
31974.slot.progress-bar {
31975  pointer-events: none;
31976}
31977
31978.slot.exit-webxr-ar-button {
31979  pointer-events: none;
31980}
31981
31982.slot.exit-webxr-ar-button:not(.enabled) {
31983  display: none;
31984}
31985
31986#default-exit-webxr-ar-button {
31987  display: flex;
31988  align-items: center;
31989  justify-content: center;
31990  position: absolute;
31991  top: env(safe-area-inset-top, 16px);
31992  right: 16px;
31993  width: 40px;
31994  height: 40px;
31995  box-sizing: border-box;
31996}
31997
31998#default-exit-webxr-ar-button > svg {
31999  fill: #fff;
32000}
32001</style>
32002<div class="container">
32003  <div class="userInput" tabindex="0" role="img"
32004      aria-label="3D model">
32005      <div class="slot canvas">
32006        <slot name="canvas">
32007          <canvas></canvas>
32008        </slot>
32009      </div>
32010
32011  </div>
32012
32013  <!-- NOTE(cdata): We need to wrap slots because browsers without ShadowDOM
32014        will have their <slot> elements removed by ShadyCSS -->
32015  <div class="slot poster">
32016    <slot name="poster">
32017      <button type="button" id="default-poster" aria-hidden="true" aria-label="Loading 3D model"></button>
32018    </slot>
32019  </div>
32020
32021  <div class="slot ar-button">
32022    <slot name="ar-button">
32023      <a id="default-ar-button" part="default-ar-button" class="fab"
32024          tabindex="2"
32025          role="button"
32026          href="javascript:void(0);"
32027          aria-label="View in your space">
32028        ${ARGlyph}
32029      </a>
32030    </slot>
32031  </div>
32032
32033  <div class="slot pan-target">
32034    <slot name="pan-target">
32035      <div id="default-pan-target">
32036      </div>
32037    </slot>
32038  </div>
32039
32040  <div class="slot interaction-prompt cover centered">
32041    <div id="prompt" class="animated-container">
32042      <slot name="interaction-prompt" aria-hidden="true">
32043        ${ControlsPrompt}
32044      </slot>
32045    </div>
32046  </div>
32047
32048  <div id="finger0" class="animated-container cover">
32049    <slot name="finger0" aria-hidden="true">
32050    </slot>
32051  </div>
32052  <div id="finger1" class="animated-container cover">
32053    <slot name="finger1" aria-hidden="true">
32054    </slot>
32055  </div>
32056
32057  <div class="slot default">
32058    <slot></slot>
32059
32060    <div class="slot progress-bar">
32061      <slot name="progress-bar">
32062        <div id="default-progress-bar" aria-hidden="true">
32063          <div class="bar" part="default-progress-bar"></div>
32064        </div>
32065      </slot>
32066    </div>
32067
32068    <div class="slot exit-webxr-ar-button">
32069      <slot name="exit-webxr-ar-button">
32070        <a id="default-exit-webxr-ar-button" part="default-exit-webxr-ar-button"
32071            tabindex="3"
32072            aria-label="Exit AR"
32073            aria-hidden="true">
32074          ${CloseIcon}
32075        </a>
32076      </slot>
32077    </div>
32078  </div>
32079</div>
32080<div class="screen-reader-only" role="region" aria-label="Live announcements">
32081  <span id="status" role="status"></span>
32082</div>`;
32083	const makeTemplate = (shadowRoot)=>{
32084	    B$1(templateResult, shadowRoot);
32085	};
32086
32087	// This file is part of meshoptimizer library and is distributed under the terms of MIT License.
32088	// Copyright (C) 2016-2022, by Arseny Kapoulkine ([email protected])
32089	var MeshoptDecoder = function() {
32090	    // Built with clang version 14.0.4
32091	    // Built from meshoptimizer 0.18
32092	    var wasm_base = "b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuikqbeeedddillviebeoweuec:q;iekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbol79IV9Rbrq:P8Yqdbk;3sezu8Jjjjjbcj;eb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Radz1jjjbhwcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhDcbhqinaqae9pmeaDaeaq9RaqaDfae6Egkcsfgocl4cifcd4hxdndndndnaoc9WGgmTmbcbhPcehsawcjdfhzalhHinaraH9Rax6midnaraHaxfgl9RcK6mbczhoinawcj;cbfaogifgoc9WfhOdndndndndnaHaic9WfgAco4fRbbaAci4coG4ciGPlbedibkaO9cb83ibaOcwf9cb83ibxikaOalRblalRbbgAco4gCaCciSgCE86bbaocGfalclfaCfgORbbaAcl4ciGgCaCciSgCE86bbaocVfaOaCfgORbbaAcd4ciGgCaCciSgCE86bbaoc7faOaCfgORbbaAciGgAaAciSgAE86bbaoctfaOaAfgARbbalRbegOco4gCaCciSgCE86bbaoc91faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc4faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc93faAaCfgARbbaOciGgOaOciSgOE86bbaoc94faAaOfgARbbalRbdgOco4gCaCciSgCE86bbaoc95faAaCfgARbbaOcl4ciGgCaCciSgCE86bbaoc96faAaCfgARbbaOcd4ciGgCaCciSgCE86bbaoc97faAaCfgARbbaOciGgOaOciSgOE86bbaoc98faAaOfgORbbalRbiglco4gAaAciSgAE86bbaoc99faOaAfgORbbalcl4ciGgAaAciSgAE86bbaoc9:faOaAfgORbbalcd4ciGgAaAciSgAE86bbaocufaOaAfgoRbbalciGglalciSglE86bbaoalfhlxdkaOalRbwalRbbgAcl4gCaCcsSgCE86bbaocGfalcwfaCfgORbbaAcsGgAaAcsSgAE86bbaocVfaOaAfgORbbalRbegAcl4gCaCcsSgCE86bbaoc7faOaCfgORbbaAcsGgAaAcsSgAE86bbaoctfaOaAfgORbbalRbdgAcl4gCaCcsSgCE86bbaoc91faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc4faOaAfgORbbalRbigAcl4gCaCcsSgCE86bbaoc93faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc94faOaAfgORbbalRblgAcl4gCaCcsSgCE86bbaoc95faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc96faOaAfgORbbalRbvgAcl4gCaCcsSgCE86bbaoc97faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc98faOaAfgORbbalRbogAcl4gCaCcsSgCE86bbaoc99faOaCfgORbbaAcsGgAaAcsSgAE86bbaoc9:faOaAfgORbbalRbrglcl4gAaAcsSgAE86bbaocufaOaAfgoRbbalcsGglalcsSglE86bbaoalfhlxekaOal8Pbb83bbaOcwfalcwf8Pbb83bbalczfhlkdnaiam9pmbaiczfhoaral9RcL0mekkaiam6mialTmidnakTmbawaPfRbbhOcbhoazhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkkazcefhzaPcefgPad6hsalhHaPad9hmexvkkcbhlasceGmdxikalaxad2fhCdnakTmbcbhHcehsawcjdfhminaral9Rax6mialTmdalaxfhlawaHfRbbhOcbhoamhiinaiawcj;cbfaofRbbgAce4cbaAceG9R7aOfgO86bbaiadfhiaocefgoak9hmbkamcefhmaHcefgHad6hsaHad9hmbkaChlxikcbhocehsinaral9Rax6mdalTmealaxfhlaocefgoad6hsadao9hmbkaChlxdkcbhlasceGTmekc9:hoxikabaqad2fawcjdfakad2z1jjjb8Aawawcjdfakcufad2fadz1jjjb8Aakaqfhqalmbkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;ebf8Kjjjjbaok;yzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:jjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarc
32092dfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk;siliui99iue99dnaeTmbcbhiabhlindndnJ;Zl81Zalcof8UebgvciV:Y:vgoal8Ueb:YNgrJb;:FSNJbbbZJbbb:;arJbbbb9GEMgw:lJbbb9p9DTmbaw:OhDxekcjjjj94hDkalclf8Uebhqalcdf8UebhkabavcefciGaiVcetfaD87ebdndnaoak:YNgwJb;:FSNJbbbZJbbb:;awJbbbb9GEMgx:lJbbb9p9DTmbax:Ohkxekcjjjj94hkkabavcdfciGaiVcetfak87ebdndnaoaq:YNgoJb;:FSNJbbbZJbbb:;aoJbbbb9GEMgx:lJbbb9p9DTmbax:Ohqxekcjjjj94hqkabavcufciGaiVcetfaq87ebdndnJbbjZararN:tawawN:taoaoN:tgrJbbbbarJbbbb9GE:rJb;:FSNJbbbZMgr:lJbbb9p9DTmbar:Ohqxekcjjjj94hqkabavciGaiVcetfaq87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2geTmbinababydbgdcwtcw91:Yadce91cjjj;8ifcjjj98G::NUdbabclfhbaecufgembkkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;LeeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiclfaeclfydbBdbaicwfaecwfydbBdbaicxfaecxfydbBdbaiczfhiaeczfheadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk;aeedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdbaicxfalBdbaicwfalBdbaiclfalBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkkkebcjwklz9Kbb";
32093	    var wasm_simd = 
vendor: 12,055 bytes, line 32093
32093"b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuikqbbebeedddilve9Weeeviebeoweuec:q;Aekr;leDo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949Wbwl79IV9RbDq;t9tqlbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk;h8JlHud97euo978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnadcefal0mbcuhoaiRbbc:Ge9hmbavaialfgrad9Rad;8qbbcj;abad9UhoaicefhldnadTmbaoc;WFbGgocjdaocjd6EhwcbhDinaDae9pmeawaeaD9RaDawfae6Egqcsfgoc9WGgkci2hxakcethmaocl4cifcd4hPabaDad2fhscbhzdnincehHalhOcbhAdninaraO9RaP6miavcj;cbfaAak2fhCaOaPfhlcbhidnakc;ab6mbaral9Rc;Gb6mbcbhoinaCaofhidndndndndnaOaoco4fRbbgXciGPlbedibkaipxbbbbbbbbbbbbbbbbpklbxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklbalczfhlkdndndndndnaXcd4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklzxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklzalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklzalczfhlkdndndndndnaXcl4ciGPlbedibkaipxbbbbbbbbbbbbbbbbpklaxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklaalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaialpbbbpklaalczfhlkdndndndndnaXco4Plbedibkaipxbbbbbbbbbbbbbbbbpkl8WxikaialpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalclfaYpQbfaXc:q:yjjbfRbbfhlxdkaialpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibaXc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgXcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spkl8WalcwfaYpQbfaXc:q:yjjbfRbbfhlxekaialpbbbpkl8Walczfhlkaoc;abfhiaocjefak0meaihoaral9Rc;Fb0mbkkdndnaiak9pmbaici4hoinaral9RcK6mdaCaifhXdndndndndnaOaico4fRbbaocoG4ciGPlbedibkaXpxbbbbbbbbbbbbbbbbpklbxikaXalpbblalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLgQcdp:meaQpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9ogLpxiiiiiiiiiiiiiiiip8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalclfaYpQbfaKc:q:yjjbfRbbfhlxdkaXalpbbwalpbbbgQclp:meaQpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9ogLpxssssssssssssssssp8JgQp5b9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibaKc:q:yjjbfpbbbgYaYpmbbbbbbbbbbbbbbbbaQp5e9cjF;8;4;W;G;ab9:9cU1:NgKcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPaLaQp9spklbalcwfaYpQbfaKc:q:yjjbfRbbfhlxekaXalpbbbpklbalczfhlkaocdfhoaiczfgiak6mbkkalTmbaAci6hHalhOaAcefgohAaoclSmdxekkcbhlaHceGmdkdnakTmbavcjdfazfhiavazfpbdbhYcbhXinaiavcj;cbfaXfgopblbgLcep9TaLpxeeeeeeeeeeeeeeeegQp9op9Hp9rgLaoakfpblbg8Acep9Ta8AaQp9op9Hp9rg8ApmbzeHdOiAlCvXoQrLgEaoamfpblbg3cep9Ta3aQp9op9Hp9rg3aoaxfpblbg5cep9Ta5aQp9op9Hp9rg5pmbzeHdOiAlCvXoQrLg8EpmbezHdiOAlvCXorQLgQaQpmbedibedibedibediaYp9UgYp9AdbbaiadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaEa8EpmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwKDYq8AkEx3m5P8Es8FgLa3a5pmwKDYq8AkEx3m5P8Es8Fg8ApmbezHdiOAlvCXorQLgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfgoaYaLa8ApmwDKYqk8AExm35Ps8E8FgQaQpmbedibedibedibedip9UgYp9AdbbaoadfgoaYaQaQpmlvorlvorlvorlvorp9UgYp9AdbbaoadfgoaYaQaQpmwDqkwDqkwDqkwDqkp9UgYp9AdbbaoadfgoaYaQaQpmxmPsxmPsxmPsxmPsp9UgYp9AdbbaoadfhiaXczfgXak6mbkkazclfgzad6mbkasavcjdfaqad2;8qbbavavcjdfaqcufad2fad;8qbbaqaDfhDc9:hoalmexikkc9:hoxekcbc99aral9Radcaadca0ESEhokavcj;kbf8Kjjjjbaokwbz:bjjjbk;uzeHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhodnaeTmbcmcsaDceSEhkcbhxcbhmcbhDcbhicbhlindnaoaq9nmbc9:hoxikdndnawRbbgrc;Ve0mbavc;abfalarcl4cu7fcsGcitfgPydlhsaPydbhzdnarcsGgPak9pmbavaiarcu7fcsGcdtfydbaxaPEhraPThPdndnadcd9hmbabaDcetfgHaz87ebaHcdfas87ebaHclfar87ebxekabaDcdtfgHazBdbaHclfasBdbaHcwfarBdbkaxaPfhxavc;abfalcitfgHarBdbaHasBdlavaicdtfarBdbavc;abfalcefcsGglcitfgHazBdbaHarBdlaiaPfhialcefhlxdkdndnaPcsSmbamaPfaPc987fcefhmxekaocefhrao8SbbgPcFeGhHdndnaPcu9mmbarhoxekaocvfhoaHcFbGhHcrhPdninar8SbbgOcFbGaPtaHVhHaOcu9kmearcefhraPcrfgPc8J9hmbxdkkarcefhokaHce4cbaHceG9R7amfhmkdndnadcd9hmbabaDcetfgraz87ebarcdfas87ebarclfam87ebxekabaDcdtfgrazBdbarclfasBdbarcwfamBdbkavc;abfalcitfgramBdbarasBdlavaicdtfamBdbavc;abfalcefcsGglcitfgrazBdbaramBdlaicefhialcefhlxekdnarcpe0mbaxcefgOavaiaqarcsGfRbbgPcl49RcsGcdtfydbaPcz6gHEhravaiaP9RcsGcdtfydbaOaHfgsaPcsGgOEhPaOThOdndnadcd9hmbabaDcetfgzax87ebazcdfar87ebazclfaP87ebxekabaDcdtfgzaxBdbazclfarBdbazcwfaPBdbkavaicdtfaxBdbavc;abfalcitfgzarBdbazaxBdlavaicefgicsGcdtfarBdbavc;abfalcefcsGcitfgzaPBdbazarBdlavaiaHfcsGgicdtfaPBdbavc;abfalcdfcsGglcitfgraxBdbaraPBdlalcefhlaiaOfhiasaOfhxxekaxcbaoRbbgzEgAarc;:eSgrfhsazcsGhCazcl4hXdndnazcs0mbascefhOxekashOavaiaX9RcsGcdtfydbhskdndnaCmbaOcefhxxekaOhxavaiaz9RcsGcdtfydbhOkdndnarTmbaocefhrxekaocdfhrao8SbegHcFeGhPdnaHcu9kmbaocofhAaPcFbGhPcrhodninar8SbbgHcFbGaotaPVhPaHcu9kmearcefhraocrfgoc8J9hmbkaAhrxekarcefhrkaPce4cbaPceG9R7amfgmhAkdndnaXcsSmbarhPxekarcefhPar8SbbgocFeGhHdnaocu9kmbarcvfhsaHcFbGhHcrhodninaP8SbbgrcFbGaotaHVhHarcu9kmeaPcefhPaocrfgoc8J9hmbkashPxekaPcefhPkaHce4cbaHceG9R7amfgmhskdndnaCcsSmbaPhoxekaPcefhoaP8SbbgrcFeGhHdnarcu9kmbaPcvfhOaHcFbGhHcrhrdninao8SbbgPcFbGartaHVhHaPcu9kmeaocefhoarcrfgrc8J9hmbkaOhoxekaocefhokaHce4cbaHceG9R7amfgmhOkdndnadcd9hmbabaDcetfgraA87ebarcdfas87ebarclfaO87ebxekabaDcdtfgraABdbarclfasBdbarcwfaOBdbkavc;abfalcitfgrasBdbaraABdlavaicdtfaABdbavc;abfalcefcsGcitfgraOBdbarasBdlavaicefgicsGcdtfasBdbavc;abfalcdfcsGcitfgraABdbaraOBdlavaiazcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhialcifhlkawcefhwalcsGhlaicsGhiaDcifgDae6mbkkcbc99aoaqSEhokavc;aef8Kjjjjbaok:llevu8Jjjjjbcz9Rhvc9:hodnaecvfal0mbcuhoaiRbbc;:eGc;qe9hmbav9cb83iwaicefhraialfc98fhwdnaeTmbdnadcdSmbcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcdtfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfglBdbaoalBdbaDcefgDae9hmbxdkkcbhDindnaraw6mbc9:skarcefhoar8SbbglcFeGhidndnalcu9mmbaohrxekarcvfhraicFbGhicrhldninao8SbbgdcFbGaltaiVhiadcu9kmeaocefhoalcrfglc8J9hmbxdkkaocefhrkabaDcetfaicd4cbaice4ceG9R7avcwfaiceGcdtVgoydbfgl87ebaoalBdbaDcefgDae9hmbkkcbc99arawSEhokaok:EPliuo97eue978Jjjjjbca9Rhidndnadcl9hmbdnaec98GglTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalae9pmeaiaeciGgvcdtgdVcbczad9R;8kbaiabalcdtfglad;8qbbdnavTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkalaiad;8qbbskdnaec98GgxTmbcbhvabhdinadczfglalpbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oawaopmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgvax6mbkkaxae9pmbaiaeciGgvcitgdfcbcaad9R;8kbaiabaxcitfglad;8qbbdnavTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmlvorxmPsCXQL358E8FpxFubbFubbFubbFubbp9op;6eaDaopmbediwDqkzHOAKY8AEgoczp:Sep;6egrp;Geaoczp:Reczp:Sep;6egwp;Gep;Kep;Legopxb;:FSb;:FSb;:FSb;:FSawaopxbbbbbbbbbbbbbbbbp:2egqawpxbbbjbbbjbbbjbbbjgmp9op9rp;Kegwawp;Meaoaop;Mearaqaramp9op9rp;Kegoaop;Mep;Kep;Kep;Jep;Negrp;Mepxbbn0bbn0bbn0bbn0gqp;Keczp:Reawarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9op9qgwaoarp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogopmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oawaopmbezHdiOAlvCXorQLp9qpklbkalaiad;8qbbkk;4wllue97euv978Jjjjjbc8W9Rhidnaec98GglTmbcbhvabhoinaiaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklbaopxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblbpEb:T:j83ibaocwfarp5eaipblbpEe:T:j83ibawaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblbpEd:T:j83ibaocKfakp5eaipblbpEi:T:j83ibaocafhoavclfgval6mbkkdnalae9pmbaiaeciGgvcitgofcbcaao9R;8kbaiabalcitfgwao;8qbbdnavTmbaiaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkclp:RepklaaipxbbjZbbjZbbjZbbjZpx;Zl81Z;Zl81Z;Zl81Z;Zl81Zakpxibbbibbbibbbibbbp9qp;6ep;NegkaraDpmbediwDqkzHOAKY8AEgrczp:Reczp:Sep;6ep;MegDaDp;Meakarczp:Sep;6ep;Megxaxp;Meakaqczp:Reczp:Sep;6ep;Megqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jepxb;:FSb;:FSb;:FSb;:FSgkp;Mepxbbn0bbn0bbn0bbn0grp;KepxFFbbFFbbFFbbFFbbgmp9oaxakp;Mearp;Keczp:Rep9qgxaqakp;Mearp;Keczp:ReaDakp;Mearp;Keamp9op9qgkpmbezHdiOAlvCXorQLgrp5baipblapEb:T:j83ibaiarp5eaipblapEe:T:j83iwaiaxakpmwDKYqk8AExm35Ps8E8Fgkp5baipblapEd:T:j83izaiakp5eaipblapEi:T:j83iKkawaiao;8qbbkk:Pddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbhdabheinaeaepbbbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepkbbaeczfheadclfgdav6mbkkdnaval9pmbaialciGgdcdtgeVcbc;abae9R;8kbaiabavcdtfgvae;8qbbdnadTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjZbbjZbbjZbbjZp:UepxbbjFbbjFbbjFbbjFp9op;Mepklbkavaiae;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz9Tbb"
32093;
32094	    var detector = new Uint8Array([
32095	        0,
32096	        97,
32097	        115,
32098	        109,
32099	        1,
32100	        0,
32101	        0,
32102	        0,
32103	        1,
32104	        4,
32105	        1,
32106	        96,
32107	        0,
32108	        0,
32109	        3,
32110	        3,
32111	        2,
32112	        0,
32113	        0,
32114	        5,
32115	        3,
32116	        1,
32117	        0,
32118	        1,
32119	        12,
32120	        1,
32121	        0,
32122	        10,
32123	        22,
32124	        2,
32125	        12,
32126	        0,
32127	        65,
32128	        0,
32129	        65,
32130	        0,
32131	        65,
32132	        0,
32133	        252,
32134	        10,
32135	        0,
32136	        0,
32137	        11,
32138	        7,
32139	        0,
32140	        65,
32141	        0,
32142	        253,
32143	        15,
32144	        26,
32145	        11
32146	    ]);
32147	    var wasmpack = new Uint8Array([
32148	        32,
32149	        0,
32150	        65,
32151	        2,
32152	        1,
32153	        106,
32154	        34,
32155	        33,
32156	        3,
32157	        128,
32158	        11,
32159	        4,
32160	        13,
32161	        64,
32162	        6,
32163	        253,
32164	        10,
32165	        7,
32166	        15,
32167	        116,
vendor: 31,980 bytes, lines 32168-32955
32168	        127,
32169	        5,
32170	        8,
32171	        12,
32172	        40,
32173	        16,
32174	        19,
32175	        54,
32176	        20,
32177	        9,
32178	        27,
32179	        255,
32180	        113,
32181	        17,
32182	        42,
32183	        67,
32184	        24,
32185	        23,
32186	        146,
32187	        148,
32188	        18,
32189	        14,
32190	        22,
32191	        45,
32192	        70,
32193	        69,
32194	        56,
32195	        114,
32196	        101,
32197	        21,
32198	        25,
32199	        63,
32200	        75,
32201	        136,
32202	        108,
32203	        28,
32204	        118,
32205	        29,
32206	        73,
32207	        115
32208	    ]);
32209	    if (typeof WebAssembly !== 'object') {
32210	        return {
32211	            supported: false
32212	        };
32213	    }
32214	    var wasm = WebAssembly.validate(detector) ? wasm_simd : wasm_base;
32215	    var instance;
32216	    var ready = WebAssembly.instantiate(unpack(wasm), {}).then(function(result) {
32217	        instance = result.instance;
32218	        instance.exports.__wasm_call_ctors();
32219	    });
32220	    function unpack(data) {
32221	        var result = new Uint8Array(data.length);
32222	        for(var i = 0; i < data.length; ++i){
32223	            var ch = data.charCodeAt(i);
32224	            result[i] = ch > 96 ? ch - 97 : ch > 64 ? ch - 39 : ch + 4;
32225	        }
32226	        var write = 0;
32227	        for(var i = 0; i < data.length; ++i){
32228	            result[write++] = result[i] < 60 ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i];
32229	        }
32230	        return result.buffer.slice(0, write);
32231	    }
32232	    function decode(fun, target, count, size, source, filter) {
32233	        var sbrk = instance.exports.sbrk;
32234	        var count4 = count + 3 & -4;
32235	        var tp = sbrk(count4 * size);
32236	        var sp = sbrk(source.length);
32237	        var heap = new Uint8Array(instance.exports.memory.buffer);
32238	        heap.set(source, sp);
32239	        var res = fun(tp, count, size, sp, source.length);
32240	        if (res == 0 && filter) {
32241	            filter(tp, count4, size);
32242	        }
32243	        target.set(heap.subarray(tp, tp + count * size));
32244	        sbrk(tp - sbrk(0));
32245	        if (res != 0) {
32246	            throw new Error("Malformed buffer data: " + res);
32247	        }
32248	    }
32249	    var filters = {
32250	        NONE: "",
32251	        OCTAHEDRAL: "meshopt_decodeFilterOct",
32252	        QUATERNION: "meshopt_decodeFilterQuat",
32253	        EXPONENTIAL: "meshopt_decodeFilterExp"
32254	    };
32255	    var decoders = {
32256	        ATTRIBUTES: "meshopt_decodeVertexBuffer",
32257	        TRIANGLES: "meshopt_decodeIndexBuffer",
32258	        INDICES: "meshopt_decodeIndexSequence"
32259	    };
32260	    var workers = [];
32261	    var requestId = 0;
32262	    function createWorker(url) {
32263	        var worker = {
32264	            object: new Worker(url),
32265	            pending: 0,
32266	            requests: {}
32267	        };
32268	        worker.object.onmessage = function(event) {
32269	            var data = event.data;
32270	            worker.pending -= data.count;
32271	            worker.requests[data.id][data.action](data.value);
32272	            delete worker.requests[data.id];
32273	        };
32274	        return worker;
32275	    }
32276	    function initWorkers(count) {
32277	        var source = "var instance; var ready = WebAssembly.instantiate(new Uint8Array([" + new Uint8Array(unpack(wasm)) + "]), {})" + ".then(function(result) { instance = result.instance; instance.exports.__wasm_call_ctors(); });" + "self.onmessage = workerProcess;" + decode.toString() + workerProcess.toString();
32278	        var blob = new Blob([
32279	            source
32280	        ], {
32281	            type: 'text/javascript'
32282	        });
32283	        var url = URL.createObjectURL(blob);
32284	        for(var i = 0; i < count; ++i){
32285	            workers[i] = createWorker(url);
32286	        }
32287	        URL.revokeObjectURL(url);
32288	    }
32289	    function decodeWorker(count, size, source, mode, filter) {
32290	        var worker = workers[0];
32291	        for(var i = 1; i < workers.length; ++i){
32292	            if (workers[i].pending < worker.pending) {
32293	                worker = workers[i];
32294	            }
32295	        }
32296	        return new Promise(function(resolve, reject) {
32297	            var data = new Uint8Array(source);
32298	            var id = requestId++;
32299	            worker.pending += count;
32300	            worker.requests[id] = {
32301	                resolve: resolve,
32302	                reject: reject
32303	            };
32304	            worker.object.postMessage({
32305	                id: id,
32306	                count: count,
32307	                size: size,
32308	                source: data,
32309	                mode: mode,
32310	                filter: filter
32311	            }, [
32312	                data.buffer
32313	            ]);
32314	        });
32315	    }
32316	    function workerProcess(event) {
32317	        ready.then(function() {
32318	            var data = event.data;
32319	            try {
32320	                var target = new Uint8Array(data.count * data.size);
32321	                decode(instance.exports[data.mode], target, data.count, data.size, data.source, instance.exports[data.filter]);
32322	                self.postMessage({
32323	                    id: data.id,
32324	                    count: data.count,
32325	                    action: "resolve",
32326	                    value: target
32327	                }, [
32328	                    target.buffer
32329	                ]);
32330	            } catch (error) {
32331	                self.postMessage({
32332	                    id: data.id,
32333	                    count: data.count,
32334	                    action: "reject",
32335	                    value: error
32336	                });
32337	            }
32338	        });
32339	    }
32340	    return {
32341	        ready: ready,
32342	        supported: true,
32343	        useWorkers: function(count) {
32344	            initWorkers(count);
32345	        },
32346	        decodeVertexBuffer: function(target, count, size, source, filter) {
32347	            decode(instance.exports.meshopt_decodeVertexBuffer, target, count, size, source, instance.exports[filters[filter]]);
32348	        },
32349	        decodeIndexBuffer: function(target, count, size, source) {
32350	            decode(instance.exports.meshopt_decodeIndexBuffer, target, count, size, source);
32351	        },
32352	        decodeIndexSequence: function(target, count, size, source) {
32353	            decode(instance.exports.meshopt_decodeIndexSequence, target, count, size, source);
32354	        },
32355	        decodeGltfBuffer: function(target, count, size, source, mode, filter) {
32356	            decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]);
32357	        },
32358	        decodeGltfBufferAsync: function(count, size, source, mode, filter) {
32359	            if (workers.length > 0) {
32360	                return decodeWorker(count, size, source, decoders[mode], filters[filter]);
32361	            }
32362	            return ready.then(function() {
32363	                var target = new Uint8Array(count * size);
32364	                decode(instance.exports[decoders[mode]], target, count, size, source, instance.exports[filters[filter]]);
32365	                return target;
32366	            });
32367	        }
32368	    };
32369	}();
32370
32371	const _taskCache$1 = new WeakMap();
32372	class DRACOLoader extends Loader {
32373	    setDecoderPath(path) {
32374	        this.decoderPath = path;
32375	        return this;
32376	    }
32377	    setDecoderConfig(config) {
32378	        this.decoderConfig = config;
32379	        return this;
32380	    }
32381	    setWorkerLimit(workerLimit) {
32382	        this.workerLimit = workerLimit;
32383	        return this;
32384	    }
32385	    load(url, onLoad, onProgress, onError) {
32386	        const loader = new FileLoader(this.manager);
32387	        loader.setPath(this.path);
32388	        loader.setResponseType('arraybuffer');
32389	        loader.setRequestHeader(this.requestHeader);
32390	        loader.setWithCredentials(this.withCredentials);
32391	        loader.load(url, (buffer)=>{
32392	            this.parse(buffer, onLoad, onError);
32393	        }, onProgress, onError);
32394	    }
32395	    parse(buffer, onLoad, onError = ()=>{}) {
32396	        this.decodeDracoFile(buffer, onLoad, null, null, SRGBColorSpace, onError).catch(onError);
32397	    }
32398	    decodeDracoFile(buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = LinearSRGBColorSpace, onError = ()=>{}) {
32399	        const taskConfig = {
32400	            attributeIDs: attributeIDs || this.defaultAttributeIDs,
32401	            attributeTypes: attributeTypes || this.defaultAttributeTypes,
32402	            useUniqueIDs: !!attributeIDs,
32403	            vertexColorSpace: vertexColorSpace
32404	        };
32405	        return this.decodeGeometry(buffer, taskConfig).then(callback).catch(onError);
32406	    }
32407	    decodeGeometry(buffer, taskConfig) {
32408	        const taskKey = JSON.stringify(taskConfig);
32409	        // Check for an existing task using this buffer. A transferred buffer cannot be transferred
32410	        // again from this thread.
32411	        if (_taskCache$1.has(buffer)) {
32412	            const cachedTask = _taskCache$1.get(buffer);
32413	            if (cachedTask.key === taskKey) {
32414	                return cachedTask.promise;
32415	            } else if (buffer.byteLength === 0) {
32416	                // Technically, it would be possible to wait for the previous task to complete,
32417	                // transfer the buffer back, and decode again with the second configuration. That
32418	                // is complex, and I don't know of any reason to decode a Draco buffer twice in
32419	                // different ways, so this is left unimplemented.
32420	                throw new Error('THREE.DRACOLoader: Unable to re-decode a buffer with different ' + 'settings. Buffer has already been transferred.');
32421	            }
32422	        }
32423	        //
32424	        let worker;
32425	        const taskID = this.workerNextTaskID++;
32426	        const taskCost = buffer.byteLength;
32427	        // Obtain a worker and assign a task, and construct a geometry instance
32428	        // when the task completes.
32429	        const geometryPending = this._getWorker(taskID, taskCost).then((_worker)=>{
32430	            worker = _worker;
32431	            return new Promise((resolve, reject)=>{
32432	                worker._callbacks[taskID] = {
32433	                    resolve,
32434	                    reject
32435	                };
32436	                worker.postMessage({
32437	                    type: 'decode',
32438	                    id: taskID,
32439	                    taskConfig,
32440	                    buffer
32441	                }, [
32442	                    buffer
32443	                ]);
32444	            // this.debug();
32445	            });
32446	        }).then((message)=>this._createGeometry(message.geometry));
32447	        // Remove task from the task list.
32448	        // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
32449	        geometryPending.catch(()=>true).then(()=>{
32450	            if (worker && taskID) {
32451	                this._releaseTask(worker, taskID);
32452	            // this.debug();
32453	            }
32454	        });
32455	        // Cache the task result.
32456	        _taskCache$1.set(buffer, {
32457	            key: taskKey,
32458	            promise: geometryPending
32459	        });
32460	        return geometryPending;
32461	    }
32462	    _createGeometry(geometryData) {
32463	        const geometry = new BufferGeometry();
32464	        if (geometryData.index) {
32465	            geometry.setIndex(new BufferAttribute(geometryData.index.array, 1));
32466	        }
32467	        for(let i = 0; i < geometryData.attributes.length; i++){
32468	            const result = geometryData.attributes[i];
32469	            const name = result.name;
32470	            const array = result.array;
32471	            const itemSize = result.itemSize;
32472	            const attribute = new BufferAttribute(array, itemSize);
32473	            if (name === 'color') {
32474	                this._assignVertexColorSpace(attribute, result.vertexColorSpace);
32475	                attribute.normalized = array instanceof Float32Array === false;
32476	            }
32477	            geometry.setAttribute(name, attribute);
32478	        }
32479	        return geometry;
32480	    }
32481	    _assignVertexColorSpace(attribute, inputColorSpace) {
32482	        // While .drc files do not specify colorspace, the only 'official' tooling
32483	        // is PLY and OBJ converters, which use sRGB. We'll assume sRGB when a .drc
32484	        // file is passed into .load() or .parse(). GLTFLoader uses internal APIs
32485	        // to decode geometry, and vertex colors are already Linear-sRGB in there.
32486	        if (inputColorSpace !== SRGBColorSpace) return;
32487	        const _color = new Color();
32488	        for(let i = 0, il = attribute.count; i < il; i++){
32489	            _color.fromBufferAttribute(attribute, i);
32490	            ColorManagement.toWorkingColorSpace(_color, SRGBColorSpace);
32491	            attribute.setXYZ(i, _color.r, _color.g, _color.b);
32492	        }
32493	    }
32494	    _loadLibrary(url, responseType) {
32495	        const loader = new FileLoader(this.manager);
32496	        loader.setPath(this.decoderPath);
32497	        loader.setResponseType(responseType);
32498	        loader.setWithCredentials(this.withCredentials);
32499	        return new Promise((resolve, reject)=>{
32500	            loader.load(url, resolve, undefined, reject);
32501	        });
32502	    }
32503	    preload() {
32504	        this._initDecoder();
32505	        return this;
32506	    }
32507	    _initDecoder() {
32508	        if (this.decoderPending) return this.decoderPending;
32509	        const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
32510	        const librariesPending = [];
32511	        if (useJS) {
32512	            librariesPending.push(this._loadLibrary('draco_decoder.js', 'text'));
32513	        } else {
32514	            librariesPending.push(this._loadLibrary('draco_wasm_wrapper.js', 'text'));
32515	            librariesPending.push(this._loadLibrary('draco_decoder.wasm', 'arraybuffer'));
32516	        }
32517	        this.decoderPending = Promise.all(librariesPending).then((libraries)=>{
32518	            const jsContent = libraries[0];
32519	            if (!useJS) {
32520	                this.decoderConfig.wasmBinary = libraries[1];
32521	            }
32522	            const fn = DRACOWorker.toString();
32523	            const body = [
32524	                '/* draco decoder */',
32525	                jsContent,
32526	                '',
32527	                '/* worker */',
32528	                fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
32529	            ].join('\n');
32530	            this.workerSourceURL = URL.createObjectURL(new Blob([
32531	                body
32532	            ]));
32533	        });
32534	        return this.decoderPending;
32535	    }
32536	    _getWorker(taskID, taskCost) {
32537	        return this._initDecoder().then(()=>{
32538	            if (this.workerPool.length < this.workerLimit) {
32539	                const worker = new Worker(this.workerSourceURL);
32540	                worker._callbacks = {};
32541	                worker._taskCosts = {};
32542	                worker._taskLoad = 0;
32543	                worker.postMessage({
32544	                    type: 'init',
32545	                    decoderConfig: this.decoderConfig
32546	                });
32547	                worker.onmessage = function(e) {
32548	                    const message = e.data;
32549	                    switch(message.type){
32550	                        case 'decode':
32551	                            worker._callbacks[message.id].resolve(message);
32552	                            break;
32553	                        case 'error':
32554	                            worker._callbacks[message.id].reject(message);
32555	                            break;
32556	                        default:
32557	                            console.error('THREE.DRACOLoader: Unexpected message, "' + message.type + '"');
32558	                    }
32559	                };
32560	                this.workerPool.push(worker);
32561	            } else {
32562	                this.workerPool.sort(function(a, b) {
32563	                    return a._taskLoad > b._taskLoad ? -1 : 1;
32564	                });
32565	            }
32566	            const worker = this.workerPool[this.workerPool.length - 1];
32567	            worker._taskCosts[taskID] = taskCost;
32568	            worker._taskLoad += taskCost;
32569	            return worker;
32570	        });
32571	    }
32572	    _releaseTask(worker, taskID) {
32573	        worker._taskLoad -= worker._taskCosts[taskID];
32574	        delete worker._callbacks[taskID];
32575	        delete worker._taskCosts[taskID];
32576	    }
32577	    debug() {
32578	        console.log('Task load: ', this.workerPool.map((worker)=>worker._taskLoad));
32579	    }
32580	    dispose() {
32581	        for(let i = 0; i < this.workerPool.length; ++i){
32582	            this.workerPool[i].terminate();
32583	        }
32584	        this.workerPool.length = 0;
32585	        if (this.workerSourceURL !== '') {
32586	            URL.revokeObjectURL(this.workerSourceURL);
32587	        }
32588	        return this;
32589	    }
32590	    constructor(manager){
32591	        super(manager);
32592	        this.decoderPath = '';
32593	        this.decoderConfig = {};
32594	        this.decoderBinary = null;
32595	        this.decoderPending = null;
32596	        this.workerLimit = 4;
32597	        this.workerPool = [];
32598	        this.workerNextTaskID = 1;
32599	        this.workerSourceURL = '';
32600	        this.defaultAttributeIDs = {
32601	            position: 'POSITION',
32602	            normal: 'NORMAL',
32603	            color: 'COLOR',
32604	            uv: 'TEX_COORD'
32605	        };
32606	        this.defaultAttributeTypes = {
32607	            position: 'Float32Array',
32608	            normal: 'Float32Array',
32609	            color: 'Float32Array',
32610	            uv: 'Float32Array'
32611	        };
32612	    }
32613	}
32614	/* WEB WORKER */ function DRACOWorker() {
32615	    let decoderConfig;
32616	    let decoderPending;
32617	    onmessage = function(e) {
32618	        const message = e.data;
32619	        switch(message.type){
32620	            case 'init':
32621	                decoderConfig = message.decoderConfig;
32622	                decoderPending = new Promise(function(resolve /*, reject*/ ) {
32623	                    decoderConfig.onModuleLoaded = function(draco) {
32624	                        // Module is Promise-like. Wrap before resolving to avoid loop.
32625	                        resolve({
32626	                            draco: draco
32627	                        });
32628	                    };
32629	                    DracoDecoderModule(decoderConfig); // eslint-disable-line no-undef
32630	                });
32631	                break;
32632	            case 'decode':
32633	                const buffer = message.buffer;
32634	                const taskConfig = message.taskConfig;
32635	                decoderPending.then((module)=>{
32636	                    const draco = module.draco;
32637	                    const decoder = new draco.Decoder();
32638	                    try {
32639	                        const geometry = decodeGeometry(draco, decoder, new Int8Array(buffer), taskConfig);
32640	                        const buffers = geometry.attributes.map((attr)=>attr.array.buffer);
32641	                        if (geometry.index) buffers.push(geometry.index.array.buffer);
32642	                        self.postMessage({
32643	                            type: 'decode',
32644	                            id: message.id,
32645	                            geometry
32646	                        }, buffers);
32647	                    } catch (error) {
32648	                        console.error(error);
32649	                        self.postMessage({
32650	                            type: 'error',
32651	                            id: message.id,
32652	                            error: error.message
32653	                        });
32654	                    } finally{
32655	                        draco.destroy(decoder);
32656	                    }
32657	                });
32658	                break;
32659	        }
32660	    };
32661	    function decodeGeometry(draco, decoder, array, taskConfig) {
32662	        const attributeIDs = taskConfig.attributeIDs;
32663	        const attributeTypes = taskConfig.attributeTypes;
32664	        let dracoGeometry;
32665	        let decodingStatus;
32666	        const geometryType = decoder.GetEncodedGeometryType(array);
32667	        if (geometryType === draco.TRIANGULAR_MESH) {
32668	            dracoGeometry = new draco.Mesh();
32669	            decodingStatus = decoder.DecodeArrayToMesh(array, array.byteLength, dracoGeometry);
32670	        } else if (geometryType === draco.POINT_CLOUD) {
32671	            dracoGeometry = new draco.PointCloud();
32672	            decodingStatus = decoder.DecodeArrayToPointCloud(array, array.byteLength, dracoGeometry);
32673	        } else {
32674	            throw new Error('THREE.DRACOLoader: Unexpected geometry type.');
32675	        }
32676	        if (!decodingStatus.ok() || dracoGeometry.ptr === 0) {
32677	            throw new Error('THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg());
32678	        }
32679	        const geometry = {
32680	            index: null,
32681	            attributes: []
32682	        };
32683	        // Gather all vertex attributes.
32684	        for(const attributeName in attributeIDs){
32685	            const attributeType = self[attributeTypes[attributeName]];
32686	            let attribute;
32687	            let attributeID;
32688	            // A Draco file may be created with default vertex attributes, whose attribute IDs
32689	            // are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
32690	            // a Draco file may contain a custom set of attributes, identified by known unique
32691	            // IDs. glTF files always do the latter, and `.drc` files typically do the former.
32692	            if (taskConfig.useUniqueIDs) {
32693	                attributeID = attributeIDs[attributeName];
32694	                attribute = decoder.GetAttributeByUniqueId(dracoGeometry, attributeID);
32695	            } else {
32696	                attributeID = decoder.GetAttributeId(dracoGeometry, draco[attributeIDs[attributeName]]);
32697	                if (attributeID === -1) continue;
32698	                attribute = decoder.GetAttribute(dracoGeometry, attributeID);
32699	            }
32700	            const attributeResult = decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute);
32701	            if (attributeName === 'color') {
32702	                attributeResult.vertexColorSpace = taskConfig.vertexColorSpace;
32703	            }
32704	            geometry.attributes.push(attributeResult);
32705	        }
32706	        // Add index.
32707	        if (geometryType === draco.TRIANGULAR_MESH) {
32708	            geometry.index = decodeIndex(draco, decoder, dracoGeometry);
32709	        }
32710	        draco.destroy(dracoGeometry);
32711	        return geometry;
32712	    }
32713	    function decodeIndex(draco, decoder, dracoGeometry) {
32714	        const numFaces = dracoGeometry.num_faces();
32715	        const numIndices = numFaces * 3;
32716	        const byteLength = numIndices * 4;
32717	        const ptr = draco._malloc(byteLength);
32718	        decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr);
32719	        const index = new Uint32Array(draco.HEAPF32.buffer, ptr, numIndices).slice();
32720	        draco._free(ptr);
32721	        return {
32722	            array: index,
32723	            itemSize: 1
32724	        };
32725	    }
32726	    function decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) {
32727	        const numComponents = attribute.num_components();
32728	        const numPoints = dracoGeometry.num_points();
32729	        const numValues = numPoints * numComponents;
32730	        const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
32731	        const dataType = getDracoDataType(draco, attributeType);
32732	        const ptr = draco._malloc(byteLength);
32733	        decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, dataType, byteLength, ptr);
32734	        const array = new attributeType(draco.HEAPF32.buffer, ptr, numValues).slice();
32735	        draco._free(ptr);
32736	        return {
32737	            name: attributeName,
32738	            array: array,
32739	            itemSize: numComponents
32740	        };
32741	    }
32742	    function getDracoDataType(draco, attributeType) {
32743	        switch(attributeType){
32744	            case Float32Array:
32745	                return draco.DT_FLOAT32;
32746	            case Int8Array:
32747	                return draco.DT_INT8;
32748	            case Int16Array:
32749	                return draco.DT_INT16;
32750	            case Int32Array:
32751	                return draco.DT_INT32;
32752	            case Uint8Array:
32753	                return draco.DT_UINT8;
32754	            case Uint16Array:
32755	                return draco.DT_UINT16;
32756	            case Uint32Array:
32757	                return draco.DT_UINT32;
32758	        }
32759	    }
32760	}
32761
32762	/**
32763	 * @param {BufferGeometry} geometry
32764	 * @param {number} drawMode
32765	 * @return {BufferGeometry}
32766	 */ function toTrianglesDrawMode(geometry, drawMode) {
32767	    if (drawMode === TrianglesDrawMode) {
32768	        console.warn('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.');
32769	        return geometry;
32770	    }
32771	    if (drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode) {
32772	        let index = geometry.getIndex();
32773	        // generate index if not present
32774	        if (index === null) {
32775	            const indices = [];
32776	            const position = geometry.getAttribute('position');
32777	            if (position !== undefined) {
32778	                for(let i = 0; i < position.count; i++){
32779	                    indices.push(i);
32780	                }
32781	                geometry.setIndex(indices);
32782	                index = geometry.getIndex();
32783	            } else {
32784	                console.error('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.');
32785	                return geometry;
32786	            }
32787	        }
32788	        //
32789	        const numberOfTriangles = index.count - 2;
32790	        const newIndices = [];
32791	        if (drawMode === TriangleFanDrawMode) {
32792	            // gl.TRIANGLE_FAN
32793	            for(let i = 1; i <= numberOfTriangles; i++){
32794	                newIndices.push(index.getX(0));
32795	                newIndices.push(index.getX(i));
32796	                newIndices.push(index.getX(i + 1));
32797	            }
32798	        } else {
32799	            // gl.TRIANGLE_STRIP
32800	            for(let i = 0; i < numberOfTriangles; i++){
32801	                if (i % 2 === 0) {
32802	                    newIndices.push(index.getX(i));
32803	                    newIndices.push(index.getX(i + 1));
32804	                    newIndices.push(index.getX(i + 2));
32805	                } else {
32806	                    newIndices.push(index.getX(i + 2));
32807	                    newIndices.push(index.getX(i + 1));
32808	                    newIndices.push(index.getX(i));
32809	                }
32810	            }
32811	        }
32812	        if (newIndices.length / 3 !== numberOfTriangles) {
32813	            console.error('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.');
32814	        }
32815	        // build final geometry
32816	        const newGeometry = geometry.clone();
32817	        newGeometry.setIndex(newIndices);
32818	        newGeometry.clearGroups();
32819	        return newGeometry;
32820	    } else {
32821	        console.error('THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:', drawMode);
32822	        return geometry;
32823	    }
32824	}
32825
32826	class GLTFLoader extends Loader {
32827	    load(url, onLoad, onProgress, onError) {
32828	        const scope = this;
32829	        let resourcePath;
32830	        if (this.resourcePath !== '') {
32831	            resourcePath = this.resourcePath;
32832	        } else if (this.path !== '') {
32833	            // If a base path is set, resources will be relative paths from that plus the relative path of the gltf file
32834	            // Example  path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'
32835	            // resourcePath = 'https://my-cnd-server.com/assets/models/'
32836	            // referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'
32837	            // referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'
32838	            const relativeUrl = LoaderUtils.extractUrlBase(url);
32839	            resourcePath = LoaderUtils.resolveURL(relativeUrl, this.path);
32840	        } else {
32841	            resourcePath = LoaderUtils.extractUrlBase(url);
32842	        }
32843	        // Tells the LoadingManager to track an extra item, which resolves after
32844	        // the model is fully loaded. This means the count of items loaded will
32845	        // be incorrect, but ensures manager.onLoad() does not fire early.
32846	        this.manager.itemStart(url);
32847	        const _onError = function(e) {
32848	            if (onError) {
32849	                onError(e);
32850	            } else {
32851	                console.error(e);
32852	            }
32853	            scope.manager.itemError(url);
32854	            scope.manager.itemEnd(url);
32855	        };
32856	        const loader = new FileLoader(this.manager);
32857	        loader.setPath(this.path);
32858	        loader.setResponseType('arraybuffer');
32859	        loader.setRequestHeader(this.requestHeader);
32860	        loader.setWithCredentials(this.withCredentials);
32861	        loader.load(url, function(data) {
32862	            try {
32863	                scope.parse(data, resourcePath, function(gltf) {
32864	                    onLoad(gltf);
32865	                    scope.manager.itemEnd(url);
32866	                }, _onError);
32867	            } catch (e) {
32868	                _onError(e);
32869	            }
32870	        }, onProgress, _onError);
32871	    }
32872	    setDRACOLoader(dracoLoader) {
32873	        this.dracoLoader = dracoLoader;
32874	        return this;
32875	    }
32876	    setKTX2Loader(ktx2Loader) {
32877	        this.ktx2Loader = ktx2Loader;
32878	        return this;
32879	    }
32880	    setMeshoptDecoder(meshoptDecoder) {
32881	        this.meshoptDecoder = meshoptDecoder;
32882	        return this;
32883	    }
32884	    register(callback) {
32885	        if (this.pluginCallbacks.indexOf(callback) === -1) {
32886	            this.pluginCallbacks.push(callback);
32887	        }
32888	        return this;
32889	    }
32890	    unregister(callback) {
32891	        if (this.pluginCallbacks.indexOf(callback) !== -1) {
32892	            this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
32893	        }
32894	        return this;
32895	    }
32896	    parse(data, path, onLoad, onError) {
32897	        let json;
32898	        const extensions = {};
32899	        const plugins = {};
32900	        const textDecoder = new TextDecoder();
32901	        if (typeof data === 'string') {
32902	            json = JSON.parse(data);
32903	        } else if (data instanceof ArrayBuffer) {
32904	            const magic = textDecoder.decode(new Uint8Array(data, 0, 4));
32905	            if (magic === BINARY_EXTENSION_HEADER_MAGIC) {
32906	                try {
32907	                    extensions[EXTENSIONS.KHR_BINARY_GLTF] = new GLTFBinaryExtension(data);
32908	                } catch (error) {
32909	                    if (onError) onError(error);
32910	                    return;
32911	                }
32912	                json = JSON.parse(extensions[EXTENSIONS.KHR_BINARY_GLTF].content);
32913	            } else {
32914	                json = JSON.parse(textDecoder.decode(data));
32915	            }
32916	        } else {
32917	            json = data;
32918	        }
32919	        if (json.asset === undefined || json.asset.version[0] < 2) {
32920	            if (onError) onError(new Error('THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.'));
32921	            return;
32922	        }
32923	        const parser = new GLTFParser(json, {
32924	            path: path || this.resourcePath || '',
32925	            crossOrigin: this.crossOrigin,
32926	            requestHeader: this.requestHeader,
32927	            manager: this.manager,
32928	            ktx2Loader: this.ktx2Loader,
32929	            meshoptDecoder: this.meshoptDecoder
32930	        });
32931	        parser.fileLoader.setRequestHeader(this.requestHeader);
32932	        for(let i = 0; i < this.pluginCallbacks.length; i++){
32933	            const plugin = this.pluginCallbacks[i](parser);
32934	            if (!plugin.name) console.error('THREE.GLTFLoader: Invalid plugin found: missing name');
32935	            plugins[plugin.name] = plugin;
32936	            // Workaround to avoid determining as unknown extension
32937	            // in addUnknownExtensionsToUserData().
32938	            // Remove this workaround if we move all the existing
32939	            // extension handlers to plugin system
32940	            extensions[plugin.name] = true;
32941	        }
32942	        if (json.extensionsUsed) {
32943	            for(let i = 0; i < json.extensionsUsed.length; ++i){
32944	                const extensionName = json.extensionsUsed[i];
32945	                const extensionsRequired = json.extensionsRequired || [];
32946	                switch(extensionName){
32947	                    case EXTENSIONS.KHR_MATERIALS_UNLIT:
32948	                        extensions[extensionName] = new GLTFMaterialsUnlitExtension$1();
32949	                        break;
32950	                    case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
32951	                        extensions[extensionName] = new GLTFDracoMeshCompressionExtension(json, this.dracoLoader);
32952	                        break;
32953	                    case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
32954	                        extensions[extensionName] = new GLTFTextureTransformExtension();
32955	                        break;
vendor: 2,009 bytes, lines 32956-33006
32956	                    case EXTENSIONS.KHR_MESH_QUANTIZATION:
32957	                        extensions[extensionName] = new GLTFMeshQuantizationExtension();
32958	                        break;
32959	                    default:
32960	                        if (extensionsRequired.indexOf(extensionName) >= 0 && plugins[extensionName] === undefined) {
32961	                            console.warn('THREE.GLTFLoader: Unknown extension "' + extensionName + '".');
32962	                        }
32963	                }
32964	            }
32965	        }
32966	        parser.setExtensions(extensions);
32967	        parser.setPlugins(plugins);
32968	        parser.parse(onLoad, onError);
32969	    }
32970	    parseAsync(data, path) {
32971	        const scope = this;
32972	        return new Promise(function(resolve, reject) {
32973	            scope.parse(data, path, resolve, reject);
32974	        });
32975	    }
32976	    constructor(manager){
32977	        super(manager);
32978	        this.dracoLoader = null;
32979	        this.ktx2Loader = null;
32980	        this.meshoptDecoder = null;
32981	        this.pluginCallbacks = [];
32982	        this.register(function(parser) {
32983	            return new GLTFMaterialsClearcoatExtension$1(parser);
32984	        });
32985	        this.register(function(parser) {
32986	            return new GLTFMaterialsDispersionExtension$1(parser);
32987	        });
32988	        this.register(function(parser) {
32989	            return new GLTFTextureBasisUExtension(parser);
32990	        });
32991	        this.register(function(parser) {
32992	            return new GLTFTextureWebPExtension(parser);
32993	        });
32994	        this.register(function(parser) {
32995	            return new GLTFTextureAVIFExtension(parser);
32996	        });
32997	        this.register(function(parser) {
32998	            return new GLTFMaterialsSheenExtension$1(parser);
32999	        });
33000	        this.register(function(parser) {
33001	            return new GLTFMaterialsTransmissionExtension$1(parser);
33002	        });
33003	        this.register(function(parser) {
33004	            return new GLTFMaterialsVolumeExtension$1(parser);
33005	        });
33006	        this.register(function(parser) {
vendor: 20,079 bytes, lines 33007-33452
33007	            return new GLTFMaterialsIorExtension$1(parser);
33008	        });
33009	        this.register(function(parser) {
33010	            return new GLTFMaterialsEmissiveStrengthExtension$1(parser);
33011	        });
33012	        this.register(function(parser) {
33013	            return new GLTFMaterialsSpecularExtension$1(parser);
33014	        });
33015	        this.register(function(parser) {
33016	            return new GLTFMaterialsIridescenceExtension$1(parser);
33017	        });
33018	        this.register(function(parser) {
33019	            return new GLTFMaterialsAnisotropyExtension$1(parser);
33020	        });
33021	        this.register(function(parser) {
33022	            return new GLTFMaterialsBumpExtension$1(parser);
33023	        });
33024	        this.register(function(parser) {
33025	            return new GLTFLightsExtension(parser);
33026	        });
33027	        this.register(function(parser) {
33028	            return new GLTFMeshoptCompression(parser);
33029	        });
33030	        this.register(function(parser) {
33031	            return new GLTFMeshGpuInstancing$1(parser);
33032	        });
33033	    }
33034	}
33035	/* GLTFREGISTRY */ function GLTFRegistry() {
33036	    let objects = {};
33037	    return {
33038	        get: function(key) {
33039	            return objects[key];
33040	        },
33041	        add: function(key, object) {
33042	            objects[key] = object;
33043	        },
33044	        remove: function(key) {
33045	            delete objects[key];
33046	        },
33047	        removeAll: function() {
33048	            objects = {};
33049	        }
33050	    };
33051	}
33052	/*********************************/ /********** EXTENSIONS ***********/ /*********************************/ const EXTENSIONS = {
33053	    KHR_BINARY_GLTF: 'KHR_binary_glTF',
33054	    KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
33055	    KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
33056	    KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
33057	    KHR_MATERIALS_DISPERSION: 'KHR_materials_dispersion',
33058	    KHR_MATERIALS_IOR: 'KHR_materials_ior',
33059	    KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
33060	    KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
33061	    KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
33062	    KHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',
33063	    KHR_MATERIALS_ANISOTROPY: 'KHR_materials_anisotropy',
33064	    KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
33065	    KHR_MATERIALS_VOLUME: 'KHR_materials_volume',
33066	    KHR_TEXTURE_BASISU: 'KHR_texture_basisu',
33067	    KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
33068	    KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
33069	    KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
33070	    EXT_MATERIALS_BUMP: 'EXT_materials_bump',
33071	    EXT_TEXTURE_WEBP: 'EXT_texture_webp',
33072	    EXT_TEXTURE_AVIF: 'EXT_texture_avif',
33073	    EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
33074	    EXT_MESH_GPU_INSTANCING: 'EXT_mesh_gpu_instancing'
33075	};
33076	/**
33077	 * Punctual Lights Extension
33078	 *
33079	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
33080	 */ class GLTFLightsExtension {
33081	    _markDefs() {
33082	        const parser = this.parser;
33083	        const nodeDefs = this.parser.json.nodes || [];
33084	        for(let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++){
33085	            const nodeDef = nodeDefs[nodeIndex];
33086	            if (nodeDef.extensions && nodeDef.extensions[this.name] && nodeDef.extensions[this.name].light !== undefined) {
33087	                parser._addNodeRef(this.cache, nodeDef.extensions[this.name].light);
33088	            }
33089	        }
33090	    }
33091	    _loadLight(lightIndex) {
33092	        const parser = this.parser;
33093	        const cacheKey = 'light:' + lightIndex;
33094	        let dependency = parser.cache.get(cacheKey);
33095	        if (dependency) return dependency;
33096	        const json = parser.json;
33097	        const extensions = json.extensions && json.extensions[this.name] || {};
33098	        const lightDefs = extensions.lights || [];
33099	        const lightDef = lightDefs[lightIndex];
33100	        let lightNode;
33101	        const color = new Color(0xffffff);
33102	        if (lightDef.color !== undefined) color.setRGB(lightDef.color[0], lightDef.color[1], lightDef.color[2], LinearSRGBColorSpace);
33103	        const range = lightDef.range !== undefined ? lightDef.range : 0;
33104	        switch(lightDef.type){
33105	            case 'directional':
33106	                lightNode = new DirectionalLight(color);
33107	                lightNode.target.position.set(0, 0, -1);
33108	                lightNode.add(lightNode.target);
33109	                break;
33110	            case 'point':
33111	                lightNode = new PointLight(color);
33112	                lightNode.distance = range;
33113	                break;
33114	            case 'spot':
33115	                lightNode = new SpotLight(color);
33116	                lightNode.distance = range;
33117	                // Handle spotlight properties.
33118	                lightDef.spot = lightDef.spot || {};
33119	                lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;
33120	                lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
33121	                lightNode.angle = lightDef.spot.outerConeAngle;
33122	                lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
33123	                lightNode.target.position.set(0, 0, -1);
33124	                lightNode.add(lightNode.target);
33125	                break;
33126	            default:
33127	                throw new Error('THREE.GLTFLoader: Unexpected light type: ' + lightDef.type);
33128	        }
33129	        // Some lights (e.g. spot) default to a position other than the origin. Reset the position
33130	        // here, because node-level parsing will only override position if explicitly specified.
33131	        lightNode.position.set(0, 0, 0);
33132	        assignExtrasToUserData(lightNode, lightDef);
33133	        if (lightDef.intensity !== undefined) lightNode.intensity = lightDef.intensity;
33134	        lightNode.name = parser.createUniqueName(lightDef.name || 'light_' + lightIndex);
33135	        dependency = Promise.resolve(lightNode);
33136	        parser.cache.add(cacheKey, dependency);
33137	        return dependency;
33138	    }
33139	    getDependency(type, index) {
33140	        if (type !== 'light') return;
33141	        return this._loadLight(index);
33142	    }
33143	    createNodeAttachment(nodeIndex) {
33144	        const self1 = this;
33145	        const parser = this.parser;
33146	        const json = parser.json;
33147	        const nodeDef = json.nodes[nodeIndex];
33148	        const lightDef = nodeDef.extensions && nodeDef.extensions[this.name] || {};
33149	        const lightIndex = lightDef.light;
33150	        if (lightIndex === undefined) return null;
33151	        return this._loadLight(lightIndex).then(function(light) {
33152	            return parser._getNodeRef(self1.cache, lightIndex, light);
33153	        });
33154	    }
33155	    constructor(parser){
33156	        this.parser = parser;
33157	        this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;
33158	        // Object3D instance caches
33159	        this.cache = {
33160	            refs: {},
33161	            uses: {}
33162	        };
33163	    }
33164	}
33165	/**
33166	 * Unlit Materials Extension
33167	 *
33168	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
33169	 */ let GLTFMaterialsUnlitExtension$1 = class GLTFMaterialsUnlitExtension {
33170	    getMaterialType() {
33171	        return MeshBasicMaterial;
33172	    }
33173	    extendParams(materialParams, materialDef, parser) {
33174	        const pending = [];
33175	        materialParams.color = new Color(1.0, 1.0, 1.0);
33176	        materialParams.opacity = 1.0;
33177	        const metallicRoughness = materialDef.pbrMetallicRoughness;
33178	        if (metallicRoughness) {
33179	            if (Array.isArray(metallicRoughness.baseColorFactor)) {
33180	                const array = metallicRoughness.baseColorFactor;
33181	                materialParams.color.setRGB(array[0], array[1], array[2], LinearSRGBColorSpace);
33182	                materialParams.opacity = array[3];
33183	            }
33184	            if (metallicRoughness.baseColorTexture !== undefined) {
33185	                pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace));
33186	            }
33187	        }
33188	        return Promise.all(pending);
33189	    }
33190	    constructor(){
33191	        this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;
33192	    }
33193	};
33194	/**
33195	 * Materials Emissive Strength Extension
33196	 *
33197	 * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
33198	 */ let GLTFMaterialsEmissiveStrengthExtension$1 = class GLTFMaterialsEmissiveStrengthExtension {
33199	    extendMaterialParams(materialIndex, materialParams) {
33200	        const parser = this.parser;
33201	        const materialDef = parser.json.materials[materialIndex];
33202	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33203	            return Promise.resolve();
33204	        }
33205	        const emissiveStrength = materialDef.extensions[this.name].emissiveStrength;
33206	        if (emissiveStrength !== undefined) {
33207	            materialParams.emissiveIntensity = emissiveStrength;
33208	        }
33209	        return Promise.resolve();
33210	    }
33211	    constructor(parser){
33212	        this.parser = parser;
33213	        this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;
33214	    }
33215	};
33216	/**
33217	 * Clearcoat Materials Extension
33218	 *
33219	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
33220	 */ let GLTFMaterialsClearcoatExtension$1 = class GLTFMaterialsClearcoatExtension {
33221	    getMaterialType(materialIndex) {
33222	        const parser = this.parser;
33223	        const materialDef = parser.json.materials[materialIndex];
33224	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33225	        return MeshPhysicalMaterial;
33226	    }
33227	    extendMaterialParams(materialIndex, materialParams) {
33228	        const parser = this.parser;
33229	        const materialDef = parser.json.materials[materialIndex];
33230	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33231	            return Promise.resolve();
33232	        }
33233	        const pending = [];
33234	        const extension = materialDef.extensions[this.name];
33235	        if (extension.clearcoatFactor !== undefined) {
33236	            materialParams.clearcoat = extension.clearcoatFactor;
33237	        }
33238	        if (extension.clearcoatTexture !== undefined) {
33239	            pending.push(parser.assignTexture(materialParams, 'clearcoatMap', extension.clearcoatTexture));
33240	        }
33241	        if (extension.clearcoatRoughnessFactor !== undefined) {
33242	            materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;
33243	        }
33244	        if (extension.clearcoatRoughnessTexture !== undefined) {
33245	            pending.push(parser.assignTexture(materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture));
33246	        }
33247	        if (extension.clearcoatNormalTexture !== undefined) {
33248	            pending.push(parser.assignTexture(materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture));
33249	            if (extension.clearcoatNormalTexture.scale !== undefined) {
33250	                const scale = extension.clearcoatNormalTexture.scale;
33251	                materialParams.clearcoatNormalScale = new Vector2(scale, scale);
33252	            }
33253	        }
33254	        return Promise.all(pending);
33255	    }
33256	    constructor(parser){
33257	        this.parser = parser;
33258	        this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
33259	    }
33260	};
33261	/**
33262	 * Materials dispersion Extension
33263	 *
33264	 * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_dispersion
33265	 */ let GLTFMaterialsDispersionExtension$1 = class GLTFMaterialsDispersionExtension {
33266	    getMaterialType(materialIndex) {
33267	        const parser = this.parser;
33268	        const materialDef = parser.json.materials[materialIndex];
33269	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33270	        return MeshPhysicalMaterial;
33271	    }
33272	    extendMaterialParams(materialIndex, materialParams) {
33273	        const parser = this.parser;
33274	        const materialDef = parser.json.materials[materialIndex];
33275	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33276	            return Promise.resolve();
33277	        }
33278	        const extension = materialDef.extensions[this.name];
33279	        materialParams.dispersion = extension.dispersion !== undefined ? extension.dispersion : 0;
33280	        return Promise.resolve();
33281	    }
33282	    constructor(parser){
33283	        this.parser = parser;
33284	        this.name = EXTENSIONS.KHR_MATERIALS_DISPERSION;
33285	    }
33286	};
33287	/**
33288	 * Iridescence Materials Extension
33289	 *
33290	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
33291	 */ let GLTFMaterialsIridescenceExtension$1 = class GLTFMaterialsIridescenceExtension {
33292	    getMaterialType(materialIndex) {
33293	        const parser = this.parser;
33294	        const materialDef = parser.json.materials[materialIndex];
33295	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33296	        return MeshPhysicalMaterial;
33297	    }
33298	    extendMaterialParams(materialIndex, materialParams) {
33299	        const parser = this.parser;
33300	        const materialDef = parser.json.materials[materialIndex];
33301	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33302	            return Promise.resolve();
33303	        }
33304	        const pending = [];
33305	        const extension = materialDef.extensions[this.name];
33306	        if (extension.iridescenceFactor !== undefined) {
33307	            materialParams.iridescence = extension.iridescenceFactor;
33308	        }
33309	        if (extension.iridescenceTexture !== undefined) {
33310	            pending.push(parser.assignTexture(materialParams, 'iridescenceMap', extension.iridescenceTexture));
33311	        }
33312	        if (extension.iridescenceIor !== undefined) {
33313	            materialParams.iridescenceIOR = extension.iridescenceIor;
33314	        }
33315	        if (materialParams.iridescenceThicknessRange === undefined) {
33316	            materialParams.iridescenceThicknessRange = [
33317	                100,
33318	                400
33319	            ];
33320	        }
33321	        if (extension.iridescenceThicknessMinimum !== undefined) {
33322	            materialParams.iridescenceThicknessRange[0] = extension.iridescenceThicknessMinimum;
33323	        }
33324	        if (extension.iridescenceThicknessMaximum !== undefined) {
33325	            materialParams.iridescenceThicknessRange[1] = extension.iridescenceThicknessMaximum;
33326	        }
33327	        if (extension.iridescenceThicknessTexture !== undefined) {
33328	            pending.push(parser.assignTexture(materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture));
33329	        }
33330	        return Promise.all(pending);
33331	    }
33332	    constructor(parser){
33333	        this.parser = parser;
33334	        this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;
33335	    }
33336	};
33337	/**
33338	 * Sheen Materials Extension
33339	 *
33340	 * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
33341	 */ let GLTFMaterialsSheenExtension$1 = class GLTFMaterialsSheenExtension {
33342	    getMaterialType(materialIndex) {
33343	        const parser = this.parser;
33344	        const materialDef = parser.json.materials[materialIndex];
33345	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33346	        return MeshPhysicalMaterial;
33347	    }
33348	    extendMaterialParams(materialIndex, materialParams) {
33349	        const parser = this.parser;
33350	        const materialDef = parser.json.materials[materialIndex];
33351	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33352	            return Promise.resolve();
33353	        }
33354	        const pending = [];
33355	        materialParams.sheenColor = new Color(0, 0, 0);
33356	        materialParams.sheenRoughness = 0;
33357	        materialParams.sheen = 1;
33358	        const extension = materialDef.extensions[this.name];
33359	        if (extension.sheenColorFactor !== undefined) {
33360	            const colorFactor = extension.sheenColorFactor;
33361	            materialParams.sheenColor.setRGB(colorFactor[0], colorFactor[1], colorFactor[2], LinearSRGBColorSpace);
33362	        }
33363	        if (extension.sheenRoughnessFactor !== undefined) {
33364	            materialParams.sheenRoughness = extension.sheenRoughnessFactor;
33365	        }
33366	        if (extension.sheenColorTexture !== undefined) {
33367	            pending.push(parser.assignTexture(materialParams, 'sheenColorMap', extension.sheenColorTexture, SRGBColorSpace));
33368	        }
33369	        if (extension.sheenRoughnessTexture !== undefined) {
33370	            pending.push(parser.assignTexture(materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture));
33371	        }
33372	        return Promise.all(pending);
33373	    }
33374	    constructor(parser){
33375	        this.parser = parser;
33376	        this.name = EXTENSIONS.KHR_MATERIALS_SHEEN;
33377	    }
33378	};
33379	/**
33380	 * Transmission Materials Extension
33381	 *
33382	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
33383	 * Draft: https://github.com/KhronosGroup/glTF/pull/1698
33384	 */ let GLTFMaterialsTransmissionExtension$1 = class GLTFMaterialsTransmissionExtension {
33385	    getMaterialType(materialIndex) {
33386	        const parser = this.parser;
33387	        const materialDef = parser.json.materials[materialIndex];
33388	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33389	        return MeshPhysicalMaterial;
33390	    }
33391	    extendMaterialParams(materialIndex, materialParams) {
33392	        const parser = this.parser;
33393	        const materialDef = parser.json.materials[materialIndex];
33394	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33395	            return Promise.resolve();
33396	        }
33397	        const pending = [];
33398	        const extension = materialDef.extensions[this.name];
33399	        if (extension.transmissionFactor !== undefined) {
33400	            materialParams.transmission = extension.transmissionFactor;
33401	        }
33402	        if (extension.transmissionTexture !== undefined) {
33403	            pending.push(parser.assignTexture(materialParams, 'transmissionMap', extension.transmissionTexture));
33404	        }
33405	        return Promise.all(pending);
33406	    }
33407	    constructor(parser){
33408	        this.parser = parser;
33409	        this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;
33410	    }
33411	};
33412	/**
33413	 * Materials Volume Extension
33414	 *
33415	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
33416	 */ let GLTFMaterialsVolumeExtension$1 = class GLTFMaterialsVolumeExtension {
33417	    getMaterialType(materialIndex) {
33418	        const parser = this.parser;
33419	        const materialDef = parser.json.materials[materialIndex];
33420	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33421	        return MeshPhysicalMaterial;
33422	    }
33423	    extendMaterialParams(materialIndex, materialParams) {
33424	        const parser = this.parser;
33425	        const materialDef = parser.json.materials[materialIndex];
33426	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33427	            return Promise.resolve();
33428	        }
33429	        const pending = [];
33430	        const extension = materialDef.extensions[this.name];
33431	        materialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0;
33432	        if (extension.thicknessTexture !== undefined) {
33433	            pending.push(parser.assignTexture(materialParams, 'thicknessMap', extension.thicknessTexture));
33434	        }
33435	        materialParams.attenuationDistance = extension.attenuationDistance || Infinity;
33436	        const colorArray = extension.attenuationColor || [
33437	            1,
33438	            1,
33439	            1
33440	        ];
33441	        materialParams.attenuationColor = new Color().setRGB(colorArray[0], colorArray[1], colorArray[2], LinearSRGBColorSpace);
33442	        return Promise.all(pending);
33443	    }
33444	    constructor(parser){
33445	        this.parser = parser;
33446	        this.name = EXTENSIONS.KHR_MATERIALS_VOLUME;
33447	    }
33448	};
33449	/**
33450	 * Materials ior Extension
33451	 *
33452	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
33453	 */ let GLTFMaterialsIorExtension$1 = class GLTFMaterialsIorExtension {
33454	    getMaterialType(materialIndex) {
33455	        const parser = this.parser;
33456	        const materialDef = parser.json.materials[materialIndex];
33457	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33458	        return MeshPhysicalMaterial;
33459	    }
33460	    extendMaterialParams(materialIndex, materialParams) {
33461	        const parser = this.parser;
33462	        const materialDef = parser.json.materials[materialIndex];
33463	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33464	            return Promise.resolve();
33465	        }
33466	        const extension = materialDef.extensions[this.name];
33467	        materialParams.ior = extension.ior !== undefined ? extension.ior : 1.5;
33468	        return Promise.resolve();
33469	    }
33470	    constructor(parser){
33471	        this.parser = parser;
33472	        this.name = EXTENSIONS.KHR_MATERIALS_IOR;
33473	    }
33474	};
33475	/**
33476	 * Materials specular Extension
33477	 *
33478	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
33479	 */ let GLTFMaterialsSpecularExtension$1 = class GLTFMaterialsSpecularExtension {
33480	    getMaterialType(materialIndex) {
33481	        const parser = this.parser;
33482	        const materialDef = parser.json.materials[materialIndex];
33483	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33484	        return MeshPhysicalMaterial;
33485	    }
33486	    extendMaterialParams(materialIndex, materialParams) {
33487	        const parser = this.parser;
33488	        const materialDef = parser.json.materials[materialIndex];
33489	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33490	            return Promise.resolve();
33491	        }
33492	        const pending = [];
33493	        const extension = materialDef.extensions[this.name];
33494	        materialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0;
33495	        if (extension.specularTexture !== undefined) {
33496	            pending.push(parser.assignTexture(materialParams, 'specularIntensityMap', extension.specularTexture));
33497	        }
33498	        const colorArray = extension.specularColorFactor || [
33499	            1,
33500	            1,
33501	            1
33502	        ];
33503	        materialParams.specularColor = new Color().setRGB(colorArray[0], colorArray[1], colorArray[2], LinearSRGBColorSpace);
33504	        if (extension.specularColorTexture !== undefined) {
33505	            pending.push(parser.assignTexture(materialParams, 'specularColorMap', extension.specularColorTexture, SRGBColorSpace));
33506	        }
33507	        return Promise.all(pending);
33508	    }
33509	    constructor(parser){
33510	        this.parser = parser;
33511	        this.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;
33512	    }
33513	};
33514	/**
33515	 * Materials bump Extension
33516	 *
33517	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
33518	 */ let GLTFMaterialsBumpExtension$1 = class GLTFMaterialsBumpExtension {
33519	    getMaterialType(materialIndex) {
33520	        const parser = this.parser;
33521	        const materialDef = parser.json.materials[materialIndex];
33522	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33523	        return MeshPhysicalMaterial;
33524	    }
33525	    extendMaterialParams(materialIndex, materialParams) {
33526	        const parser = this.parser;
33527	        const materialDef = parser.json.materials[materialIndex];
33528	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33529	            return Promise.resolve();
33530	        }
33531	        const pending = [];
33532	        const extension = materialDef.extensions[this.name];
33533	        materialParams.bumpScale = extension.bumpFactor !== undefined ? extension.bumpFactor : 1.0;
33534	        if (extension.bumpTexture !== undefined) {
33535	            pending.push(parser.assignTexture(materialParams, 'bumpMap', extension.bumpTexture));
33536	        }
33537	        return Promise.all(pending);
33538	    }
33539	    constructor(parser){
33540	        this.parser = parser;
33541	        this.name = EXTENSIONS.EXT_MATERIALS_BUMP;
33542	    }
33543	};
33544	/**
33545	 * Materials anisotropy Extension
33546	 *
33547	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_anisotropy
33548	 */ let GLTFMaterialsAnisotropyExtension$1 = class GLTFMaterialsAnisotropyExtension {
33549	    getMaterialType(materialIndex) {
33550	        const parser = this.parser;
33551	        const materialDef = parser.json.materials[materialIndex];
33552	        if (!materialDef.extensions || !materialDef.extensions[this.name]) return null;
33553	        return MeshPhysicalMaterial;
33554	    }
33555	    extendMaterialParams(materialIndex, materialParams) {
33556	        const parser = this.parser;
33557	        const materialDef = parser.json.materials[materialIndex];
33558	        if (!materialDef.extensions || !materialDef.extensions[this.name]) {
33559	            return Promise.resolve();
33560	        }
33561	        const pending = [];
33562	        const extension = materialDef.extensions[this.name];
33563	        if (extension.anisotropyStrength !== undefined) {
33564	            materialParams.anisotropy = extension.anisotropyStrength;
33565	        }
33566	        if (extension.anisotropyRotation !== undefined) {
33567	            materialParams.anisotropyRotation = extension.anisotropyRotation;
33568	        }
33569	        if (extension.anisotropyTexture !== undefined) {
33570	            pending.push(parser.assignTexture(materialParams, 'anisotropyMap', extension.anisotropyTexture));
33571	        }
33572	        return Promise.all(pending);
33573	    }
33574	    constructor(parser){
33575	        this.parser = parser;
33576	        this.name = EXTENSIONS.KHR_MATERIALS_ANISOTROPY;
33577	    }
33578	};
33579	/**
33580	 * BasisU Texture Extension
33581	 *
33582	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
33583	 */ class GLTFTextureBasisUExtension {
33584	    loadTexture(textureIndex) {
33585	        const parser = this.parser;
33586	        const json = parser.json;
33587	        const textureDef = json.textures[textureIndex];
33588	        if (!textureDef.extensions || !textureDef.extensions[this.name]) {
33589	            return null;
33590	        }
33591	        const extension = textureDef.extensions[this.name];
33592	        const loader = parser.options.ktx2Loader;
33593	        if (!loader) {
33594	            if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
33595	                throw new Error('THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures');
33596	            } else {
33597	                // Assumes that the extension is optional and that a fallback texture is present
33598	                return null;
33599	            }
33600	        }
33601	        return parser.loadTextureImage(textureIndex, extension.source, loader);
33602	    }
33603	    constructor(parser){
33604	        this.parser = parser;
33605	        this.name = EXTENSIONS.KHR_TEXTURE_BASISU;
33606	    }
33607	}
33608	/**
33609	 * WebP Texture Extension
33610	 *
33611	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp
33612	 */ class GLTFTextureWebPExtension {
33613	    loadTexture(textureIndex) {
33614	        const name = this.name;
33615	        const parser = this.parser;
33616	        const json = parser.json;
33617	        const textureDef = json.textures[textureIndex];
33618	        if (!textureDef.extensions || !textureDef.extensions[name]) {
33619	            return null;
33620	        }
33621	        const extension = textureDef.extensions[name];
33622	        const source = json.images[extension.source];
33623	        let loader = parser.textureLoader;
33624	        if (source.uri) {
33625	            const handler = parser.options.manager.getHandler(source.uri);
33626	            if (handler !== null) loader = handler;
33627	        }
33628	        return this.detectSupport().then(function(isSupported) {
33629	            if (isSupported) return parser.loadTextureImage(textureIndex, extension.source, loader);
33630	            if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
33631	                throw new Error('THREE.GLTFLoader: WebP required by asset but unsupported.');
33632	            }
33633	            // Fall back to PNG or JPEG.
33634	            return parser.loadTexture(textureIndex);
33635	        });
33636	    }
33637	    detectSupport() {
33638	        if (!this.isSupported) {
33639	            this.isSupported = new Promise(function(resolve) {
33640	                const image = new Image();
33641	                // Lossy test image. Support for lossy images doesn't guarantee support for all
33642	                // WebP images, unfortunately.
33643	                image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
33644	                image.onload = image.onerror = function() {
33645	                    resolve(image.height === 1);
33646	                };
33647	            });
33648	        }
33649	        return this.isSupported;
33650	    }
33651	    constructor(parser){
33652	        this.parser = parser;
33653	        this.name = EXTENSIONS.EXT_TEXTURE_WEBP;
33654	        this.isSupported = null;
33655	    }
33656	}
33657	/**
33658	 * AVIF Texture Extension
33659	 *
33660	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_avif
33661	 */ class GLTFTextureAVIFExtension {
33662	    loadTexture(textureIndex) {
33663	        const name = this.name;
33664	        const parser = this.parser;
33665	        const json = parser.json;
33666	        const textureDef = json.textures[textureIndex];
33667	        if (!textureDef.extensions || !textureDef.extensions[name]) {
33668	            return null;
33669	        }
33670	        const extension = textureDef.extensions[name];
33671	        const source = json.images[extension.source];
33672	        let loader = parser.textureLoader;
33673	        if (source.uri) {
33674	            const handler = parser.options.manager.getHandler(source.uri);
33675	            if (handler !== null) loader = handler;
33676	        }
33677	        return this.detectSupport().then(function(isSupported) {
33678	            if (isSupported) return parser.loadTextureImage(textureIndex, extension.source, loader);
33679	            if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
33680	                throw new Error('THREE.GLTFLoader: AVIF required by asset but unsupported.');
33681	            }
33682	            // Fall back to PNG or JPEG.
33683	            return parser.loadTexture(textureIndex);
33684	        });
33685	    }
33686	    detectSupport() {
33687	        if (!this.isSupported) {
33688	            this.isSupported = new Promise(function(resolve) {
33689	                const image = new Image();
33690	                // Lossy test image.
33691	                image.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdj
vendor: 4,621 bytes, lines 33691-33791
33691FDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=';
33692	                image.onload = image.onerror = function() {
33693	                    resolve(image.height === 1);
33694	                };
33695	            });
33696	        }
33697	        return this.isSupported;
33698	    }
33699	    constructor(parser){
33700	        this.parser = parser;
33701	        this.name = EXTENSIONS.EXT_TEXTURE_AVIF;
33702	        this.isSupported = null;
33703	    }
33704	}
33705	/**
33706	 * meshopt BufferView Compression Extension
33707	 *
33708	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
33709	 */ class GLTFMeshoptCompression {
33710	    loadBufferView(index) {
33711	        const json = this.parser.json;
33712	        const bufferView = json.bufferViews[index];
33713	        if (bufferView.extensions && bufferView.extensions[this.name]) {
33714	            const extensionDef = bufferView.extensions[this.name];
33715	            const buffer = this.parser.getDependency('buffer', extensionDef.buffer);
33716	            const decoder = this.parser.options.meshoptDecoder;
33717	            if (!decoder || !decoder.supported) {
33718	                if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
33719	                    throw new Error('THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files');
33720	                } else {
33721	                    // Assumes that the extension is optional and that fallback buffer data is present
33722	                    return null;
33723	                }
33724	            }
33725	            return buffer.then(function(res) {
33726	                const byteOffset = extensionDef.byteOffset || 0;
33727	                const byteLength = extensionDef.byteLength || 0;
33728	                const count = extensionDef.count;
33729	                const stride = extensionDef.byteStride;
33730	                const source = new Uint8Array(res, byteOffset, byteLength);
33731	                if (decoder.decodeGltfBufferAsync) {
33732	                    return decoder.decodeGltfBufferAsync(count, stride, source, extensionDef.mode, extensionDef.filter).then(function(res) {
33733	                        return res.buffer;
33734	                    });
33735	                } else {
33736	                    // Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync
33737	                    return decoder.ready.then(function() {
33738	                        const result = new ArrayBuffer(count * stride);
33739	                        decoder.decodeGltfBuffer(new Uint8Array(result), count, stride, source, extensionDef.mode, extensionDef.filter);
33740	                        return result;
33741	                    });
33742	                }
33743	            });
33744	        } else {
33745	            return null;
33746	        }
33747	    }
33748	    constructor(parser){
33749	        this.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION;
33750	        this.parser = parser;
33751	    }
33752	}
33753	/**
33754	 * GPU Instancing Extension
33755	 *
33756	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
33757	 *
33758	 */ let GLTFMeshGpuInstancing$1 = class GLTFMeshGpuInstancing {
33759	    createNodeMesh(nodeIndex) {
33760	        const json = this.parser.json;
33761	        const nodeDef = json.nodes[nodeIndex];
33762	        if (!nodeDef.extensions || !nodeDef.extensions[this.name] || nodeDef.mesh === undefined) {
33763	            return null;
33764	        }
33765	        const meshDef = json.meshes[nodeDef.mesh];
33766	        // No Points or Lines + Instancing support yet
33767	        for (const primitive of meshDef.primitives){
33768	            if (primitive.mode !== WEBGL_CONSTANTS$1.TRIANGLES && primitive.mode !== WEBGL_CONSTANTS$1.TRIANGLE_STRIP && primitive.mode !== WEBGL_CONSTANTS$1.TRIANGLE_FAN && primitive.mode !== undefined) {
33769	                return null;
33770	            }
33771	        }
33772	        const extensionDef = nodeDef.extensions[this.name];
33773	        const attributesDef = extensionDef.attributes;
33774	        // @TODO: Can we support InstancedMesh + SkinnedMesh?
33775	        const pending = [];
33776	        const attributes = {};
33777	        for(const key in attributesDef){
33778	            pending.push(this.parser.getDependency('accessor', attributesDef[key]).then((accessor)=>{
33779	                attributes[key] = accessor;
33780	                return attributes[key];
33781	            }));
33782	        }
33783	        if (pending.length < 1) {
33784	            return null;
33785	        }
33786	        pending.push(this.parser.createNodeMesh(nodeIndex));
33787	        return Promise.all(pending).then((results)=>{
33788	            const nodeObject = results.pop();
33789	            const meshes = nodeObject.isGroup ? nodeObject.children : [
33790	                nodeObject
33791	            ];
vendor: 13,399 bytes, lines 33792-34112
33792	            const count = results[0].count; // All attribute counts should be same
33793	            const instancedMeshes = [];
33794	            for (const mesh of meshes){
33795	                // Temporal variables
33796	                const m = new Matrix4();
33797	                const p = new Vector3();
33798	                const q = new Quaternion();
33799	                const s = new Vector3(1, 1, 1);
33800	                const instancedMesh = new InstancedMesh(mesh.geometry, mesh.material, count);
33801	                for(let i = 0; i < count; i++){
33802	                    if (attributes.TRANSLATION) {
33803	                        p.fromBufferAttribute(attributes.TRANSLATION, i);
33804	                    }
33805	                    if (attributes.ROTATION) {
33806	                        q.fromBufferAttribute(attributes.ROTATION, i);
33807	                    }
33808	                    if (attributes.SCALE) {
33809	                        s.fromBufferAttribute(attributes.SCALE, i);
33810	                    }
33811	                    instancedMesh.setMatrixAt(i, m.compose(p, q, s));
33812	                }
33813	                // Add instance attributes to the geometry, excluding TRS.
33814	                for(const attributeName in attributes){
33815	                    if (attributeName === '_COLOR_0') {
33816	                        const attr = attributes[attributeName];
33817	                        instancedMesh.instanceColor = new InstancedBufferAttribute(attr.array, attr.itemSize, attr.normalized);
33818	                    } else if (attributeName !== 'TRANSLATION' && attributeName !== 'ROTATION' && attributeName !== 'SCALE') {
33819	                        mesh.geometry.setAttribute(attributeName, attributes[attributeName]);
33820	                    }
33821	                }
33822	                // Just in case
33823	                Object3D.prototype.copy.call(instancedMesh, mesh);
33824	                this.parser.assignFinalMaterial(instancedMesh);
33825	                instancedMeshes.push(instancedMesh);
33826	            }
33827	            if (nodeObject.isGroup) {
33828	                nodeObject.clear();
33829	                nodeObject.add(...instancedMeshes);
33830	                return nodeObject;
33831	            }
33832	            return instancedMeshes[0];
33833	        });
33834	    }
33835	    constructor(parser){
33836	        this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;
33837	        this.parser = parser;
33838	    }
33839	};
33840	/* BINARY EXTENSION */ const BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
33841	const BINARY_EXTENSION_HEADER_LENGTH = 12;
33842	const BINARY_EXTENSION_CHUNK_TYPES = {
33843	    JSON: 0x4E4F534A,
33844	    BIN: 0x004E4942
33845	};
33846	class GLTFBinaryExtension {
33847	    constructor(data){
33848	        this.name = EXTENSIONS.KHR_BINARY_GLTF;
33849	        this.content = null;
33850	        this.body = null;
33851	        const headerView = new DataView(data, 0, BINARY_EXTENSION_HEADER_LENGTH);
33852	        const textDecoder = new TextDecoder();
33853	        this.header = {
33854	            magic: textDecoder.decode(new Uint8Array(data.slice(0, 4))),
33855	            version: headerView.getUint32(4, true),
33856	            length: headerView.getUint32(8, true)
33857	        };
33858	        if (this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC) {
33859	            throw new Error('THREE.GLTFLoader: Unsupported glTF-Binary header.');
33860	        } else if (this.header.version < 2.0) {
33861	            throw new Error('THREE.GLTFLoader: Legacy binary file detected.');
33862	        }
33863	        const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;
33864	        const chunkView = new DataView(data, BINARY_EXTENSION_HEADER_LENGTH);
33865	        let chunkIndex = 0;
33866	        while(chunkIndex < chunkContentsLength){
33867	            const chunkLength = chunkView.getUint32(chunkIndex, true);
33868	            chunkIndex += 4;
33869	            const chunkType = chunkView.getUint32(chunkIndex, true);
33870	            chunkIndex += 4;
33871	            if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON) {
33872	                const contentArray = new Uint8Array(data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength);
33873	                this.content = textDecoder.decode(contentArray);
33874	            } else if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN) {
33875	                const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
33876	                this.body = data.slice(byteOffset, byteOffset + chunkLength);
33877	            }
33878	            // Clients must ignore chunks with unknown types.
33879	            chunkIndex += chunkLength;
33880	        }
33881	        if (this.content === null) {
33882	            throw new Error('THREE.GLTFLoader: JSON content not found.');
33883	        }
33884	    }
33885	}
33886	/**
33887	 * DRACO Mesh Compression Extension
33888	 *
33889	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
33890	 */ class GLTFDracoMeshCompressionExtension {
33891	    decodePrimitive(primitive, parser) {
33892	        const json = this.json;
33893	        const dracoLoader = this.dracoLoader;
33894	        const bufferViewIndex = primitive.extensions[this.name].bufferView;
33895	        const gltfAttributeMap = primitive.extensions[this.name].attributes;
33896	        const threeAttributeMap = {};
33897	        const attributeNormalizedMap = {};
33898	        const attributeTypeMap = {};
33899	        for(const attributeName in gltfAttributeMap){
33900	            const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase();
33901	            threeAttributeMap[threeAttributeName] = gltfAttributeMap[attributeName];
33902	        }
33903	        for(const attributeName in primitive.attributes){
33904	            const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase();
33905	            if (gltfAttributeMap[attributeName] !== undefined) {
33906	                const accessorDef = json.accessors[primitive.attributes[attributeName]];
33907	                const componentType = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
33908	                attributeTypeMap[threeAttributeName] = componentType.name;
33909	                attributeNormalizedMap[threeAttributeName] = accessorDef.normalized === true;
33910	            }
33911	        }
33912	        return parser.getDependency('bufferView', bufferViewIndex).then(function(bufferView) {
33913	            return new Promise(function(resolve, reject) {
33914	                dracoLoader.decodeDracoFile(bufferView, function(geometry) {
33915	                    for(const attributeName in geometry.attributes){
33916	                        const attribute = geometry.attributes[attributeName];
33917	                        const normalized = attributeNormalizedMap[attributeName];
33918	                        if (normalized !== undefined) attribute.normalized = normalized;
33919	                    }
33920	                    resolve(geometry);
33921	                }, threeAttributeMap, attributeTypeMap, LinearSRGBColorSpace, reject);
33922	            });
33923	        });
33924	    }
33925	    constructor(json, dracoLoader){
33926	        if (!dracoLoader) {
33927	            throw new Error('THREE.GLTFLoader: No DRACOLoader instance provided.');
33928	        }
33929	        this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
33930	        this.json = json;
33931	        this.dracoLoader = dracoLoader;
33932	        this.dracoLoader.preload();
33933	    }
33934	}
33935	/**
33936	 * Texture Transform Extension
33937	 *
33938	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform
33939	 */ class GLTFTextureTransformExtension {
33940	    extendTexture(texture, transform) {
33941	        if ((transform.texCoord === undefined || transform.texCoord === texture.channel) && transform.offset === undefined && transform.rotation === undefined && transform.scale === undefined) {
33942	            // See https://github.com/mrdoob/three.js/issues/21819.
33943	            return texture;
33944	        }
33945	        texture = texture.clone();
33946	        if (transform.texCoord !== undefined) {
33947	            texture.channel = transform.texCoord;
33948	        }
33949	        if (transform.offset !== undefined) {
33950	            texture.offset.fromArray(transform.offset);
33951	        }
33952	        if (transform.rotation !== undefined) {
33953	            texture.rotation = transform.rotation;
33954	        }
33955	        if (transform.scale !== undefined) {
33956	            texture.repeat.fromArray(transform.scale);
33957	        }
33958	        texture.needsUpdate = true;
33959	        return texture;
33960	    }
33961	    constructor(){
33962	        this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;
33963	    }
33964	}
33965	/**
33966	 * Mesh Quantization Extension
33967	 *
33968	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization
33969	 */ class GLTFMeshQuantizationExtension {
33970	    constructor(){
33971	        this.name = EXTENSIONS.KHR_MESH_QUANTIZATION;
33972	    }
33973	}
33974	/*********************************/ /********** INTERPOLATION ********/ /*********************************/ // Spline Interpolation
33975	// Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation
33976	class GLTFCubicSplineInterpolant extends Interpolant {
33977	    copySampleValue_(index) {
33978	        // Copies a sample value to the result buffer. See description of glTF
33979	        // CUBICSPLINE values layout in interpolate_() function below.
33980	        const result = this.resultBuffer, values = this.sampleValues, valueSize = this.valueSize, offset = index * valueSize * 3 + valueSize;
33981	        for(let i = 0; i !== valueSize; i++){
33982	            result[i] = values[offset + i];
33983	        }
33984	        return result;
33985	    }
33986	    interpolate_(i1, t0, t, t1) {
33987	        const result = this.resultBuffer;
33988	        const values = this.sampleValues;
33989	        const stride = this.valueSize;
33990	        const stride2 = stride * 2;
33991	        const stride3 = stride * 3;
33992	        const td = t1 - t0;
33993	        const p = (t - t0) / td;
33994	        const pp = p * p;
33995	        const ppp = pp * p;
33996	        const offset1 = i1 * stride3;
33997	        const offset0 = offset1 - stride3;
33998	        const s2 = -2 * ppp + 3 * pp;
33999	        const s3 = ppp - pp;
34000	        const s0 = 1 - s2;
34001	        const s1 = s3 - pp + p;
34002	        // Layout of keyframe output values for CUBICSPLINE animations:
34003	        //   [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
34004	        for(let i = 0; i !== stride; i++){
34005	            const p0 = values[offset0 + i + stride]; // splineVertex_k
34006	            const m0 = values[offset0 + i + stride2] * td; // outTangent_k * (t_k+1 - t_k)
34007	            const p1 = values[offset1 + i + stride]; // splineVertex_k+1
34008	            const m1 = values[offset1 + i] * td; // inTangent_k+1 * (t_k+1 - t_k)
34009	            result[i] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
34010	        }
34011	        return result;
34012	    }
34013	    constructor(parameterPositions, sampleValues, sampleSize, resultBuffer){
34014	        super(parameterPositions, sampleValues, sampleSize, resultBuffer);
34015	    }
34016	}
34017	const _q = new Quaternion();
34018	class GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {
34019	    interpolate_(i1, t0, t, t1) {
34020	        const result = super.interpolate_(i1, t0, t, t1);
34021	        _q.fromArray(result).normalize().toArray(result);
34022	        return result;
34023	    }
34024	}
34025	/*********************************/ /********** INTERNALS ************/ /*********************************/ /* CONSTANTS */ const WEBGL_CONSTANTS$1 = {
34026	    POINTS: 0,
34027	    LINES: 1,
34028	    LINE_LOOP: 2,
34029	    LINE_STRIP: 3,
34030	    TRIANGLES: 4,
34031	    TRIANGLE_STRIP: 5,
34032	    TRIANGLE_FAN: 6};
34033	const WEBGL_COMPONENT_TYPES = {
34034	    5120: Int8Array,
34035	    5121: Uint8Array,
34036	    5122: Int16Array,
34037	    5123: Uint16Array,
34038	    5125: Uint32Array,
34039	    5126: Float32Array
34040	};
34041	const WEBGL_FILTERS = {
34042	    9728: NearestFilter,
34043	    9729: LinearFilter,
34044	    9984: NearestMipmapNearestFilter,
34045	    9985: LinearMipmapNearestFilter,
34046	    9986: NearestMipmapLinearFilter,
34047	    9987: LinearMipmapLinearFilter
34048	};
34049	const WEBGL_WRAPPINGS = {
34050	    33071: ClampToEdgeWrapping,
34051	    33648: MirroredRepeatWrapping,
34052	    10497: RepeatWrapping
34053	};
34054	const WEBGL_TYPE_SIZES = {
34055	    'SCALAR': 1,
34056	    'VEC2': 2,
34057	    'VEC3': 3,
34058	    'VEC4': 4,
34059	    'MAT2': 4,
34060	    'MAT3': 9,
34061	    'MAT4': 16
34062	};
34063	const ATTRIBUTES = {
34064	    POSITION: 'position',
34065	    NORMAL: 'normal',
34066	    TANGENT: 'tangent',
34067	    TEXCOORD_0: 'uv',
34068	    TEXCOORD_1: 'uv1',
34069	    TEXCOORD_2: 'uv2',
34070	    TEXCOORD_3: 'uv3',
34071	    COLOR_0: 'color',
34072	    WEIGHTS_0: 'skinWeight',
34073	    JOINTS_0: 'skinIndex'
34074	};
34075	const PATH_PROPERTIES$1 = {
34076	    scale: 'scale',
34077	    translation: 'position',
34078	    rotation: 'quaternion',
34079	    weights: 'morphTargetInfluences'
34080	};
34081	const INTERPOLATION = {
34082	    CUBICSPLINE: undefined,
34083	    // keyframe track will be initialized with a default interpolation type, then modified.
34084	    LINEAR: InterpolateLinear,
34085	    STEP: InterpolateDiscrete
34086	};
34087	const ALPHA_MODES = {
34088	    OPAQUE: 'OPAQUE',
34089	    MASK: 'MASK',
34090	    BLEND: 'BLEND'
34091	};
34092	/**
34093	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
34094	 *
34095	 * @param {Object<string, Material>} cache
34096	 * @return {Material}
34097	 */ function createDefaultMaterial(cache) {
34098	    if (cache['DefaultMaterial'] === undefined) {
34099	        cache['DefaultMaterial'] = new MeshStandardMaterial({
34100	            color: 0xFFFFFF,
34101	            emissive: 0x000000,
34102	            metalness: 1,
34103	            roughness: 1,
34104	            transparent: false,
34105	            depthTest: true,
34106	            side: FrontSide
34107	        });
34108	    }
34109	    return cache['DefaultMaterial'];
34110	}
34111	function addUnknownExtensionsToUserData(knownExtensions, object, objectDef) {
34112	    // Add unknown glTF extensions to an object's userData.
vendor: 5,010 bytes, lines 34113-34223
34113	    for(const name in objectDef.extensions){
34114	        if (knownExtensions[name] === undefined) {
34115	            object.userData.gltfExtensions = object.userData.gltfExtensions || {};
34116	            object.userData.gltfExtensions[name] = objectDef.extensions[name];
34117	        }
34118	    }
34119	}
34120	/**
34121	 * @param {Object3D|Material|BufferGeometry} object
34122	 * @param {GLTF.definition} gltfDef
34123	 */ function assignExtrasToUserData(object, gltfDef) {
34124	    if (gltfDef.extras !== undefined) {
34125	        if (typeof gltfDef.extras === 'object') {
34126	            Object.assign(object.userData, gltfDef.extras);
34127	        } else {
34128	            console.warn('THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras);
34129	        }
34130	    }
34131	}
34132	/**
34133	 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
34134	 *
34135	 * @param {BufferGeometry} geometry
34136	 * @param {Array<GLTF.Target>} targets
34137	 * @param {GLTFParser} parser
34138	 * @return {Promise<BufferGeometry>}
34139	 */ function addMorphTargets(geometry, targets, parser) {
34140	    let hasMorphPosition = false;
34141	    let hasMorphNormal = false;
34142	    let hasMorphColor = false;
34143	    for(let i = 0, il = targets.length; i < il; i++){
34144	        const target = targets[i];
34145	        if (target.POSITION !== undefined) hasMorphPosition = true;
34146	        if (target.NORMAL !== undefined) hasMorphNormal = true;
34147	        if (target.COLOR_0 !== undefined) hasMorphColor = true;
34148	        if (hasMorphPosition && hasMorphNormal && hasMorphColor) break;
34149	    }
34150	    if (!hasMorphPosition && !hasMorphNormal && !hasMorphColor) return Promise.resolve(geometry);
34151	    const pendingPositionAccessors = [];
34152	    const pendingNormalAccessors = [];
34153	    const pendingColorAccessors = [];
34154	    for(let i = 0, il = targets.length; i < il; i++){
34155	        const target = targets[i];
34156	        if (hasMorphPosition) {
34157	            const pendingAccessor = target.POSITION !== undefined ? parser.getDependency('accessor', target.POSITION) : geometry.attributes.position;
34158	            pendingPositionAccessors.push(pendingAccessor);
34159	        }
34160	        if (hasMorphNormal) {
34161	            const pendingAccessor = target.NORMAL !== undefined ? parser.getDependency('accessor', target.NORMAL) : geometry.attributes.normal;
34162	            pendingNormalAccessors.push(pendingAccessor);
34163	        }
34164	        if (hasMorphColor) {
34165	            const pendingAccessor = target.COLOR_0 !== undefined ? parser.getDependency('accessor', target.COLOR_0) : geometry.attributes.color;
34166	            pendingColorAccessors.push(pendingAccessor);
34167	        }
34168	    }
34169	    return Promise.all([
34170	        Promise.all(pendingPositionAccessors),
34171	        Promise.all(pendingNormalAccessors),
34172	        Promise.all(pendingColorAccessors)
34173	    ]).then(function(accessors) {
34174	        const morphPositions = accessors[0];
34175	        const morphNormals = accessors[1];
34176	        const morphColors = accessors[2];
34177	        if (hasMorphPosition) geometry.morphAttributes.position = morphPositions;
34178	        if (hasMorphNormal) geometry.morphAttributes.normal = morphNormals;
34179	        if (hasMorphColor) geometry.morphAttributes.color = morphColors;
34180	        geometry.morphTargetsRelative = true;
34181	        return geometry;
34182	    });
34183	}
34184	/**
34185	 * @param {Mesh} mesh
34186	 * @param {GLTF.Mesh} meshDef
34187	 */ function updateMorphTargets(mesh, meshDef) {
34188	    mesh.updateMorphTargets();
34189	    if (meshDef.weights !== undefined) {
34190	        for(let i = 0, il = meshDef.weights.length; i < il; i++){
34191	            mesh.morphTargetInfluences[i] = meshDef.weights[i];
34192	        }
34193	    }
34194	    // .extras has user-defined data, so check that .extras.targetNames is an array.
34195	    if (meshDef.extras && Array.isArray(meshDef.extras.targetNames)) {
34196	        const targetNames = meshDef.extras.targetNames;
34197	        if (mesh.morphTargetInfluences.length === targetNames.length) {
34198	            mesh.morphTargetDictionary = {};
34199	            for(let i = 0, il = targetNames.length; i < il; i++){
34200	                mesh.morphTargetDictionary[targetNames[i]] = i;
34201	            }
34202	        } else {
34203	            console.warn('THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.');
34204	        }
34205	    }
34206	}
34207	function createPrimitiveKey(primitiveDef) {
34208	    let geometryKey;
34209	    const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION];
34210	    if (dracoExtension) {
34211	        geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey(dracoExtension.attributes);
34212	    } else {
34213	        geometryKey = primitiveDef.indices + ':' + createAttributesKey(primitiveDef.attributes) + ':' + primitiveDef.mode;
34214	    }
34215	    if (primitiveDef.targets !== undefined) {
34216	        for(let i = 0, il = primitiveDef.targets.length; i < il; i++){
34217	            geometryKey += ':' + createAttributesKey(primitiveDef.targets[i]);
34218	        }
34219	    }
34220	    return geometryKey;
34221	}
34222	function createAttributesKey(attributes) {
34223	    let attributesKey = '';
vendor: 15,606 bytes, lines 34224-34565
34224	    const keys = Object.keys(attributes).sort();
34225	    for(let i = 0, il = keys.length; i < il; i++){
34226	        attributesKey += keys[i] + ':' + attributes[keys[i]] + ';';
34227	    }
34228	    return attributesKey;
34229	}
34230	function getNormalizedComponentScale(constructor) {
34231	    // Reference:
34232	    // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data
34233	    switch(constructor){
34234	        case Int8Array:
34235	            return 1 / 127;
34236	        case Uint8Array:
34237	            return 1 / 255;
34238	        case Int16Array:
34239	            return 1 / 32767;
34240	        case Uint16Array:
34241	            return 1 / 65535;
34242	        default:
34243	            throw new Error('THREE.GLTFLoader: Unsupported normalized accessor component type.');
34244	    }
34245	}
34246	function getImageURIMimeType(uri) {
34247	    if (uri.search(/\.jpe?g($|\?)/i) > 0 || uri.search(/^data\:image\/jpeg/) === 0) return 'image/jpeg';
34248	    if (uri.search(/\.webp($|\?)/i) > 0 || uri.search(/^data\:image\/webp/) === 0) return 'image/webp';
34249	    if (uri.search(/\.ktx2($|\?)/i) > 0 || uri.search(/^data\:image\/ktx2/) === 0) return 'image/ktx2';
34250	    return 'image/png';
34251	}
34252	const _identityMatrix = new Matrix4();
34253	/* GLTF PARSER */ class GLTFParser {
34254	    setExtensions(extensions) {
34255	        this.extensions = extensions;
34256	    }
34257	    setPlugins(plugins) {
34258	        this.plugins = plugins;
34259	    }
34260	    parse(onLoad, onError) {
34261	        const parser = this;
34262	        const json = this.json;
34263	        const extensions = this.extensions;
34264	        // Clear the loader cache
34265	        this.cache.removeAll();
34266	        this.nodeCache = {};
34267	        // Mark the special nodes/meshes in json for efficient parse
34268	        this._invokeAll(function(ext) {
34269	            return ext._markDefs && ext._markDefs();
34270	        });
34271	        Promise.all(this._invokeAll(function(ext) {
34272	            return ext.beforeRoot && ext.beforeRoot();
34273	        })).then(function() {
34274	            return Promise.all([
34275	                parser.getDependencies('scene'),
34276	                parser.getDependencies('animation'),
34277	                parser.getDependencies('camera')
34278	            ]);
34279	        }).then(function(dependencies) {
34280	            const result = {
34281	                scene: dependencies[0][json.scene || 0],
34282	                scenes: dependencies[0],
34283	                animations: dependencies[1],
34284	                cameras: dependencies[2],
34285	                asset: json.asset,
34286	                parser: parser,
34287	                userData: {}
34288	            };
34289	            addUnknownExtensionsToUserData(extensions, result, json);
34290	            assignExtrasToUserData(result, json);
34291	            return Promise.all(parser._invokeAll(function(ext) {
34292	                return ext.afterRoot && ext.afterRoot(result);
34293	            })).then(function() {
34294	                for (const scene of result.scenes){
34295	                    scene.updateMatrixWorld();
34296	                }
34297	                onLoad(result);
34298	            });
34299	        }).catch(onError);
34300	    }
34301	    /**
34302		 * Marks the special nodes/meshes in json for efficient parse.
34303		 */ _markDefs() {
34304	        const nodeDefs = this.json.nodes || [];
34305	        const skinDefs = this.json.skins || [];
34306	        const meshDefs = this.json.meshes || [];
34307	        // Nothing in the node definition indicates whether it is a Bone or an
34308	        // Object3D. Use the skins' joint references to mark bones.
34309	        for(let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex++){
34310	            const joints = skinDefs[skinIndex].joints;
34311	            for(let i = 0, il = joints.length; i < il; i++){
34312	                nodeDefs[joints[i]].isBone = true;
34313	            }
34314	        }
34315	        // Iterate over all nodes, marking references to shared resources,
34316	        // as well as skeleton joints.
34317	        for(let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++){
34318	            const nodeDef = nodeDefs[nodeIndex];
34319	            if (nodeDef.mesh !== undefined) {
34320	                this._addNodeRef(this.meshCache, nodeDef.mesh);
34321	                // Nothing in the mesh definition indicates whether it is
34322	                // a SkinnedMesh or Mesh. Use the node's mesh reference
34323	                // to mark SkinnedMesh if node has skin.
34324	                if (nodeDef.skin !== undefined) {
34325	                    meshDefs[nodeDef.mesh].isSkinnedMesh = true;
34326	                }
34327	            }
34328	            if (nodeDef.camera !== undefined) {
34329	                this._addNodeRef(this.cameraCache, nodeDef.camera);
34330	            }
34331	        }
34332	    }
34333	    /**
34334		 * Counts references to shared node / Object3D resources. These resources
34335		 * can be reused, or "instantiated", at multiple nodes in the scene
34336		 * hierarchy. Mesh, Camera, and Light instances are instantiated and must
34337		 * be marked. Non-scenegraph resources (like Materials, Geometries, and
34338		 * Textures) can be reused directly and are not marked here.
34339		 *
34340		 * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
34341		 *
34342		 * @param {Object} cache
34343		 * @param {Object3D} index
34344		 */ _addNodeRef(cache, index) {
34345	        if (index === undefined) return;
34346	        if (cache.refs[index] === undefined) {
34347	            cache.refs[index] = cache.uses[index] = 0;
34348	        }
34349	        cache.refs[index]++;
34350	    }
34351	    /**
34352		 * Returns a reference to a shared resource, cloning it if necessary.
34353		 *
34354		 * @param {Object} cache
34355		 * @param {number} index
34356		 * @param {Object} object
34357		 * @return {Object}
34358		 */ _getNodeRef(cache, index, object) {
34359	        if (cache.refs[index] <= 1) return object;
34360	        const ref = object.clone();
34361	        // Propagates mappings to the cloned object, prevents mappings on the
34362	        // original object from being lost.
34363	        const updateMappings = (original, clone)=>{
34364	            const mappings = this.associations.get(original);
34365	            if (mappings != null) {
34366	                this.associations.set(clone, mappings);
34367	            }
34368	            for (const [i, child] of original.children.entries()){
34369	                updateMappings(child, clone.children[i]);
34370	            }
34371	        };
34372	        updateMappings(object, ref);
34373	        ref.name += '_instance_' + cache.uses[index]++;
34374	        return ref;
34375	    }
34376	    _invokeOne(func) {
34377	        const extensions = Object.values(this.plugins);
34378	        extensions.push(this);
34379	        for(let i = 0; i < extensions.length; i++){
34380	            const result = func(extensions[i]);
34381	            if (result) return result;
34382	        }
34383	        return null;
34384	    }
34385	    _invokeAll(func) {
34386	        const extensions = Object.values(this.plugins);
34387	        extensions.unshift(this);
34388	        const pending = [];
34389	        for(let i = 0; i < extensions.length; i++){
34390	            const result = func(extensions[i]);
34391	            if (result) pending.push(result);
34392	        }
34393	        return pending;
34394	    }
34395	    /**
34396		 * Requests the specified dependency asynchronously, with caching.
34397		 * @param {string} type
34398		 * @param {number} index
34399		 * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
34400		 */ getDependency(type, index) {
34401	        const cacheKey = type + ':' + index;
34402	        let dependency = this.cache.get(cacheKey);
34403	        if (!dependency) {
34404	            switch(type){
34405	                case 'scene':
34406	                    dependency = this.loadScene(index);
34407	                    break;
34408	                case 'node':
34409	                    dependency = this._invokeOne(function(ext) {
34410	                        return ext.loadNode && ext.loadNode(index);
34411	                    });
34412	                    break;
34413	                case 'mesh':
34414	                    dependency = this._invokeOne(function(ext) {
34415	                        return ext.loadMesh && ext.loadMesh(index);
34416	                    });
34417	                    break;
34418	                case 'accessor':
34419	                    dependency = this.loadAccessor(index);
34420	                    break;
34421	                case 'bufferView':
34422	                    dependency = this._invokeOne(function(ext) {
34423	                        return ext.loadBufferView && ext.loadBufferView(index);
34424	                    });
34425	                    break;
34426	                case 'buffer':
34427	                    dependency = this.loadBuffer(index);
34428	                    break;
34429	                case 'material':
34430	                    dependency = this._invokeOne(function(ext) {
34431	                        return ext.loadMaterial && ext.loadMaterial(index);
34432	                    });
34433	                    break;
34434	                case 'texture':
34435	                    dependency = this._invokeOne(function(ext) {
34436	                        return ext.loadTexture && ext.loadTexture(index);
34437	                    });
34438	                    break;
34439	                case 'skin':
34440	                    dependency = this.loadSkin(index);
34441	                    break;
34442	                case 'animation':
34443	                    dependency = this._invokeOne(function(ext) {
34444	                        return ext.loadAnimation && ext.loadAnimation(index);
34445	                    });
34446	                    break;
34447	                case 'camera':
34448	                    dependency = this.loadCamera(index);
34449	                    break;
34450	                default:
34451	                    dependency = this._invokeOne(function(ext) {
34452	                        return ext != this && ext.getDependency && ext.getDependency(type, index);
34453	                    });
34454	                    if (!dependency) {
34455	                        throw new Error('Unknown type: ' + type);
34456	                    }
34457	                    break;
34458	            }
34459	            this.cache.add(cacheKey, dependency);
34460	        }
34461	        return dependency;
34462	    }
34463	    /**
34464		 * Requests all dependencies of the specified type asynchronously, with caching.
34465		 * @param {string} type
34466		 * @return {Promise<Array<Object>>}
34467		 */ getDependencies(type) {
34468	        let dependencies = this.cache.get(type);
34469	        if (!dependencies) {
34470	            const parser = this;
34471	            const defs = this.json[type + (type === 'mesh' ? 'es' : 's')] || [];
34472	            dependencies = Promise.all(defs.map(function(def, index) {
34473	                return parser.getDependency(type, index);
34474	            }));
34475	            this.cache.add(type, dependencies);
34476	        }
34477	        return dependencies;
34478	    }
34479	    /**
34480		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
34481		 * @param {number} bufferIndex
34482		 * @return {Promise<ArrayBuffer>}
34483		 */ loadBuffer(bufferIndex) {
34484	        const bufferDef = this.json.buffers[bufferIndex];
34485	        const loader = this.fileLoader;
34486	        if (bufferDef.type && bufferDef.type !== 'arraybuffer') {
34487	            throw new Error('THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.');
34488	        }
34489	        // If present, GLB container is required to be the first buffer.
34490	        if (bufferDef.uri === undefined && bufferIndex === 0) {
34491	            return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body);
34492	        }
34493	        const options = this.options;
34494	        return new Promise(function(resolve, reject) {
34495	            loader.load(LoaderUtils.resolveURL(bufferDef.uri, options.path), resolve, undefined, function() {
34496	                reject(new Error('THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".'));
34497	            });
34498	        });
34499	    }
34500	    /**
34501		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
34502		 * @param {number} bufferViewIndex
34503		 * @return {Promise<ArrayBuffer>}
34504		 */ loadBufferView(bufferViewIndex) {
34505	        const bufferViewDef = this.json.bufferViews[bufferViewIndex];
34506	        return this.getDependency('buffer', bufferViewDef.buffer).then(function(buffer) {
34507	            const byteLength = bufferViewDef.byteLength || 0;
34508	            const byteOffset = bufferViewDef.byteOffset || 0;
34509	            return buffer.slice(byteOffset, byteOffset + byteLength);
34510	        });
34511	    }
34512	    /**
34513		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
34514		 * @param {number} accessorIndex
34515		 * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
34516		 */ loadAccessor(accessorIndex) {
34517	        const parser = this;
34518	        const json = this.json;
34519	        const accessorDef = this.json.accessors[accessorIndex];
34520	        if (accessorDef.bufferView === undefined && accessorDef.sparse === undefined) {
34521	            const itemSize = WEBGL_TYPE_SIZES[accessorDef.type];
34522	            const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
34523	            const normalized = accessorDef.normalized === true;
34524	            const array = new TypedArray(accessorDef.count * itemSize);
34525	            return Promise.resolve(new BufferAttribute(array, itemSize, normalized));
34526	        }
34527	        const pendingBufferViews = [];
34528	        if (accessorDef.bufferView !== undefined) {
34529	            pendingBufferViews.push(this.getDependency('bufferView', accessorDef.bufferView));
34530	        } else {
34531	            pendingBufferViews.push(null);
34532	        }
34533	        if (accessorDef.sparse !== undefined) {
34534	            pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.indices.bufferView));
34535	            pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.values.bufferView));
34536	        }
34537	        return Promise.all(pendingBufferViews).then(function(bufferViews) {
34538	            const bufferView = bufferViews[0];
34539	            const itemSize = WEBGL_TYPE_SIZES[accessorDef.type];
34540	            const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
34541	            // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
34542	            const elementBytes = TypedArray.BYTES_PER_ELEMENT;
34543	            const itemBytes = elementBytes * itemSize;
34544	            const byteOffset = accessorDef.byteOffset || 0;
34545	            const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[accessorDef.bufferView].byteStride : undefined;
34546	            const normalized = accessorDef.normalized === true;
34547	            let array, bufferAttribute;
34548	            // The buffer is not interleaved if the stride is the item size in bytes.
34549	            if (byteStride && byteStride !== itemBytes) {
34550	                // Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own InterleavedBuffer
34551	                // This makes sure that IBA.count reflects accessor.count properly
34552	                const ibSlice = Math.floor(byteOffset / byteStride);
34553	                const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
34554	                let ib = parser.cache.get(ibCacheKey);
34555	                if (!ib) {
34556	                    array = new TypedArray(bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes);
34557	                    // Integer parameters to IB/IBA are in array elements, not bytes.
34558	                    ib = new InterleavedBuffer(array, byteStride / elementBytes);
34559	                    parser.cache.add(ibCacheKey, ib);
34560	                }
34561	                bufferAttribute = new InterleavedBufferAttribute(ib, itemSize, byteOffset % byteStride / elementBytes, normalized);
34562	            } else {
34563	                if (bufferView === null) {
34564	                    array = new TypedArray(accessorDef.count * itemSize);
34565	                } else {
vendor: 12,524 bytes, lines 34566-34807
34566	                    array = new TypedArray(bufferView, byteOffset, accessorDef.count * itemSize);
34567	                }
34568	                bufferAttribute = new BufferAttribute(array, itemSize, normalized);
34569	            }
34570	            // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
34571	            if (accessorDef.sparse !== undefined) {
34572	                const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;
34573	                const TypedArrayIndices = WEBGL_COMPONENT_TYPES[accessorDef.sparse.indices.componentType];
34574	                const byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;
34575	                const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;
34576	                const sparseIndices = new TypedArrayIndices(bufferViews[1], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices);
34577	                const sparseValues = new TypedArray(bufferViews[2], byteOffsetValues, accessorDef.sparse.count * itemSize);
34578	                if (bufferView !== null) {
34579	                    // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
34580	                    bufferAttribute = new BufferAttribute(bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized);
34581	                }
34582	                // Ignore normalized since we copy from sparse
34583	                bufferAttribute.normalized = false;
34584	                for(let i = 0, il = sparseIndices.length; i < il; i++){
34585	                    const index = sparseIndices[i];
34586	                    bufferAttribute.setX(index, sparseValues[i * itemSize]);
34587	                    if (itemSize >= 2) bufferAttribute.setY(index, sparseValues[i * itemSize + 1]);
34588	                    if (itemSize >= 3) bufferAttribute.setZ(index, sparseValues[i * itemSize + 2]);
34589	                    if (itemSize >= 4) bufferAttribute.setW(index, sparseValues[i * itemSize + 3]);
34590	                    if (itemSize >= 5) throw new Error('THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.');
34591	                }
34592	                bufferAttribute.normalized = normalized;
34593	            }
34594	            return bufferAttribute;
34595	        });
34596	    }
34597	    /**
34598		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
34599		 * @param {number} textureIndex
34600		 * @return {Promise<THREE.Texture|null>}
34601		 */ loadTexture(textureIndex) {
34602	        const json = this.json;
34603	        const options = this.options;
34604	        const textureDef = json.textures[textureIndex];
34605	        const sourceIndex = textureDef.source;
34606	        const sourceDef = json.images[sourceIndex];
34607	        let loader = this.textureLoader;
34608	        if (sourceDef.uri) {
34609	            const handler = options.manager.getHandler(sourceDef.uri);
34610	            if (handler !== null) loader = handler;
34611	        }
34612	        return this.loadTextureImage(textureIndex, sourceIndex, loader);
34613	    }
34614	    loadTextureImage(textureIndex, sourceIndex, loader) {
34615	        const parser = this;
34616	        const json = this.json;
34617	        const textureDef = json.textures[textureIndex];
34618	        const sourceDef = json.images[sourceIndex];
34619	        const cacheKey = (sourceDef.uri || sourceDef.bufferView) + ':' + textureDef.sampler;
34620	        if (this.textureCache[cacheKey]) {
34621	            // See https://github.com/mrdoob/three.js/issues/21559.
34622	            return this.textureCache[cacheKey];
34623	        }
34624	        const promise = this.loadImageSource(sourceIndex, loader).then(function(texture) {
34625	            texture.flipY = false;
34626	            texture.name = textureDef.name || sourceDef.name || '';
34627	            if (texture.name === '' && typeof sourceDef.uri === 'string' && sourceDef.uri.startsWith('data:image/') === false) {
34628	                texture.name = sourceDef.uri;
34629	            }
34630	            const samplers = json.samplers || {};
34631	            const sampler = samplers[textureDef.sampler] || {};
34632	            texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || LinearFilter;
34633	            texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || LinearMipmapLinearFilter;
34634	            texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || RepeatWrapping;
34635	            texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || RepeatWrapping;
34636	            texture.generateMipmaps = !texture.isCompressedTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
34637	            parser.associations.set(texture, {
34638	                textures: textureIndex
34639	            });
34640	            return texture;
34641	        }).catch(function() {
34642	            return null;
34643	        });
34644	        this.textureCache[cacheKey] = promise;
34645	        return promise;
34646	    }
34647	    loadImageSource(sourceIndex, loader) {
34648	        const parser = this;
34649	        const json = this.json;
34650	        const options = this.options;
34651	        if (this.sourceCache[sourceIndex] !== undefined) {
34652	            return this.sourceCache[sourceIndex].then((texture)=>texture.clone());
34653	        }
34654	        const sourceDef = json.images[sourceIndex];
34655	        const URL = self.URL || self.webkitURL;
34656	        let sourceURI = sourceDef.uri || '';
34657	        let isObjectURL = false;
34658	        if (sourceDef.bufferView !== undefined) {
34659	            // Load binary image data from bufferView, if provided.
34660	            sourceURI = parser.getDependency('bufferView', sourceDef.bufferView).then(function(bufferView) {
34661	                isObjectURL = true;
34662	                const blob = new Blob([
34663	                    bufferView
34664	                ], {
34665	                    type: sourceDef.mimeType
34666	                });
34667	                sourceURI = URL.createObjectURL(blob);
34668	                return sourceURI;
34669	            });
34670	        } else if (sourceDef.uri === undefined) {
34671	            throw new Error('THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView');
34672	        }
34673	        const promise = Promise.resolve(sourceURI).then(function(sourceURI) {
34674	            return new Promise(function(resolve, reject) {
34675	                let onLoad = resolve;
34676	                if (loader.isImageBitmapLoader === true) {
34677	                    onLoad = function(imageBitmap) {
34678	                        const texture = new Texture$1(imageBitmap);
34679	                        texture.needsUpdate = true;
34680	                        resolve(texture);
34681	                    };
34682	                }
34683	                loader.load(LoaderUtils.resolveURL(sourceURI, options.path), onLoad, undefined, reject);
34684	            });
34685	        }).then(function(texture) {
34686	            // Clean up resources and configure Texture.
34687	            if (isObjectURL === true) {
34688	                URL.revokeObjectURL(sourceURI);
34689	            }
34690	            assignExtrasToUserData(texture, sourceDef);
34691	            texture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType(sourceDef.uri);
34692	            return texture;
34693	        }).catch(function(error) {
34694	            console.error('THREE.GLTFLoader: Couldn\'t load texture', sourceURI);
34695	            throw error;
34696	        });
34697	        this.sourceCache[sourceIndex] = promise;
34698	        return promise;
34699	    }
34700	    /**
34701		 * Asynchronously assigns a texture to the given material parameters.
34702		 *
34703		 * @param {Object} materialParams
34704		 * @param {string} mapName
34705		 * @param {Object} mapDef
34706		 * @param {string} colorSpace
34707		 * @return {Promise<Texture>}
34708		 */ assignTexture(materialParams, mapName, mapDef, colorSpace) {
34709	        const parser = this;
34710	        return this.getDependency('texture', mapDef.index).then(function(texture) {
34711	            if (!texture) return null;
34712	            if (mapDef.texCoord !== undefined && mapDef.texCoord > 0) {
34713	                texture = texture.clone();
34714	                texture.channel = mapDef.texCoord;
34715	            }
34716	            if (parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]) {
34717	                const transform = mapDef.extensions !== undefined ? mapDef.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM] : undefined;
34718	                if (transform) {
34719	                    const gltfReference = parser.associations.get(texture);
34720	                    texture = parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM].extendTexture(texture, transform);
34721	                    parser.associations.set(texture, gltfReference);
34722	                }
34723	            }
34724	            if (colorSpace !== undefined) {
34725	                texture.colorSpace = colorSpace;
34726	            }
34727	            materialParams[mapName] = texture;
34728	            return texture;
34729	        });
34730	    }
34731	    /**
34732		 * Assigns final material to a Mesh, Line, or Points instance. The instance
34733		 * already has a material (generated from the glTF material options alone)
34734		 * but reuse of the same glTF material may require multiple threejs materials
34735		 * to accommodate different primitive types, defines, etc. New materials will
34736		 * be created if necessary, and reused from a cache.
34737		 * @param  {Object3D} mesh Mesh, Line, or Points instance.
34738		 */ assignFinalMaterial(mesh) {
34739	        const geometry = mesh.geometry;
34740	        let material = mesh.material;
34741	        const useDerivativeTangents = geometry.attributes.tangent === undefined;
34742	        const useVertexColors = geometry.attributes.color !== undefined;
34743	        const useFlatShading = geometry.attributes.normal === undefined;
34744	        if (mesh.isPoints) {
34745	            const cacheKey = 'PointsMaterial:' + material.uuid;
34746	            let pointsMaterial = this.cache.get(cacheKey);
34747	            if (!pointsMaterial) {
34748	                pointsMaterial = new PointsMaterial();
34749	                Material$1.prototype.copy.call(pointsMaterial, material);
34750	                pointsMaterial.color.copy(material.color);
34751	                pointsMaterial.map = material.map;
34752	                pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
34753	                this.cache.add(cacheKey, pointsMaterial);
34754	            }
34755	            material = pointsMaterial;
34756	        } else if (mesh.isLine) {
34757	            const cacheKey = 'LineBasicMaterial:' + material.uuid;
34758	            let lineMaterial = this.cache.get(cacheKey);
34759	            if (!lineMaterial) {
34760	                lineMaterial = new LineBasicMaterial();
34761	                Material$1.prototype.copy.call(lineMaterial, material);
34762	                lineMaterial.color.copy(material.color);
34763	                lineMaterial.map = material.map;
34764	                this.cache.add(cacheKey, lineMaterial);
34765	            }
34766	            material = lineMaterial;
34767	        }
34768	        // Clone the material if it will be modified
34769	        if (useDerivativeTangents || useVertexColors || useFlatShading) {
34770	            let cacheKey = 'ClonedMaterial:' + material.uuid + ':';
34771	            if (useDerivativeTangents) cacheKey += 'derivative-tangents:';
34772	            if (useVertexColors) cacheKey += 'vertex-colors:';
34773	            if (useFlatShading) cacheKey += 'flat-shading:';
34774	            let cachedMaterial = this.cache.get(cacheKey);
34775	            if (!cachedMaterial) {
34776	                cachedMaterial = material.clone();
34777	                if (useVertexColors) cachedMaterial.vertexColors = true;
34778	                if (useFlatShading) cachedMaterial.flatShading = true;
34779	                if (useDerivativeTangents) {
34780	                    // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
34781	                    if (cachedMaterial.normalScale) cachedMaterial.normalScale.y *= -1;
34782	                    if (cachedMaterial.clearcoatNormalScale) cachedMaterial.clearcoatNormalScale.y *= -1;
34783	                }
34784	                this.cache.add(cacheKey, cachedMaterial);
34785	                this.associations.set(cachedMaterial, this.associations.get(material));
34786	            }
34787	            material = cachedMaterial;
34788	        }
34789	        mesh.material = material;
34790	    }
34791	    getMaterialType() {
34792	        return MeshStandardMaterial;
34793	    }
34794	    /**
34795		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
34796		 * @param {number} materialIndex
34797		 * @return {Promise<Material>}
34798		 */ loadMaterial(materialIndex) {
34799	        const parser = this;
34800	        const json = this.json;
34801	        const extensions = this.extensions;
34802	        const materialDef = json.materials[materialIndex];
34803	        let materialType;
34804	        const materialParams = {};
34805	        const materialExtensions = materialDef.extensions || {};
34806	        const pending = [];
34807	        if (materialExtensions[EXTENSIONS.KHR_MATERIALS_UNLIT]) {
vendor: 12,157 bytes, lines 34808-35035
34808	            const kmuExtension = extensions[EXTENSIONS.KHR_MATERIALS_UNLIT];
34809	            materialType = kmuExtension.getMaterialType();
34810	            pending.push(kmuExtension.extendParams(materialParams, materialDef, parser));
34811	        } else {
34812	            // Specification:
34813	            // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
34814	            const metallicRoughness = materialDef.pbrMetallicRoughness || {};
34815	            materialParams.color = new Color(1.0, 1.0, 1.0);
34816	            materialParams.opacity = 1.0;
34817	            if (Array.isArray(metallicRoughness.baseColorFactor)) {
34818	                const array = metallicRoughness.baseColorFactor;
34819	                materialParams.color.setRGB(array[0], array[1], array[2], LinearSRGBColorSpace);
34820	                materialParams.opacity = array[3];
34821	            }
34822	            if (metallicRoughness.baseColorTexture !== undefined) {
34823	                pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, SRGBColorSpace));
34824	            }
34825	            materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
34826	            materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;
34827	            if (metallicRoughness.metallicRoughnessTexture !== undefined) {
34828	                pending.push(parser.assignTexture(materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture));
34829	                pending.push(parser.assignTexture(materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture));
34830	            }
34831	            materialType = this._invokeOne(function(ext) {
34832	                return ext.getMaterialType && ext.getMaterialType(materialIndex);
34833	            });
34834	            pending.push(Promise.all(this._invokeAll(function(ext) {
34835	                return ext.extendMaterialParams && ext.extendMaterialParams(materialIndex, materialParams);
34836	            })));
34837	        }
34838	        if (materialDef.doubleSided === true) {
34839	            materialParams.side = DoubleSide;
34840	        }
34841	        const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;
34842	        if (alphaMode === ALPHA_MODES.BLEND) {
34843	            materialParams.transparent = true;
34844	            // See: https://github.com/mrdoob/three.js/issues/17706
34845	            materialParams.depthWrite = false;
34846	        } else {
34847	            materialParams.transparent = false;
34848	            if (alphaMode === ALPHA_MODES.MASK) {
34849	                materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;
34850	            }
34851	        }
34852	        if (materialDef.normalTexture !== undefined && materialType !== MeshBasicMaterial) {
34853	            pending.push(parser.assignTexture(materialParams, 'normalMap', materialDef.normalTexture));
34854	            materialParams.normalScale = new Vector2(1, 1);
34855	            if (materialDef.normalTexture.scale !== undefined) {
34856	                const scale = materialDef.normalTexture.scale;
34857	                materialParams.normalScale.set(scale, scale);
34858	            }
34859	        }
34860	        if (materialDef.occlusionTexture !== undefined && materialType !== MeshBasicMaterial) {
34861	            pending.push(parser.assignTexture(materialParams, 'aoMap', materialDef.occlusionTexture));
34862	            if (materialDef.occlusionTexture.strength !== undefined) {
34863	                materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;
34864	            }
34865	        }
34866	        if (materialDef.emissiveFactor !== undefined && materialType !== MeshBasicMaterial) {
34867	            const emissiveFactor = materialDef.emissiveFactor;
34868	            materialParams.emissive = new Color().setRGB(emissiveFactor[0], emissiveFactor[1], emissiveFactor[2], LinearSRGBColorSpace);
34869	        }
34870	        if (materialDef.emissiveTexture !== undefined && materialType !== MeshBasicMaterial) {
34871	            pending.push(parser.assignTexture(materialParams, 'emissiveMap', materialDef.emissiveTexture, SRGBColorSpace));
34872	        }
34873	        return Promise.all(pending).then(function() {
34874	            const material = new materialType(materialParams);
34875	            if (materialDef.name) material.name = materialDef.name;
34876	            assignExtrasToUserData(material, materialDef);
34877	            parser.associations.set(material, {
34878	                materials: materialIndex
34879	            });
34880	            if (materialDef.extensions) addUnknownExtensionsToUserData(extensions, material, materialDef);
34881	            return material;
34882	        });
34883	    }
34884	    /**
34885		 * When Object3D instances are targeted by animation, they need unique names.
34886		 *
34887		 * @param {string} originalName
34888		 * @return {string}
34889		 */ createUniqueName(originalName) {
34890	        const sanitizedName = PropertyBinding.sanitizeNodeName(originalName || '');
34891	        if (sanitizedName in this.nodeNamesUsed) {
34892	            return sanitizedName + '_' + ++this.nodeNamesUsed[sanitizedName];
34893	        } else {
34894	            this.nodeNamesUsed[sanitizedName] = 0;
34895	            return sanitizedName;
34896	        }
34897	    }
34898	    /**
34899		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
34900		 *
34901		 * Creates BufferGeometries from primitives.
34902		 *
34903		 * @param {Array<GLTF.Primitive>} primitives
34904		 * @return {Promise<Array<BufferGeometry>>}
34905		 */ loadGeometries(primitives) {
34906	        const parser = this;
34907	        const extensions = this.extensions;
34908	        const cache = this.primitiveCache;
34909	        function createDracoPrimitive(primitive) {
34910	            return extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(primitive, parser).then(function(geometry) {
34911	                return addPrimitiveAttributes(geometry, primitive, parser);
34912	            });
34913	        }
34914	        const pending = [];
34915	        for(let i = 0, il = primitives.length; i < il; i++){
34916	            const primitive = primitives[i];
34917	            const cacheKey = createPrimitiveKey(primitive);
34918	            // See if we've already created this geometry
34919	            const cached = cache[cacheKey];
34920	            if (cached) {
34921	                // Use the cached geometry if it exists
34922	                pending.push(cached.promise);
34923	            } else {
34924	                let geometryPromise;
34925	                if (primitive.extensions && primitive.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]) {
34926	                    // Use DRACO geometry if available
34927	                    geometryPromise = createDracoPrimitive(primitive);
34928	                } else {
34929	                    // Otherwise create a new geometry
34930	                    geometryPromise = addPrimitiveAttributes(new BufferGeometry(), primitive, parser);
34931	                }
34932	                // Cache this geometry
34933	                cache[cacheKey] = {
34934	                    primitive: primitive,
34935	                    promise: geometryPromise
34936	                };
34937	                pending.push(geometryPromise);
34938	            }
34939	        }
34940	        return Promise.all(pending);
34941	    }
34942	    /**
34943		 * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
34944		 * @param {number} meshIndex
34945		 * @return {Promise<Group|Mesh|SkinnedMesh>}
34946		 */ loadMesh(meshIndex) {
34947	        const parser = this;
34948	        const json = this.json;
34949	        const extensions = this.extensions;
34950	        const meshDef = json.meshes[meshIndex];
34951	        const primitives = meshDef.primitives;
34952	        const pending = [];
34953	        for(let i = 0, il = primitives.length; i < il; i++){
34954	            const material = primitives[i].material === undefined ? createDefaultMaterial(this.cache) : this.getDependency('material', primitives[i].material);
34955	            pending.push(material);
34956	        }
34957	        pending.push(parser.loadGeometries(primitives));
34958	        return Promise.all(pending).then(function(results) {
34959	            const materials = results.slice(0, results.length - 1);
34960	            const geometries = results[results.length - 1];
34961	            const meshes = [];
34962	            for(let i = 0, il = geometries.length; i < il; i++){
34963	                const geometry = geometries[i];
34964	                const primitive = primitives[i];
34965	                // 1. create Mesh
34966	                let mesh;
34967	                const material = materials[i];
34968	                if (primitive.mode === WEBGL_CONSTANTS$1.TRIANGLES || primitive.mode === WEBGL_CONSTANTS$1.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS$1.TRIANGLE_FAN || primitive.mode === undefined) {
34969	                    // .isSkinnedMesh isn't in glTF spec. See ._markDefs()
34970	                    mesh = meshDef.isSkinnedMesh === true ? new SkinnedMesh(geometry, material) : new Mesh(geometry, material);
34971	                    if (mesh.isSkinnedMesh === true) {
34972	                        // normalize skin weights to fix malformed assets (see #15319)
34973	                        mesh.normalizeSkinWeights();
34974	                    }
34975	                    if (primitive.mode === WEBGL_CONSTANTS$1.TRIANGLE_STRIP) {
34976	                        mesh.geometry = toTrianglesDrawMode(mesh.geometry, TriangleStripDrawMode);
34977	                    } else if (primitive.mode === WEBGL_CONSTANTS$1.TRIANGLE_FAN) {
34978	                        mesh.geometry = toTrianglesDrawMode(mesh.geometry, TriangleFanDrawMode);
34979	                    }
34980	                } else if (primitive.mode === WEBGL_CONSTANTS$1.LINES) {
34981	                    mesh = new LineSegments(geometry, material);
34982	                } else if (primitive.mode === WEBGL_CONSTANTS$1.LINE_STRIP) {
34983	                    mesh = new Line(geometry, material);
34984	                } else if (primitive.mode === WEBGL_CONSTANTS$1.LINE_LOOP) {
34985	                    mesh = new LineLoop(geometry, material);
34986	                } else if (primitive.mode === WEBGL_CONSTANTS$1.POINTS) {
34987	                    mesh = new Points(geometry, material);
34988	                } else {
34989	                    throw new Error('THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode);
34990	                }
34991	                if (Object.keys(mesh.geometry.morphAttributes).length > 0) {
34992	                    updateMorphTargets(mesh, meshDef);
34993	                }
34994	                mesh.name = parser.createUniqueName(meshDef.name || 'mesh_' + meshIndex);
34995	                assignExtrasToUserData(mesh, meshDef);
34996	                if (primitive.extensions) addUnknownExtensionsToUserData(extensions, mesh, primitive);
34997	                parser.assignFinalMaterial(mesh);
34998	                meshes.push(mesh);
34999	            }
35000	            for(let i = 0, il = meshes.length; i < il; i++){
35001	                parser.associations.set(meshes[i], {
35002	                    meshes: meshIndex,
35003	                    primitives: i
35004	                });
35005	            }
35006	            if (meshes.length === 1) {
35007	                if (meshDef.extensions) addUnknownExtensionsToUserData(extensions, meshes[0], meshDef);
35008	                return meshes[0];
35009	            }
35010	            const group = new Group();
35011	            if (meshDef.extensions) addUnknownExtensionsToUserData(extensions, group, meshDef);
35012	            parser.associations.set(group, {
35013	                meshes: meshIndex
35014	            });
35015	            for(let i = 0, il = meshes.length; i < il; i++){
35016	                group.add(meshes[i]);
35017	            }
35018	            return group;
35019	        });
35020	    }
35021	    /**
35022		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
35023		 * @param {number} cameraIndex
35024		 * @return {Promise<THREE.Camera>}
35025		 */ loadCamera(cameraIndex) {
35026	        let camera;
35027	        const cameraDef = this.json.cameras[cameraIndex];
35028	        const params = cameraDef[cameraDef.type];
35029	        if (!params) {
35030	            console.warn('THREE.GLTFLoader: Missing camera parameters.');
35031	            return;
35032	        }
35033	        if (cameraDef.type === 'perspective') {
35034	            camera = new PerspectiveCamera(MathUtils.radToDeg(params.yfov), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6);
35035	        } else if (cameraDef.type === 'orthographic') {
vendor: 4,195 bytes, lines 35036-35122
35036	            camera = new OrthographicCamera(-params.xmag, params.xmag, params.ymag, -params.ymag, params.znear, params.zfar);
35037	        }
35038	        if (cameraDef.name) camera.name = this.createUniqueName(cameraDef.name);
35039	        assignExtrasToUserData(camera, cameraDef);
35040	        return Promise.resolve(camera);
35041	    }
35042	    /**
35043		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
35044		 * @param {number} skinIndex
35045		 * @return {Promise<Skeleton>}
35046		 */ loadSkin(skinIndex) {
35047	        const skinDef = this.json.skins[skinIndex];
35048	        const pending = [];
35049	        for(let i = 0, il = skinDef.joints.length; i < il; i++){
35050	            pending.push(this._loadNodeShallow(skinDef.joints[i]));
35051	        }
35052	        if (skinDef.inverseBindMatrices !== undefined) {
35053	            pending.push(this.getDependency('accessor', skinDef.inverseBindMatrices));
35054	        } else {
35055	            pending.push(null);
35056	        }
35057	        return Promise.all(pending).then(function(results) {
35058	            const inverseBindMatrices = results.pop();
35059	            const jointNodes = results;
35060	            // Note that bones (joint nodes) may or may not be in the
35061	            // scene graph at this time.
35062	            const bones = [];
35063	            const boneInverses = [];
35064	            for(let i = 0, il = jointNodes.length; i < il; i++){
35065	                const jointNode = jointNodes[i];
35066	                if (jointNode) {
35067	                    bones.push(jointNode);
35068	                    const mat = new Matrix4();
35069	                    if (inverseBindMatrices !== null) {
35070	                        mat.fromArray(inverseBindMatrices.array, i * 16);
35071	                    }
35072	                    boneInverses.push(mat);
35073	                } else {
35074	                    console.warn('THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[i]);
35075	                }
35076	            }
35077	            return new Skeleton(bones, boneInverses);
35078	        });
35079	    }
35080	    /**
35081		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
35082		 * @param {number} animationIndex
35083		 * @return {Promise<AnimationClip>}
35084		 */ loadAnimation(animationIndex) {
35085	        const json = this.json;
35086	        const parser = this;
35087	        const animationDef = json.animations[animationIndex];
35088	        const animationName = animationDef.name ? animationDef.name : 'animation_' + animationIndex;
35089	        const pendingNodes = [];
35090	        const pendingInputAccessors = [];
35091	        const pendingOutputAccessors = [];
35092	        const pendingSamplers = [];
35093	        const pendingTargets = [];
35094	        for(let i = 0, il = animationDef.channels.length; i < il; i++){
35095	            const channel = animationDef.channels[i];
35096	            const sampler = animationDef.samplers[channel.sampler];
35097	            const target = channel.target;
35098	            const name = target.node;
35099	            const input = animationDef.parameters !== undefined ? animationDef.parameters[sampler.input] : sampler.input;
35100	            const output = animationDef.parameters !== undefined ? animationDef.parameters[sampler.output] : sampler.output;
35101	            if (target.node === undefined) continue;
35102	            pendingNodes.push(this.getDependency('node', name));
35103	            pendingInputAccessors.push(this.getDependency('accessor', input));
35104	            pendingOutputAccessors.push(this.getDependency('accessor', output));
35105	            pendingSamplers.push(sampler);
35106	            pendingTargets.push(target);
35107	        }
35108	        return Promise.all([
35109	            Promise.all(pendingNodes),
35110	            Promise.all(pendingInputAccessors),
35111	            Promise.all(pendingOutputAccessors),
35112	            Promise.all(pendingSamplers),
35113	            Promise.all(pendingTargets)
35114	        ]).then(function(dependencies) {
35115	            const nodes = dependencies[0];
35116	            const inputAccessors = dependencies[1];
35117	            const outputAccessors = dependencies[2];
35118	            const samplers = dependencies[3];
35119	            const targets = dependencies[4];
35120	            const tracks = [];
35121	            for(let i = 0, il = nodes.length; i < il; i++){
35122	                const node = nodes[i];
vendor: 4,599 bytes, lines 35123-35225
35123	                const inputAccessor = inputAccessors[i];
35124	                const outputAccessor = outputAccessors[i];
35125	                const sampler = samplers[i];
35126	                const target = targets[i];
35127	                if (node === undefined) continue;
35128	                if (node.updateMatrix) {
35129	                    node.updateMatrix();
35130	                }
35131	                const createdTracks = parser._createAnimationTracks(node, inputAccessor, outputAccessor, sampler, target);
35132	                if (createdTracks) {
35133	                    for(let k = 0; k < createdTracks.length; k++){
35134	                        tracks.push(createdTracks[k]);
35135	                    }
35136	                }
35137	            }
35138	            return new AnimationClip(animationName, undefined, tracks);
35139	        });
35140	    }
35141	    createNodeMesh(nodeIndex) {
35142	        const json = this.json;
35143	        const parser = this;
35144	        const nodeDef = json.nodes[nodeIndex];
35145	        if (nodeDef.mesh === undefined) return null;
35146	        return parser.getDependency('mesh', nodeDef.mesh).then(function(mesh) {
35147	            const node = parser._getNodeRef(parser.meshCache, nodeDef.mesh, mesh);
35148	            // if weights are provided on the node, override weights on the mesh.
35149	            if (nodeDef.weights !== undefined) {
35150	                node.traverse(function(o) {
35151	                    if (!o.isMesh) return;
35152	                    for(let i = 0, il = nodeDef.weights.length; i < il; i++){
35153	                        o.morphTargetInfluences[i] = nodeDef.weights[i];
35154	                    }
35155	                });
35156	            }
35157	            return node;
35158	        });
35159	    }
35160	    /**
35161		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
35162		 * @param {number} nodeIndex
35163		 * @return {Promise<Object3D>}
35164		 */ loadNode(nodeIndex) {
35165	        const json = this.json;
35166	        const parser = this;
35167	        const nodeDef = json.nodes[nodeIndex];
35168	        const nodePending = parser._loadNodeShallow(nodeIndex);
35169	        const childPending = [];
35170	        const childrenDef = nodeDef.children || [];
35171	        for(let i = 0, il = childrenDef.length; i < il; i++){
35172	            childPending.push(parser.getDependency('node', childrenDef[i]));
35173	        }
35174	        const skeletonPending = nodeDef.skin === undefined ? Promise.resolve(null) : parser.getDependency('skin', nodeDef.skin);
35175	        return Promise.all([
35176	            nodePending,
35177	            Promise.all(childPending),
35178	            skeletonPending
35179	        ]).then(function(results) {
35180	            const node = results[0];
35181	            const children = results[1];
35182	            const skeleton = results[2];
35183	            if (skeleton !== null) {
35184	                // This full traverse should be fine because
35185	                // child glTF nodes have not been added to this node yet.
35186	                node.traverse(function(mesh) {
35187	                    if (!mesh.isSkinnedMesh) return;
35188	                    mesh.bind(skeleton, _identityMatrix);
35189	                });
35190	            }
35191	            for(let i = 0, il = children.length; i < il; i++){
35192	                node.add(children[i]);
35193	            }
35194	            return node;
35195	        });
35196	    }
35197	    // ._loadNodeShallow() parses a single node.
35198	    // skin and child nodes are created and added in .loadNode() (no '_' prefix).
35199	    _loadNodeShallow(nodeIndex) {
35200	        const json = this.json;
35201	        const extensions = this.extensions;
35202	        const parser = this;
35203	        // This method is called from .loadNode() and .loadSkin().
35204	        // Cache a node to avoid duplication.
35205	        if (this.nodeCache[nodeIndex] !== undefined) {
35206	            return this.nodeCache[nodeIndex];
35207	        }
35208	        const nodeDef = json.nodes[nodeIndex];
35209	        // reserve node's name before its dependencies, so the root has the intended name.
35210	        const nodeName = nodeDef.name ? parser.createUniqueName(nodeDef.name) : '';
35211	        const pending = [];
35212	        const meshPromise = parser._invokeOne(function(ext) {
35213	            return ext.createNodeMesh && ext.createNodeMesh(nodeIndex);
35214	        });
35215	        if (meshPromise) {
35216	            pending.push(meshPromise);
35217	        }
35218	        if (nodeDef.camera !== undefined) {
35219	            pending.push(parser.getDependency('camera', nodeDef.camera).then(function(camera) {
35220	                return parser._getNodeRef(parser.cameraCache, nodeDef.camera, camera);
35221	            }));
35222	        }
35223	        parser._invokeAll(function(ext) {
35224	            return ext.createNodeAttachment && ext.createNodeAttachment(nodeIndex);
35225	        }
vendor: 5,641 bytes, lines 35225-35356
35225).forEach(function(promise) {
35226	            pending.push(promise);
35227	        });
35228	        this.nodeCache[nodeIndex] = Promise.all(pending).then(function(objects) {
35229	            let node;
35230	            // .isBone isn't in glTF spec. See ._markDefs
35231	            if (nodeDef.isBone === true) {
35232	                node = new Bone();
35233	            } else if (objects.length > 1) {
35234	                node = new Group();
35235	            } else if (objects.length === 1) {
35236	                node = objects[0];
35237	            } else {
35238	                node = new Object3D();
35239	            }
35240	            if (node !== objects[0]) {
35241	                for(let i = 0, il = objects.length; i < il; i++){
35242	                    node.add(objects[i]);
35243	                }
35244	            }
35245	            if (nodeDef.name) {
35246	                node.userData.name = nodeDef.name;
35247	                node.name = nodeName;
35248	            }
35249	            assignExtrasToUserData(node, nodeDef);
35250	            if (nodeDef.extensions) addUnknownExtensionsToUserData(extensions, node, nodeDef);
35251	            if (nodeDef.matrix !== undefined) {
35252	                const matrix = new Matrix4();
35253	                matrix.fromArray(nodeDef.matrix);
35254	                node.applyMatrix4(matrix);
35255	            } else {
35256	                if (nodeDef.translation !== undefined) {
35257	                    node.position.fromArray(nodeDef.translation);
35258	                }
35259	                if (nodeDef.rotation !== undefined) {
35260	                    node.quaternion.fromArray(nodeDef.rotation);
35261	                }
35262	                if (nodeDef.scale !== undefined) {
35263	                    node.scale.fromArray(nodeDef.scale);
35264	                }
35265	            }
35266	            if (!parser.associations.has(node)) {
35267	                parser.associations.set(node, {});
35268	            }
35269	            parser.associations.get(node).nodes = nodeIndex;
35270	            return node;
35271	        });
35272	        return this.nodeCache[nodeIndex];
35273	    }
35274	    /**
35275		 * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
35276		 * @param {number} sceneIndex
35277		 * @return {Promise<Group>}
35278		 */ loadScene(sceneIndex) {
35279	        const extensions = this.extensions;
35280	        const sceneDef = this.json.scenes[sceneIndex];
35281	        const parser = this;
35282	        // Loader returns Group, not Scene.
35283	        // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
35284	        const scene = new Group();
35285	        if (sceneDef.name) scene.name = parser.createUniqueName(sceneDef.name);
35286	        assignExtrasToUserData(scene, sceneDef);
35287	        if (sceneDef.extensions) addUnknownExtensionsToUserData(extensions, scene, sceneDef);
35288	        const nodeIds = sceneDef.nodes || [];
35289	        const pending = [];
35290	        for(let i = 0, il = nodeIds.length; i < il; i++){
35291	            pending.push(parser.getDependency('node', nodeIds[i]));
35292	        }
35293	        return Promise.all(pending).then(function(nodes) {
35294	            for(let i = 0, il = nodes.length; i < il; i++){
35295	                scene.add(nodes[i]);
35296	            }
35297	            // Removes dangling associations, associations that reference a node that
35298	            // didn't make it into the scene.
35299	            const reduceAssociations = (node)=>{
35300	                const reducedAssociations = new Map();
35301	                for (const [key, value] of parser.associations){
35302	                    if (key instanceof Material$1 || key instanceof Texture$1) {
35303	                        reducedAssociations.set(key, value);
35304	                    }
35305	                }
35306	                node.traverse((node)=>{
35307	                    const mappings = parser.associations.get(node);
35308	                    if (mappings != null) {
35309	                        reducedAssociations.set(node, mappings);
35310	                    }
35311	                });
35312	                return reducedAssociations;
35313	            };
35314	            parser.associations = reduceAssociations(scene);
35315	            return scene;
35316	        });
35317	    }
35318	    _createAnimationTracks(node, inputAccessor, outputAccessor, sampler, target) {
35319	        const tracks = [];
35320	        const targetName = node.name ? node.name : node.uuid;
35321	        const targetNames = [];
35322	        if (PATH_PROPERTIES$1[target.path] === PATH_PROPERTIES$1.weights) {
35323	            node.traverse(function(object) {
35324	                if (object.morphTargetInfluences) {
35325	                    targetNames.push(object.name ? object.name : object.uuid);
35326	                }
35327	            });
35328	        } else {
35329	            targetNames.push(targetName);
35330	        }
35331	        let TypedKeyframeTrack;
35332	        switch(PATH_PROPERTIES$1[target.path]){
35333	            case PATH_PROPERTIES$1.weights:
35334	                TypedKeyframeTrack = NumberKeyframeTrack;
35335	                break;
35336	            case PATH_PROPERTIES$1.rotation:
35337	                TypedKeyframeTrack = QuaternionKeyframeTrack;
35338	                break;
35339	            case PATH_PROPERTIES$1.position:
35340	            case PATH_PROPERTIES$1.scale:
35341	                TypedKeyframeTrack = VectorKeyframeTrack;
35342	                break;
35343	            default:
35344	                switch(outputAccessor.itemSize){
35345	                    case 1:
35346	                        TypedKeyframeTrack = NumberKeyframeTrack;
35347	                        break;
35348	                    case 2:
35349	                    case 3:
35350	                    default:
35351	                        TypedKeyframeTrack = VectorKeyframeTrack;
35352	                        break;
35353	                }
35354	                break;
35355	        }
35356	        const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[sampler.interpolation] : InterpolateLinear;
vendor: 15,206 bytes, lines 35357-35706
35357	        const outputArray = this._getArrayFromAccessor(outputAccessor);
35358	        for(let j = 0, jl = targetNames.length; j < jl; j++){
35359	            const track = new TypedKeyframeTrack(targetNames[j] + '.' + PATH_PROPERTIES$1[target.path], inputAccessor.array, outputArray, interpolation);
35360	            // Override interpolation with custom factory method.
35361	            if (sampler.interpolation === 'CUBICSPLINE') {
35362	                this._createCubicSplineTrackInterpolant(track);
35363	            }
35364	            tracks.push(track);
35365	        }
35366	        return tracks;
35367	    }
35368	    _getArrayFromAccessor(accessor) {
35369	        let outputArray = accessor.array;
35370	        if (accessor.normalized) {
35371	            const scale = getNormalizedComponentScale(outputArray.constructor);
35372	            const scaled = new Float32Array(outputArray.length);
35373	            for(let j = 0, jl = outputArray.length; j < jl; j++){
35374	                scaled[j] = outputArray[j] * scale;
35375	            }
35376	            outputArray = scaled;
35377	        }
35378	        return outputArray;
35379	    }
35380	    _createCubicSplineTrackInterpolant(track) {
35381	        track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline(result) {
35382	            // A CUBICSPLINE keyframe in glTF has three output values for each input value,
35383	            // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
35384	            // must be divided by three to get the interpolant's sampleSize argument.
35385	            const interpolantType = this instanceof QuaternionKeyframeTrack ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;
35386	            return new interpolantType(this.times, this.values, this.getValueSize() / 3, result);
35387	        };
35388	        // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
35389	        track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
35390	    }
35391	    constructor(json = {}, options = {}){
35392	        this.json = json;
35393	        this.extensions = {};
35394	        this.plugins = {};
35395	        this.options = options;
35396	        // loader object cache
35397	        this.cache = new GLTFRegistry();
35398	        // associations between Three.js objects and glTF elements
35399	        this.associations = new Map();
35400	        // BufferGeometry caching
35401	        this.primitiveCache = {};
35402	        // Node cache
35403	        this.nodeCache = {};
35404	        // Object3D instance caches
35405	        this.meshCache = {
35406	            refs: {},
35407	            uses: {}
35408	        };
35409	        this.cameraCache = {
35410	            refs: {},
35411	            uses: {}
35412	        };
35413	        this.lightCache = {
35414	            refs: {},
35415	            uses: {}
35416	        };
35417	        this.sourceCache = {};
35418	        this.textureCache = {};
35419	        // Track node names, to ensure no duplicates
35420	        this.nodeNamesUsed = {};
35421	        // Use an ImageBitmapLoader if imageBitmaps are supported. Moves much of the
35422	        // expensive work of uploading a texture to the GPU off the main thread.
35423	        let isSafari = false;
35424	        let safariVersion = -1;
35425	        let isFirefox = false;
35426	        let firefoxVersion = -1;
35427	        if (typeof navigator !== 'undefined') {
35428	            const userAgent = navigator.userAgent;
35429	            isSafari = /^((?!chrome|android).)*safari/i.test(userAgent) === true;
35430	            const safariMatch = userAgent.match(/Version\/(\d+)/);
35431	            safariVersion = isSafari && safariMatch ? parseInt(safariMatch[1], 10) : -1;
35432	            isFirefox = userAgent.indexOf('Firefox') > -1;
35433	            firefoxVersion = isFirefox ? userAgent.match(/Firefox\/([0-9]+)\./)[1] : -1;
35434	        }
35435	        if (typeof createImageBitmap === 'undefined' || isSafari && safariVersion < 17 || isFirefox && firefoxVersion < 98) {
35436	            this.textureLoader = new TextureLoader(this.options.manager);
35437	        } else {
35438	            this.textureLoader = new ImageBitmapLoader(this.options.manager);
35439	        }
35440	        this.textureLoader.setCrossOrigin(this.options.crossOrigin);
35441	        this.textureLoader.setRequestHeader(this.options.requestHeader);
35442	        this.fileLoader = new FileLoader(this.options.manager);
35443	        this.fileLoader.setResponseType('arraybuffer');
35444	        if (this.options.crossOrigin === 'use-credentials') {
35445	            this.fileLoader.setWithCredentials(true);
35446	        }
35447	    }
35448	}
35449	/**
35450	 * @param {BufferGeometry} geometry
35451	 * @param {GLTF.Primitive} primitiveDef
35452	 * @param {GLTFParser} parser
35453	 */ function computeBounds(geometry, primitiveDef, parser) {
35454	    const attributes = primitiveDef.attributes;
35455	    const box = new Box3();
35456	    if (attributes.POSITION !== undefined) {
35457	        const accessor = parser.json.accessors[attributes.POSITION];
35458	        const min = accessor.min;
35459	        const max = accessor.max;
35460	        // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
35461	        if (min !== undefined && max !== undefined) {
35462	            box.set(new Vector3(min[0], min[1], min[2]), new Vector3(max[0], max[1], max[2]));
35463	            if (accessor.normalized) {
35464	                const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);
35465	                box.min.multiplyScalar(boxScale);
35466	                box.max.multiplyScalar(boxScale);
35467	            }
35468	        } else {
35469	            console.warn('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.');
35470	            return;
35471	        }
35472	    } else {
35473	        return;
35474	    }
35475	    const targets = primitiveDef.targets;
35476	    if (targets !== undefined) {
35477	        const maxDisplacement = new Vector3();
35478	        const vector = new Vector3();
35479	        for(let i = 0, il = targets.length; i < il; i++){
35480	            const target = targets[i];
35481	            if (target.POSITION !== undefined) {
35482	                const accessor = parser.json.accessors[target.POSITION];
35483	                const min = accessor.min;
35484	                const max = accessor.max;
35485	                // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
35486	                if (min !== undefined && max !== undefined) {
35487	                    // we need to get max of absolute components because target weight is [-1,1]
35488	                    vector.setX(Math.max(Math.abs(min[0]), Math.abs(max[0])));
35489	                    vector.setY(Math.max(Math.abs(min[1]), Math.abs(max[1])));
35490	                    vector.setZ(Math.max(Math.abs(min[2]), Math.abs(max[2])));
35491	                    if (accessor.normalized) {
35492	                        const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);
35493	                        vector.multiplyScalar(boxScale);
35494	                    }
35495	                    // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
35496	                    // to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets
35497	                    // are used to implement key-frame animations and as such only two are active at a time - this results in very large
35498	                    // boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.
35499	                    maxDisplacement.max(vector);
35500	                } else {
35501	                    console.warn('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.');
35502	                }
35503	            }
35504	        }
35505	        // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
35506	        box.expandByVector(maxDisplacement);
35507	    }
35508	    geometry.boundingBox = box;
35509	    const sphere = new Sphere();
35510	    box.getCenter(sphere.center);
35511	    sphere.radius = box.min.distanceTo(box.max) / 2;
35512	    geometry.boundingSphere = sphere;
35513	}
35514	/**
35515	 * @param {BufferGeometry} geometry
35516	 * @param {GLTF.Primitive} primitiveDef
35517	 * @param {GLTFParser} parser
35518	 * @return {Promise<BufferGeometry>}
35519	 */ function addPrimitiveAttributes(geometry, primitiveDef, parser) {
35520	    const attributes = primitiveDef.attributes;
35521	    const pending = [];
35522	    function assignAttributeAccessor(accessorIndex, attributeName) {
35523	        return parser.getDependency('accessor', accessorIndex).then(function(accessor) {
35524	            geometry.setAttribute(attributeName, accessor);
35525	        });
35526	    }
35527	    for(const gltfAttributeName in attributes){
35528	        const threeAttributeName = ATTRIBUTES[gltfAttributeName] || gltfAttributeName.toLowerCase();
35529	        // Skip attributes already provided by e.g. Draco extension.
35530	        if (threeAttributeName in geometry.attributes) continue;
35531	        pending.push(assignAttributeAccessor(attributes[gltfAttributeName], threeAttributeName));
35532	    }
35533	    if (primitiveDef.indices !== undefined && !geometry.index) {
35534	        const accessor = parser.getDependency('accessor', primitiveDef.indices).then(function(accessor) {
35535	            geometry.setIndex(accessor);
35536	        });
35537	        pending.push(accessor);
35538	    }
35539	    if (ColorManagement.workingColorSpace !== LinearSRGBColorSpace && 'COLOR_0' in attributes) {
35540	        console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${ColorManagement.workingColorSpace}" not supported.`);
35541	    }
35542	    assignExtrasToUserData(geometry, primitiveDef);
35543	    computeBounds(geometry, primitiveDef, parser);
35544	    return Promise.all(pending).then(function() {
35545	        return primitiveDef.targets !== undefined ? addMorphTargets(geometry, primitiveDef.targets, parser) : geometry;
35546	    });
35547	}
35548
35549	/**
35550	 * @author Deepkolos / https://github.com/deepkolos
35551	 */ class WorkerPool {
35552	    _initWorker(workerId) {
35553	        if (!this.workers[workerId]) {
35554	            const worker = this.workerCreator();
35555	            worker.addEventListener('message', this._onMessage.bind(this, workerId));
35556	            this.workers[workerId] = worker;
35557	        }
35558	    }
35559	    _getIdleWorker() {
35560	        for(let i = 0; i < this.pool; i++)if (!(this.workerStatus & 1 << i)) return i;
35561	        return -1;
35562	    }
35563	    _onMessage(workerId, msg) {
35564	        const resolve = this.workersResolve[workerId];
35565	        resolve && resolve(msg);
35566	        if (this.queue.length) {
35567	            const { resolve, msg, transfer } = this.queue.shift();
35568	            this.workersResolve[workerId] = resolve;
35569	            this.workers[workerId].postMessage(msg, transfer);
35570	        } else {
35571	            this.workerStatus ^= 1 << workerId;
35572	        }
35573	    }
35574	    setWorkerCreator(workerCreator) {
35575	        this.workerCreator = workerCreator;
35576	    }
35577	    setWorkerLimit(pool) {
35578	        this.pool = pool;
35579	    }
35580	    postMessage(msg, transfer) {
35581	        return new Promise((resolve)=>{
35582	            const workerId = this._getIdleWorker();
35583	            if (workerId !== -1) {
35584	                this._initWorker(workerId);
35585	                this.workerStatus |= 1 << workerId;
35586	                this.workersResolve[workerId] = resolve;
35587	                this.workers[workerId].postMessage(msg, transfer);
35588	            } else {
35589	                this.queue.push({
35590	                    resolve,
35591	                    msg,
35592	                    transfer
35593	                });
35594	            }
35595	        });
35596	    }
35597	    dispose() {
35598	        this.workers.forEach((worker)=>worker.terminate());
35599	        this.workersResolve.length = 0;
35600	        this.workers.length = 0;
35601	        this.queue.length = 0;
35602	        this.workerStatus = 0;
35603	    }
35604	    constructor(pool = 4){
35605	        this.pool = pool;
35606	        this.queue = [];
35607	        this.workers = [];
35608	        this.workersResolve = [];
35609	        this.workerStatus = 0;
35610	    }
35611	}
35612
35613	const t = 0, n = 2, g$1 = 1, u = 2, T = 0, C$1 = 1, R = 10, it = 0, ct = 9, yt = 15, xt = 16, wt = 22, Ft = 37, Ct = 43, te$1 = 76, ae = 83, ge = 97, ue = 100, we = 103, Ae = 109, In = 165, Sn = 166, pi = 1000066e3;
35614	class Ii {
35615	    constructor(){
35616	        this.vkFormat = 0, this.typeSize = 1, this.pixelWidth = 0, this.pixelHeight = 0, this.pixelDepth = 0, this.layerCount = 0, this.faceCount = 1, this.supercompressionScheme = 0, this.levels = [], this.dataFormatDescriptor = [
35617	            {
35618	                vendorId: 0,
35619	                descriptorType: 0,
35620	                descriptorBlockSize: 0,
35621	                versionNumber: 2,
35622	                colorModel: 0,
35623	                colorPrimaries: 1,
35624	                transferFunction: 2,
35625	                flags: 0,
35626	                texelBlockDimension: [
35627	                    0,
35628	                    0,
35629	                    0,
35630	                    0
35631	                ],
35632	                bytesPlane: [
35633	                    0,
35634	                    0,
35635	                    0,
35636	                    0,
35637	                    0,
35638	                    0,
35639	                    0,
35640	                    0
35641	                ],
35642	                samples: []
35643	            }
35644	        ], this.keyValue = {}, this.globalData = null;
35645	    }
35646	}
35647	class Si {
35648	    _nextUint8() {
35649	        const t = this._dataView.getUint8(this._offset);
35650	        return this._offset += 1, t;
35651	    }
35652	    _nextUint16() {
35653	        const t = this._dataView.getUint16(this._offset, this._littleEndian);
35654	        return this._offset += 2, t;
35655	    }
35656	    _nextUint32() {
35657	        const t = this._dataView.getUint32(this._offset, this._littleEndian);
35658	        return this._offset += 4, t;
35659	    }
35660	    _nextUint64() {
35661	        const t = this._dataView.getUint32(this._offset, this._littleEndian) + 2 ** 32 * this._dataView.getUint32(this._offset + 4, this._littleEndian);
35662	        return this._offset += 8, t;
35663	    }
35664	    _nextInt32() {
35665	        const t = this._dataView.getInt32(this._offset, this._littleEndian);
35666	        return this._offset += 4, t;
35667	    }
35668	    _nextUint8Array(t) {
35669	        const e = new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + this._offset, t);
35670	        return this._offset += t, e;
35671	    }
35672	    _skip(t) {
35673	        return this._offset += t, this;
35674	    }
35675	    _scan(t, e) {
35676	        void 0 === e && (e = 0);
35677	        const n = this._offset;
35678	        let i = 0;
35679	        for(; this._dataView.getUint8(this._offset) !== e && i < t;)i++, this._offset++;
35680	        return i < t && this._offset++, new Uint8Array(this._dataView.buffer, this._dataView.byteOffset + n, i);
35681	    }
35682	    constructor(t, e, n, i){
35683	        this._dataView = void 0, this._littleEndian = void 0, this._offset = void 0, this._dataView = new DataView(t.buffer, t.byteOffset + e, n), this._littleEndian = i, this._offset = 0;
35684	    }
35685	}
35686	const Oi = [
35687	    171,
35688	    75,
35689	    84,
35690	    88,
35691	    32,
35692	    50,
35693	    48,
35694	    187,
35695	    13,
35696	    10,
35697	    26,
35698	    10
35699	];
35700	function Ti(t) {
35701	    return (new TextDecoder).decode(t);
35702	}
35703	function Pi(t) {
35704	    const e = new Uint8Array(t.buffer, t.byteOffset, Oi.length);
35705	    if (e[0] !== Oi[0] || e[1] !== Oi[1] || e[2] !== Oi[2] || e[3] !== Oi[3] || e[4] !== Oi[4] || e[5] !== Oi[5] || e[6] !== Oi[6] || e[7] !== Oi[7] || e[8] !== Oi[8] || e[9] !== Oi[9] || e[10] !== Oi[10] || e[11] !== Oi[11]) throw new Error("Missing KTX 2.0 identifier.");
35706	    const n = new Ii, i = 17 * Uint32Array.BYTES_PER_ELEMENT, s = new Si(t, Oi.length, i, true);
vendor: 4,191 bytes, lines 35707-35804
35707	    n.vkFormat = s._nextUint32(), n.typeSize = s._nextUint32(), n.pixelWidth = s._nextUint32(), n.pixelHeight = s._nextUint32(), n.pixelDepth = s._nextUint32(), n.layerCount = s._nextUint32(), n.faceCount = s._nextUint32();
35708	    const a = s._nextUint32();
35709	    n.supercompressionScheme = s._nextUint32();
35710	    const r = s._nextUint32(), o = s._nextUint32(), l = s._nextUint32(), f = s._nextUint32(), h = s._nextUint64(), U = s._nextUint64(), c = new Si(t, Oi.length + i, 3 * a * 8, true);
35711	    for(let e = 0; e < a; e++)n.levels.push({
35712	        levelData: new Uint8Array(t.buffer, t.byteOffset + c._nextUint64(), c._nextUint64()),
35713	        uncompressedByteLength: c._nextUint64()
35714	    });
35715	    const _ = new Si(t, r, o, true), p = {
35716	        vendorId: _._skip(4)._nextUint16(),
35717	        descriptorType: _._nextUint16(),
35718	        versionNumber: _._nextUint16(),
35719	        descriptorBlockSize: _._nextUint16(),
35720	        colorModel: _._nextUint8(),
35721	        colorPrimaries: _._nextUint8(),
35722	        transferFunction: _._nextUint8(),
35723	        flags: _._nextUint8(),
35724	        texelBlockDimension: [
35725	            _._nextUint8(),
35726	            _._nextUint8(),
35727	            _._nextUint8(),
35728	            _._nextUint8()
35729	        ],
35730	        bytesPlane: [
35731	            _._nextUint8(),
35732	            _._nextUint8(),
35733	            _._nextUint8(),
35734	            _._nextUint8(),
35735	            _._nextUint8(),
35736	            _._nextUint8(),
35737	            _._nextUint8(),
35738	            _._nextUint8()
35739	        ],
35740	        samples: []
35741	    }, g = (p.descriptorBlockSize / 4 - 6) / 4;
35742	    for(let t = 0; t < g; t++){
35743	        const e = {
35744	            bitOffset: _._nextUint16(),
35745	            bitLength: _._nextUint8(),
35746	            channelType: _._nextUint8(),
35747	            samplePosition: [
35748	                _._nextUint8(),
35749	                _._nextUint8(),
35750	                _._nextUint8(),
35751	                _._nextUint8()
35752	            ],
35753	            sampleLower: -Infinity,
35754	            sampleUpper: Infinity
35755	        };
35756	        64 & e.channelType ? (e.sampleLower = _._nextInt32(), e.sampleUpper = _._nextInt32()) : (e.sampleLower = _._nextUint32(), e.sampleUpper = _._nextUint32()), p.samples[t] = e;
35757	    }
35758	    n.dataFormatDescriptor.length = 0, n.dataFormatDescriptor.push(p);
35759	    const y = new Si(t, l, f, true);
35760	    for(; y._offset < f;){
35761	        const t = y._nextUint32(), e = y._scan(t), i = Ti(e);
35762	        if (n.keyValue[i] = y._nextUint8Array(t - e.byteLength - 1), i.match(/^ktx/i)) {
35763	            const t = Ti(n.keyValue[i]);
35764	            n.keyValue[i] = t.substring(0, t.lastIndexOf("\0"));
35765	        }
35766	        y._skip(t % 4 ? 4 - t % 4 : 0);
35767	    }
35768	    if (U <= 0) return n;
35769	    const x = new Si(t, h, U, true), u = x._nextUint16(), b = x._nextUint16(), d = x._nextUint32(), w = x._nextUint32(), m = x._nextUint32(), D = x._nextUint32(), B = [];
35770	    for(let t = 0; t < a; t++)B.push({
35771	        imageFlags: x._nextUint32(),
35772	        rgbSliceByteOffset: x._nextUint32(),
35773	        rgbSliceByteLength: x._nextUint32(),
35774	        alphaSliceByteOffset: x._nextUint32(),
35775	        alphaSliceByteLength: x._nextUint32()
35776	    });
35777	    const L = h + x._offset, v = L + d, A = v + w, k = A + m, V = new Uint8Array(t.buffer, t.byteOffset + L, d), I = new Uint8Array(t.buffer, t.byteOffset + v, w), S = new Uint8Array(t.buffer, t.byteOffset + A, m), F = new Uint8Array(t.buffer, t.byteOffset + k, D);
35778	    return n.globalData = {
35779	        endpointCount: u,
35780	        selectorCount: b,
35781	        imageDescs: B,
35782	        endpointsData: V,
35783	        selectorsData: I,
35784	        tablesData: S,
35785	        extendedData: F
35786	    }, n;
35787	}
35788
35789	let A, I, B;
35790	const g = {
35791	    env: {
35792	        emscripten_notify_memory_growth: function(A) {
35793	            B = new Uint8Array(I.exports.memory.buffer);
35794	        }
35795	    }
35796	};
35797	class Q {
35798	    init() {
35799	        return A || (A = "undefined" != typeof fetch ? fetch("data:application/wasm;base64," + C).then((A)=>A.arrayBuffer()).then((A)=>WebAssembly.instantiate(A, g)).then(this._init) : WebAssembly.instantiate(Buffer.from(C, "base64"), g).then(this._init), A);
35800	    }
35801	    _init(A) {
35802	        I = A.instance, g.env.emscripten_notify_memory_growth(0);
35803	    }
35804	    decode(A, g = 0) {
35805	        if (!I) throw new Error("ZSTDDecoder: Await .init() before decoding.");
35806	        const Q = A.byteLength, C = I.exports.malloc(Q);
35807	        B.set(A, C), g = g || Number(I.exports.ZSTD_findDecompressedSize(C, Q));
35808	        const E = I.exports.malloc(g), i = I.exports.ZSTD_decompress(E, g, C, Q), D = B.slice(E, E + i);
35809	        return I.exports.free(C), I.exports.free(E), D;
35810	    }
35811	}
35812	const C = 
vendor: 38,978 bytes, line 35812
35812"AGFzbQEAAAABpQEVYAF/AX9gAn9/AGADf39/AX9gBX9/f39/AX9gAX8AYAJ/fwF/YAR/f39/AX9gA39/fwBgBn9/f39/fwF/YAd/f39/f39/AX9gAn9/AX5gAn5+AX5gAABgBX9/f39/AGAGf39/f39/AGAIf39/f39/f38AYAl/f39/f39/f38AYAABf2AIf39/f39/f38Bf2ANf39/f39/f39/f39/fwF/YAF/AX4CJwEDZW52H2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGgABANpaAEFAAAFAgEFCwACAQABAgIFBQcAAwABDgsBAQcAEhMHAAUBDAQEAAANBwQCAgYCBAgDAwMDBgEACQkHBgICAAYGAgQUBwYGAwIGAAMCAQgBBwUGCgoEEQAEBAEIAwgDBQgDEA8IAAcABAUBcAECAgUEAQCAAgYJAX8BQaCgwAILB2AHBm1lbW9yeQIABm1hbGxvYwAoBGZyZWUAJgxaU1REX2lzRXJyb3IAaBlaU1REX2ZpbmREZWNvbXByZXNzZWRTaXplAFQPWlNURF9kZWNvbXByZXNzAEoGX3N0YXJ0ACQJBwEAQQELASQKussBaA8AIAAgACgCBCABajYCBAsZACAAKAIAIAAoAgRBH3F0QQAgAWtBH3F2CwgAIABBiH9LC34BBH9BAyEBIAAoAgQiA0EgTQRAIAAoAggiASAAKAIQTwRAIAAQDQ8LIAAoAgwiAiABRgRAQQFBAiADQSBJGw8LIAAgASABIAJrIANBA3YiBCABIARrIAJJIgEbIgJrIgQ2AgggACADIAJBA3RrNgIEIAAgBCgAADYCAAsgAQsUAQF/IAAgARACIQIgACABEAEgAgv3AQECfyACRQRAIABCADcCACAAQQA2AhAgAEIANwIIQbh/DwsgACABNgIMIAAgAUEEajYCECACQQRPBEAgACABIAJqIgFBfGoiAzYCCCAAIAMoAAA2AgAgAUF/ai0AACIBBEAgAEEIIAEQFGs2AgQgAg8LIABBADYCBEF/DwsgACABNgIIIAAgAS0AACIDNgIAIAJBfmoiBEEBTQRAIARBAWtFBEAgACABLQACQRB0IANyIgM2AgALIAAgAS0AAUEIdCADajYCAAsgASACakF/ai0AACIBRQRAIABBADYCBEFsDwsgAEEoIAEQFCACQQN0ams2AgQgAgsWACAAIAEpAAA3AAAgACABKQAINwAICy8BAX8gAUECdEGgHWooAgAgACgCAEEgIAEgACgCBGprQR9xdnEhAiAAIAEQASACCyEAIAFCz9bTvtLHq9lCfiAAfEIfiUKHla+vmLbem55/fgsdAQF/IAAoAgggACgCDEYEfyAAKAIEQSBGBUEACwuCBAEDfyACQYDAAE8EQCAAIAEgAhBnIAAPCyAAIAJqIQMCQCAAIAFzQQNxRQRAAkAgAkEBSARAIAAhAgwBCyAAQQNxRQRAIAAhAgwBCyAAIQIDQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADTw0BIAJBA3ENAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgA0F8aiIEIABJBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAsMACAAIAEpAAA3AAALQQECfyAAKAIIIgEgACgCEEkEQEEDDwsgACAAKAIEIgJBB3E2AgQgACABIAJBA3ZrIgE2AgggACABKAAANgIAQQALDAAgACABKAIANgAAC/cCAQJ/AkAgACABRg0AAkAgASACaiAASwRAIAAgAmoiBCABSw0BCyAAIAEgAhALDwsgACABc0EDcSEDAkACQCAAIAFJBEAgAwRAIAAhAwwDCyAAQQNxRQRAIAAhAwwCCyAAIQMDQCACRQ0EIAMgAS0AADoAACABQQFqIQEgAkF/aiECIANBAWoiA0EDcQ0ACwwBCwJAIAMNACAEQQNxBEADQCACRQ0FIAAgAkF/aiICaiIDIAEgAmotAAA6AAAgA0EDcQ0ACwsgAkEDTQ0AA0AgACACQXxqIgJqIAEgAmooAgA2AgAgAkEDSw0ACwsgAkUNAgNAIAAgAkF/aiICaiABIAJqLQAAOgAAIAINAAsMAgsgAkEDTQ0AIAIhBANAIAMgASgCADYCACABQQRqIQEgA0EEaiEDIARBfGoiBEEDSw0ACyACQQNxIQILIAJFDQADQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAAL8wICAn8BfgJAIAJFDQAgACACaiIDQX9qIAE6AAAgACABOgAAIAJBA0kNACADQX5qIAE6AAAgACABOgABIANBfWogAToAACAAIAE6AAIgAkEHSQ0AIANBfGogAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa0iBUIghiAFhCEFIAMgBGohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkFgaiICQR9LDQALCyAACy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAIajYCACADCy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAFajYCACADCx8AIAAgASACKAIEEAg2AgAgARAEGiAAIAJBCGo2AgQLCAAgAGdBH3MLugUBDX8jAEEQayIKJAACfyAEQQNNBEAgCkEANgIMIApBDGogAyAEEAsaIAAgASACIApBDGpBBBAVIgBBbCAAEAMbIAAgACAESxsMAQsgAEEAIAEoAgBBAXRBAmoQECENQVQgAygAACIGQQ9xIgBBCksNABogAiAAQQVqNgIAIAMgBGoiAkF8aiEMIAJBeWohDiACQXtqIRAgAEEGaiELQQQhBSAGQQR2IQRBICAAdCIAQQFyIQkgASgCACEPQQAhAiADIQYCQANAIAlBAkggAiAPS3JFBEAgAiEHAkAgCARAA0AgBEH//wNxQf//A0YEQCAHQRhqIQcgBiAQSQR/IAZBAmoiBigAACAFdgUgBUEQaiEFIARBEHYLIQQMAQsLA0AgBEEDcSIIQQNGBEAgBUECaiEFIARBAnYhBCAHQQNqIQcMAQsLIAcgCGoiByAPSw0EIAVBAmohBQNAIAIgB0kEQCANIAJBAXRqQQA7AQAgAkEBaiECDAELCyAGIA5LQQAgBiAFQQN1aiIHIAxLG0UEQCAHKAAAIAVBB3EiBXYhBAwCCyAEQQJ2IQQLIAYhBwsCfyALQX9qIAQgAEF/anEiBiAAQQF0QX9qIgggCWsiEUkNABogBCAIcSIEQQAgESAEIABIG2shBiALCyEIIA0gAkEBdGogBkF/aiIEOwEAIAlBASAGayAEIAZBAUgbayEJA0AgCSAASARAIABBAXUhACALQX9qIQsMAQsLAn8gByAOS0EAIAcgBSAIaiIFQQN1aiIGIAxLG0UEQCAFQQdxDAELIAUgDCIGIAdrQQN0awshBSACQQFqIQIgBEUhCCAGKAAAIAVBH3F2IQQMAQsLQWwgCUEBRyAFQSBKcg0BGiABIAJBf2o2AgAgBiAFQQdqQQN1aiADawwBC0FQCyEAIApBEGokACAACwkAQQFBBSAAGwsMACAAIAEoAAA2AAALqgMBCn8jAEHwAGsiCiQAIAJBAWohDiAAQQhqIQtBgIAEIAVBf2p0QRB1IQxBACECQQEhBkEBIAV0IglBf2oiDyEIA0AgAiAORkUEQAJAIAEgAkEBdCINai8BACIHQf//A0YEQCALIAhBA3RqIAI2AgQgCEF/aiEIQQEhBwwBCyAGQQAgDCAHQRB0QRB1ShshBgsgCiANaiAHOwEAIAJBAWohAgwBCwsgACAFNgIEIAAgBjYCACAJQQN2IAlBAXZqQQNqIQxBACEAQQAhBkEAIQIDQCAGIA5GBEADQAJAIAAgCUYNACAKIAsgAEEDdGoiASgCBCIGQQF0aiICIAIvAQAiAkEBajsBACABIAUgAhAUayIIOgADIAEgAiAIQf8BcXQgCWs7AQAgASAEIAZBAnQiAmooAgA6AAIgASACIANqKAIANgIEIABBAWohAAwBCwsFIAEgBkEBdGouAQAhDUEAIQcDQCAHIA1ORQRAIAsgAkEDdGogBjYCBANAIAIgDGogD3EiAiAISw0ACyAHQQFqIQcMAQsLIAZBAWohBgwBCwsgCkHwAGokAAsjAEIAIAEQCSAAhUKHla+vmLbem55/fkLj3MqV/M7y9YV/fAsQACAAQn43AwggACABNgIACyQBAX8gAARAIAEoAgQiAgRAIAEoAgggACACEQEADwsgABAmCwsfACAAIAEgAi8BABAINgIAIAEQBBogACACQQRqNgIEC0oBAX9BoCAoAgAiASAAaiIAQX9MBEBBiCBBMDYCAEF/DwsCQCAAPwBBEHRNDQAgABBmDQBBiCBBMDYCAEF/DwtBoCAgADYCACABC9cBAQh/Qbp/IQoCQCACKAIEIgggAigCACIJaiIOIAEgAGtLDQBBbCEKIAkgBCADKAIAIgtrSw0AIAAgCWoiBCACKAIIIgxrIQ0gACABQWBqIg8gCyAJQQAQKSADIAkgC2o2AgACQAJAIAwgBCAFa00EQCANIQUMAQsgDCAEIAZrSw0CIAcgDSAFayIAaiIBIAhqIAdNBEAgBCABIAgQDxoMAgsgBCABQQAgAGsQDyEBIAIgACAIaiIINgIEIAEgAGshBAsgBCAPIAUgCEEBECkLIA4hCgsgCgubAgEBfyMAQYABayINJAAgDSADNgJ8AkAgAkEDSwRAQX8hCQwBCwJAAkACQAJAIAJBAWsOAwADAgELIAZFBEBBuH8hCQwEC0FsIQkgBS0AACICIANLDQMgACAHIAJBAnQiAmooAgAgAiAIaigCABA7IAEgADYCAEEBIQkMAwsgASAJNgIAQQAhCQwCCyAKRQRAQWwhCQwCC0EAIQkgC0UgDEEZSHINAUEIIAR0QQhqIQBBACECA0AgAiAATw0CIAJBQGshAgwAAAsAC0FsIQkgDSANQfwAaiANQfgAaiAFIAYQFSICEAMNACANKAJ4IgMgBEsNACAAIA0gDSgCfCAHIAggAxAYIAEgADYCACACIQkLIA1BgAFqJAAgCQsLACAAIAEgAhALGgsQACAALwAAIAAtAAJBEHRyCy8AAn9BuH8gAUEISQ0AGkFyIAAoAAQiAEF3Sw0AGkG4fyAAQQhqIgAgACABSxsLCwkAIAAgATsAAAsDAAELigYBBX8gACAAKAIAIgVBfnE2AgBBACAAIAVBAXZqQYQgKAIAIgQgAEYbIQECQAJAIAAoAgQiAkUNACACKAIAIgNBAXENACACQQhqIgUgA0EBdkF4aiIDQQggA0EISxtnQR9zQQJ0QYAfaiIDKAIARgRAIAMgAigCDDYCAAsgAigCCCIDBEAgAyACKAIMNgIECyACKAIMIgMEQCADIAIoAgg2AgALIAIgAigCACAAKAIAQX5xajYCAEGEICEAAkACQCABRQ0AIAEgAjYCBCABKAIAIgNBAXENASADQQF2QXhqIgNBCCADQQhLG2dBH3NBAnRBgB9qIgMoAgAgAUEIakYEQCADIAEoAgw2AgALIAEoAggiAwRAIAMgASgCDDYCBAsgASgCDCIDBEAgAyABKAIINgIAQYQgKAIAIQQLIAIgAigCACABKAIAQX5xajYCACABIARGDQAgASABKAIAQQF2akEEaiEACyAAIAI2AgALIAIoAgBBAXZBeGoiAEEIIABBCEsbZ0Efc0ECdEGAH2oiASgCACEAIAEgBTYCACACIAA2AgwgAkEANgIIIABFDQEgACAFNgIADwsCQCABRQ0AIAEoAgAiAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAigCACABQQhqRgRAIAIgASgCDDYCAAsgASgCCCICBEAgAiABKAIMNgIECyABKAIMIgIEQCACIAEoAgg2AgBBhCAoAgAhBAsgACAAKAIAIAEoAgBBfnFqIgI2AgACQCABIARHBEAgASABKAIAQQF2aiAANgIEIAAoAgAhAgwBC0GEICAANgIACyACQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgIoAgAhASACIABBCGoiAjYCACAAIAE2AgwgAEEANgIIIAFFDQEgASACNgIADwsgBUEBdkF4aiIBQQggAUEISxtnQR9zQQJ0QYAfaiICKAIAIQEgAiAAQQhqIgI2AgAgACABNgIMIABBADYCCCABRQ0AIAEgAjYCAAsLDgAgAARAIABBeGoQJQsLgAIBA38CQCAAQQ9qQXhxQYQgKAIAKAIAQQF2ayICEB1Bf0YNAAJAQYQgKAIAIgAoAgAiAUEBcQ0AIAFBAXZBeGoiAUEIIAFBCEsbZ0Efc0ECdEGAH2oiASgCACAAQQhqRgRAIAEgACgCDDYCAAsgACgCCCIBBEAgASAAKAIMNgIECyAAKAIMIgFFDQAgASAAKAIINgIAC0EBIQEgACAAKAIAIAJBAXRqIgI2AgAgAkEBcQ0AIAJBAXZBeGoiAkEIIAJBCEsbZ0Efc0ECdEGAH2oiAygCACECIAMgAEEIaiIDNgIAIAAgAjYCDCAAQQA2AgggAkUNACACIAM2AgALIAELtwIBA38CQAJAIABBASAAGyICEDgiAA0AAkACQEGEICgCACIARQ0AIAAoAgAiA0EBcQ0AIAAgA0EBcjYCACADQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgAgAEEIakYEQCABIAAoAgw2AgALIAAoAggiAQRAIAEgACgCDDYCBAsgACgCDCIBBEAgASAAKAIINgIACyACECchAkEAIQFBhCAoAgAhACACDQEgACAAKAIAQX5xNgIAQQAPCyACQQ9qQXhxIgMQHSICQX9GDQIgAkEHakF4cSIAIAJHBEAgACACaxAdQX9GDQMLAkBBhCAoAgAiAUUEQEGAICAANgIADAELIAAgATYCBAtBhCAgADYCACAAIANBAXRBAXI2AgAMAQsgAEUNAQsgAEEIaiEBCyABC7kDAQJ/IAAgA2ohBQJAIANBB0wEQANAIAAgBU8NAiAAIAItAAA6AAAgAEEBaiEAIAJBAWohAgwAAAsACyAEQQFGBEACQCAAIAJrIgZBB00EQCAAIAItAAA6AAAgACACLQABOgABIAAgAi0AAjoAAiAAIAItAAM6AAMgAEEEaiACIAZBAnQiBkHAHmooAgBqIgIQFyACIAZB4B5qKAIAayECDAELIAAgAhAMCyACQQhqIQIgAEEIaiEACwJAAkACQAJAIAUgAU0EQCAAIANqIQEgBEEBRyAAIAJrQQ9Kcg0BA0AgACACEAwgAkEIaiECIABBCGoiACABSQ0ACwwFCyAAIAFLBEAgACEBDAQLIARBAUcgACACa0EPSnINASAAIQMgAiEEA0AgAyAEEAwgBEEIaiEEIANBCGoiAyABSQ0ACwwCCwNAIAAgAhAHIAJBEGohAiAAQRBqIgAgAUkNAAsMAwsgACEDIAIhBANAIAMgBBAHIARBEGohBCADQRBqIgMgAUkNAAsLIAIgASAAa2ohAgsDQCABIAVPDQEgASACLQAAOgAAIAFBAWohASACQQFqIQIMAAALAAsLQQECfyAAIAAoArjgASIDNgLE4AEgACgCvOABIQQgACABNgK84AEgACABIAJqNgK44AEgACABIAQgA2tqNgLA4AELpgEBAX8gACAAKALs4QEQFjYCyOABIABCADcD+OABIABCADcDuOABIABBwOABakIANwMAIABBqNAAaiIBQYyAgOAANgIAIABBADYCmOIBIABCADcDiOEBIABCAzcDgOEBIABBrNABakHgEikCADcCACAAQbTQAWpB6BIoAgA2AgAgACABNgIMIAAgAEGYIGo2AgggACAAQaAwajYCBCAAIABBEGo2AgALYQEBf0G4fyEDAkAgAUEDSQ0AIAIgABAhIgFBA3YiADYCCCACIAFBAXE2AgQgAiABQQF2QQNxIgM2AgACQCADQX9qIgFBAksNAAJAIAFBAWsOAgEAAgtBbA8LIAAhAwsgAwsMACAAIAEgAkEAEC4LiAQCA38CfiADEBYhBCAAQQBBKBAQIQAgBCACSwRAIAQPCyABRQRAQX8PCwJAAkAgA0EBRg0AIAEoAAAiBkGo6r5pRg0AQXYhAyAGQXBxQdDUtMIBRw0BQQghAyACQQhJDQEgAEEAQSgQECEAIAEoAAQhASAAQQE2AhQgACABrTcDAEEADwsgASACIAMQLyIDIAJLDQAgACADNgIYQXIhAyABIARqIgVBf2otAAAiAkEIcQ0AIAJBIHEiBkUEQEFwIQMgBS0AACIFQacBSw0BIAVBB3GtQgEgBUEDdkEKaq2GIgdCA4h+IAd8IQggBEEBaiEECyACQQZ2IQMgAkECdiEFAkAgAkEDcUF/aiICQQJLBEBBACECDAELAkACQAJAIAJBAWsOAgECAAsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAVBAXEhBQJ+AkACQAJAIANBf2oiA0ECTQRAIANBAWsOAgIDAQtCfyAGRQ0DGiABIARqMQAADAMLIAEgBGovAACtQoACfAwCCyABIARqKAAArQwBCyABIARqKQAACyEHIAAgBTYCICAAIAI2AhwgACAHNwMAQQAhAyAAQQA2AhQgACAHIAggBhsiBzcDCCAAIAdCgIAIIAdCgIAIVBs+AhALIAMLWwEBf0G4fyEDIAIQFiICIAFNBH8gACACakF/ai0AACIAQQNxQQJ0QaAeaigCACACaiAAQQZ2IgFBAnRBsB5qKAIAaiAAQSBxIgBFaiABRSAAQQV2cWoFQbh/CwsdACAAKAKQ4gEQWiAAQQA2AqDiASAAQgA3A5DiAQu1AwEFfyMAQZACayIKJABBuH8hBgJAIAVFDQAgBCwAACIIQf8BcSEHAkAgCEF/TARAIAdBgn9qQQF2IgggBU8NAkFsIQYgB0GBf2oiBUGAAk8NAiAEQQFqIQdBACEGA0AgBiAFTwRAIAUhBiAIIQcMAwUgACAGaiAHIAZBAXZqIgQtAABBBHY6AAAgACAGQQFyaiAELQAAQQ9xOgAAIAZBAmohBgwBCwAACwALIAcgBU8NASAAIARBAWogByAKEFMiBhADDQELIAYhBEEAIQYgAUEAQTQQECEJQQAhBQNAIAQgBkcEQCAAIAZqIggtAAAiAUELSwRAQWwhBgwDBSAJIAFBAnRqIgEgASgCAEEBajYCACAGQQFqIQZBASAILQAAdEEBdSAFaiEFDAILAAsLQWwhBiAFRQ0AIAUQFEEBaiIBQQxLDQAgAyABNgIAQQFBASABdCAFayIDEBQiAXQgA0cNACAAIARqIAFBAWoiADoAACAJIABBAnRqIgAgACgCAEEBajYCACAJKAIEIgBBAkkgAEEBcXINACACIARBAWo2AgAgB0EBaiEGCyAKQZACaiQAIAYLxhEBDH8jAEHwAGsiBSQAQWwhCwJAIANBCkkNACACLwAAIQogAi8AAiEJIAIvAAQhByAFQQhqIAQQDgJAIAMgByAJIApqakEGaiIMSQ0AIAUtAAohCCAFQdgAaiACQQZqIgIgChAGIgsQAw0BIAVBQGsgAiAKaiICIAkQBiILEAMNASAFQShqIAIgCWoiAiAHEAYiCxADDQEgBUEQaiACIAdqIAMgDGsQBiILEAMNASAAIAFqIg9BfWohECAEQQRqIQZBASELIAAgAUEDakECdiIDaiIMIANqIgIgA2oiDiEDIAIhBCAMIQcDQCALIAMgEElxBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgCS0AAyELIAcgBiAFQUBrIAgQAkECdGoiCS8BADsAACAFQUBrIAktAAIQASAJLQADIQogBCAGIAVBKGogCBACQQJ0aiIJLwEAOwAAIAVBKGogCS0AAhABIAktAAMhCSADIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgDS0AAyENIAAgC2oiCyAGIAVB2ABqIAgQAkECdGoiAC8BADsAACAFQdgAaiAALQACEAEgAC0AAyEAIAcgCmoiCiAGIAVBQGsgCBACQQJ0aiIHLwEAOwAAIAVBQGsgBy0AAhABIActAAMhByAEIAlqIgkgBiAFQShqIAgQAkECdGoiBC8BADsAACAFQShqIAQtAAIQASAELQADIQQgAyANaiIDIAYgBUEQaiAIEAJBAnRqIg0vAQA7AAAgBUEQaiANLQACEAEgACALaiEAIAcgCmohByAEIAlqIQQgAyANLQADaiEDIAVB2ABqEA0gBUFAaxANciAFQShqEA1yIAVBEGoQDXJFIQsMAQsLIAQgDksgByACS3INAEFsIQsgACAMSw0BIAxBfWohCQNAQQAgACAJSSAFQdgAahAEGwRAIAAgBiAFQdgAaiAIEAJBAnRqIgovAQA7AAAgBUHYAGogCi0AAhABIAAgCi0AA2oiACAGIAVB2ABqIAgQAkECdGoiCi8BADsAACAFQdgAaiAKLQACEAEgACAKLQADaiEADAEFIAxBfmohCgNAIAVB2ABqEAQgACAKS3JFBEAgACAGIAVB2ABqIAgQAkECdGoiCS8BADsAACAFQdgAaiAJLQACEAEgACAJLQADaiEADAELCwNAIAAgCk0EQCAAIAYgBUHYAGogCBACQQJ0aiIJLwEAOwAAIAVB2ABqIAktAAIQASAAIAktAANqIQAMAQsLAkAgACAMTw0AIAAgBiAFQdgAaiAIEAIiAEECdGoiDC0AADoAACAMLQADQQFGBEAgBUHYAGogDC0AAhABDAELIAUoAlxBH0sNACAFQdgAaiAGIABBAnRqLQACEAEgBSgCXEEhSQ0AIAVBIDYCXAsgAkF9aiEMA0BBACAHIAxJIAVBQGsQBBsEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiIAIAYgBUFAayAIEAJBAnRqIgcvAQA7AAAgBUFAayAHLQACEAEgACAHLQADaiEHDAEFIAJBfmohDANAIAVBQGsQBCAHIAxLckUEQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwNAIAcgDE0EQCAHIAYgBUFAayAIEAJBAnRqIgAvAQA7AAAgBUFAayAALQACEAEgByAALQADaiEHDAELCwJAIAcgAk8NACAHIAYgBUFAayAIEAIiAEECdGoiAi0AADoAACACLQADQQFGBEAgBUFAayACLQACEAEMAQsgBSgCREEfSw0AIAVBQGsgBiAAQQJ0ai0AAhABIAUoAkRBIUkNACAFQSA2AkQLIA5BfWohAgNAQQAgBCACSSAFQShqEAQbBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2oiACAGIAVBKGogCBACQQJ0aiIELwEAOwAAIAVBKGogBC0AAhABIAAgBC0AA2ohBAwBBSAOQX5qIQIDQCAFQShqEAQgBCACS3JFBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsDQCAEIAJNBEAgBCAGIAVBKGogCBACQQJ0aiIALwEAOwAAIAVBKGogAC0AAhABIAQgAC0AA2ohBAwBCwsCQCAEIA5PDQAgBCAGIAVBKGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBKGogAi0AAhABDAELIAUoAixBH0sNACAFQShqIAYgAEECdGotAAIQASAFKAIsQSFJDQAgBUEgNgIsCwNAQQAgAyAQSSAFQRBqEAQbBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2oiACAGIAVBEGogCBACQQJ0aiICLwEAOwAAIAVBEGogAi0AAhABIAAgAi0AA2ohAwwBBSAPQX5qIQIDQCAFQRBqEAQgAyACS3JFBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsDQCADIAJNBEAgAyAGIAVBEGogCBACQQJ0aiIALwEAOwAAIAVBEGogAC0AAhABIAMgAC0AA2ohAwwBCwsCQCADIA9PDQAgAyAGIAVBEGogCBACIgBBAnRqIgItAAA6AAAgAi0AA0EBRgRAIAVBEGogAi0AAhABDAELIAUoAhRBH0sNACAFQRBqIAYgAEECdGotAAIQASAFKAIUQSFJDQAgBUEgNgIUCyABQWwgBUHYAGoQCiAFQUBrEApxIAVBKGoQCnEgBUEQahAKcRshCwwJCwAACwALAAALAAsAAAsACwAACwALQWwhCwsgBUHwAGokACALC7UEAQ5/IwBBEGsiBiQAIAZBBGogABAOQVQhBQJAIARB3AtJDQAgBi0ABCEHIANB8ARqQQBB7AAQECEIIAdBDEsNACADQdwJaiIJIAggBkEIaiAGQQxqIAEgAhAxIhAQA0UEQCAGKAIMIgQgB0sNASADQdwFaiEPIANBpAVqIREgAEEEaiESIANBqAVqIQEgBCEFA0AgBSICQX9qIQUgCCACQQJ0aigCAEUNAAsgAkEBaiEOQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgASALaiAKNgIAIAVBAWohBSAKIAxqIQoMAQsLIAEgCjYCAEEAIQUgBigCCCELA0AgBSALRkUEQCABIAUgCWotAAAiDEECdGoiDSANKAIAIg1BAWo2AgAgDyANQQF0aiINIAw6AAEgDSAFOgAAIAVBAWohBQwBCwtBACEBIANBADYCqAUgBEF/cyAHaiEJQQEhBQNAIAUgDk9FBEAgCCAFQQJ0IgtqKAIAIQwgAyALaiABNgIAIAwgBSAJanQgAWohASAFQQFqIQUMAQsLIAcgBEEBaiIBIAJrIgRrQQFqIQgDQEEBIQUgBCAIT0UEQANAIAUgDk9FBEAgBUECdCIJIAMgBEE0bGpqIAMgCWooAgAgBHY2AgAgBUEBaiEFDAELCyAEQQFqIQQMAQsLIBIgByAPIAogESADIAIgARBkIAZBAToABSAGIAc6AAYgACAGKAIENgIACyAQIQULIAZBEGokACAFC8ENAQt/IwBB8ABrIgUkAEFsIQkCQCADQQpJDQAgAi8AACEKIAIvAAIhDCACLwAEIQYgBUEIaiAEEA4CQCADIAYgCiAMampBBmoiDUkNACAFLQAKIQcgBUHYAGogAkEGaiICIAoQBiIJEAMNASAFQUBrIAIgCmoiAiAMEAYiCRADDQEgBUEoaiACIAxqIgIgBhAGIgkQAw0BIAVBEGogAiAGaiADIA1rEAYiCRADDQEgACABaiIOQX1qIQ8gBEEEaiEGQQEhCSAAIAFBA2pBAnYiAmoiCiACaiIMIAJqIg0hAyAMIQQgCiECA0AgCSADIA9JcQRAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAACAGIAVBQGsgBxACQQF0aiIILQAAIQsgBUFAayAILQABEAEgAiALOgAAIAYgBUEoaiAHEAJBAXRqIggtAAAhCyAFQShqIAgtAAEQASAEIAs6AAAgBiAFQRBqIAcQAkEBdGoiCC0AACELIAVBEGogCC0AARABIAMgCzoAACAGIAVB2ABqIAcQAkEBdGoiCC0AACELIAVB2ABqIAgtAAEQASAAIAs6AAEgBiAFQUBrIAcQAkEBdGoiCC0AACELIAVBQGsgCC0AARABIAIgCzoAASAGIAVBKGogBxACQQF0aiIILQAAIQsgBUEoaiAILQABEAEgBCALOgABIAYgBUEQaiAHEAJBAXRqIggtAAAhCyAFQRBqIAgtAAEQASADIAs6AAEgA0ECaiEDIARBAmohBCACQQJqIQIgAEECaiEAIAkgBUHYAGoQDUVxIAVBQGsQDUVxIAVBKGoQDUVxIAVBEGoQDUVxIQkMAQsLIAQgDUsgAiAMS3INAEFsIQkgACAKSw0BIApBfWohCQNAIAVB2ABqEAQgACAJT3JFBEAgBiAFQdgAaiAHEAJBAXRqIggtAAAhCyAFQdgAaiAILQABEAEgACALOgAAIAYgBUHYAGogBxACQQF0aiIILQAAIQsgBUHYAGogCC0AARABIAAgCzoAASAAQQJqIQAMAQsLA0AgBUHYAGoQBCAAIApPckUEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCwNAIAAgCkkEQCAGIAVB2ABqIAcQAkEBdGoiCS0AACEIIAVB2ABqIAktAAEQASAAIAg6AAAgAEEBaiEADAELCyAMQX1qIQADQCAFQUBrEAQgAiAAT3JFBEAgBiAFQUBrIAcQAkEBdGoiCi0AACEJIAVBQGsgCi0AARABIAIgCToAACAGIAVBQGsgBxACQQF0aiIKLQAAIQkgBUFAayAKLQABEAEgAiAJOgABIAJBAmohAgwBCwsDQCAFQUBrEAQgAiAMT3JFBEAgBiAFQUBrIAcQAkEBdGoiAC0AACEKIAVBQGsgAC0AARABIAIgCjoAACACQQFqIQIMAQsLA0AgAiAMSQRAIAYgBUFAayAHEAJBAXRqIgAtAAAhCiAFQUBrIAAtAAEQASACIAo6AAAgAkEBaiECDAELCyANQX1qIQADQCAFQShqEAQgBCAAT3JFBEAgBiAFQShqIAcQAkEBdGoiAi0AACEKIAVBKGogAi0AARABIAQgCjoAACAGIAVBKGogBxACQQF0aiICLQAAIQogBUEoaiACLQABEAEgBCAKOgABIARBAmohBAwBCwsDQCAFQShqEAQgBCANT3JFBEAgBiAFQShqIAcQAkEBdGoiAC0AACECIAVBKGogAC0AARABIAQgAjoAACAEQQFqIQQMAQsLA0AgBCANSQRAIAYgBUEoaiAHEAJBAXRqIgAtAAAhAiAFQShqIAAtAAEQASAEIAI6AAAgBEEBaiEEDAELCwNAIAVBEGoQBCADIA9PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIAYgBUEQaiAHEAJBAXRqIgAtAAAhAiAFQRBqIAAtAAEQASADIAI6AAEgA0ECaiEDDAELCwNAIAVBEGoQBCADIA5PckUEQCAGIAVBEGogBxACQQF0aiIALQAAIQIgBUEQaiAALQABEAEgAyACOgAAIANBAWohAwwBCwsDQCADIA5JBEAgBiAFQRBqIAcQAkEBdGoiAC0AACECIAVBEGogAC0AARABIAMgAjoAACADQQFqIQMMAQsLIAFBbCAFQdgAahAKIAVBQGsQCnEgBUEoahAKcSAFQRBqEApxGyEJDAELQWwhCQsgBUHwAGokACAJC8oCAQR/IwBBIGsiBSQAIAUgBBAOIAUtAAIhByAFQQhqIAIgAxAGIgIQA0UEQCAEQQRqIQIgACABaiIDQX1qIQQDQCAFQQhqEAQgACAET3JFBEAgAiAFQQhqIAcQAkEBdGoiBi0AACEIIAVBCGogBi0AARABIAAgCDoAACACIAVBCGogBxACQQF0aiIGLQAAIQggBUEIaiAGLQABEAEgACAIOgABIABBAmohAAwBCwsDQCAFQQhqEAQgACADT3JFBEAgAiAFQQhqIAcQAkEBdGoiBC0AACEGIAVBCGogBC0AARABIAAgBjoAACAAQQFqIQAMAQsLA0AgACADT0UEQCACIAVBCGogBxACQQF0aiIELQAAIQYgBUEIaiAELQABEAEgACAGOgAAIABBAWohAAwBCwsgAUFsIAVBCGoQChshAgsgBUEgaiQAIAILtgMBCX8jAEEQayIGJAAgBkEANgIMIAZBADYCCEFUIQQCQAJAIANBQGsiDCADIAZBCGogBkEMaiABIAIQMSICEAMNACAGQQRqIAAQDiAGKAIMIgcgBi0ABEEBaksNASAAQQRqIQogBkEAOgAFIAYgBzoABiAAIAYoAgQ2AgAgB0EBaiEJQQEhBANAIAQgCUkEQCADIARBAnRqIgEoAgAhACABIAU2AgAgACAEQX9qdCAFaiEFIARBAWohBAwBCwsgB0EBaiEHQQAhBSAGKAIIIQkDQCAFIAlGDQEgAyAFIAxqLQAAIgRBAnRqIgBBASAEdEEBdSILIAAoAgAiAWoiADYCACAHIARrIQhBACEEAkAgC0EDTQRAA0AgBCALRg0CIAogASAEakEBdGoiACAIOgABIAAgBToAACAEQQFqIQQMAAALAAsDQCABIABPDQEgCiABQQF0aiIEIAg6AAEgBCAFOgAAIAQgCDoAAyAEIAU6AAIgBCAIOgAFIAQgBToABCAEIAg6AAcgBCAFOgAGIAFBBGohAQwAAAsACyAFQQFqIQUMAAALAAsgAiEECyAGQRBqJAAgBAutAQECfwJAQYQgKAIAIABHIAAoAgBBAXYiAyABa0F4aiICQXhxQQhHcgR/IAIFIAMQJ0UNASACQQhqC0EQSQ0AIAAgACgCACICQQFxIAAgAWpBD2pBeHEiASAAa0EBdHI2AgAgASAANgIEIAEgASgCAEEBcSAAIAJBAXZqIAFrIgJBAXRyNgIAQYQgIAEgAkH/////B3FqQQRqQYQgKAIAIABGGyABNgIAIAEQJQsLygIBBX8CQAJAAkAgAEEIIABBCEsbZ0EfcyAAaUEBR2oiAUEESSAAIAF2cg0AIAFBAnRB/B5qKAIAIgJFDQADQCACQXhqIgMoAgBBAXZBeGoiBSAATwRAIAIgBUEIIAVBCEsbZ0Efc0ECdEGAH2oiASgCAEYEQCABIAIoAgQ2AgALDAMLIARBHksNASAEQQFqIQQgAigCBCICDQALC0EAIQMgAUEgTw0BA0AgAUECdEGAH2ooAgAiAkUEQCABQR5LIQIgAUEBaiEBIAJFDQEMAwsLIAIgAkF4aiIDKAIAQQF2QXhqIgFBCCABQQhLG2dBH3NBAnRBgB9qIgEoAgBGBEAgASACKAIENgIACwsgAigCACIBBEAgASACKAIENgIECyACKAIEIgEEQCABIAIoAgA2AgALIAMgAygCAEEBcjYCACADIAAQNwsgAwvhCwINfwV+IwBB8ABrIgckACAHIAAoAvDhASIINgJcIAEgAmohDSAIIAAoAoDiAWohDwJAAkAgBUUEQCABIQQMAQsgACgCxOABIRAgACgCwOABIREgACgCvOABIQ4gAEEBNgKM4QFBACEIA0AgCEEDRwRAIAcgCEECdCICaiAAIAJqQazQAWooAgA2AkQgCEEBaiEIDAELC0FsIQwgB0EYaiADIAQQBhADDQEgB0EsaiAHQRhqIAAoAgAQEyAHQTRqIAdBGGogACgCCBATIAdBPGogB0EYaiAAKAIEEBMgDUFgaiESIAEhBEEAIQwDQCAHKAIwIAcoAixBA3RqKQIAIhRCEIinQf8BcSEIIAcoAkAgBygCPEEDdGopAgAiFUIQiKdB/wFxIQsgBygCOCAHKAI0QQN0aikCACIWQiCIpyEJIBVCIIghFyAUQiCIpyECAkAgFkIQiKdB/wFxIgNBAk8EQAJAIAZFIANBGUlyRQRAIAkgB0EYaiADQSAgBygCHGsiCiAKIANLGyIKEAUgAyAKayIDdGohCSAHQRhqEAQaIANFDQEgB0EYaiADEAUgCWohCQwBCyAHQRhqIAMQBSAJaiEJIAdBGGoQBBoLIAcpAkQhGCAHIAk2AkQgByAYNwNIDAELAkAgA0UEQCACBEAgBygCRCEJDAMLIAcoAkghCQwBCwJAAkAgB0EYakEBEAUgCSACRWpqIgNBA0YEQCAHKAJEQX9qIgMgA0VqIQkMAQsgA0ECdCAHaigCRCIJIAlFaiEJIANBAUYNAQsgByAHKAJINgJMCwsgByAHKAJENgJIIAcgCTYCRAsgF6chAyALBEAgB0EYaiALEAUgA2ohAwsgCCALakEUTwRAIAdBGGoQBBoLIAgEQCAHQRhqIAgQBSACaiECCyAHQRhqEAQaIAcgB0EYaiAUQhiIp0H/AXEQCCAUp0H//wNxajYCLCAHIAdBGGogFUIYiKdB/wFxEAggFadB//8DcWo2AjwgB0EYahAEGiAHIAdBGGogFkIYiKdB/wFxEAggFqdB//8DcWo2AjQgByACNgJgIAcoAlwhCiAHIAk2AmggByADNgJkAkACQAJAIAQgAiADaiILaiASSw0AIAIgCmoiEyAPSw0AIA0gBGsgC0Egak8NAQsgByAHKQNoNwMQIAcgBykDYDcDCCAEIA0gB0EIaiAHQdwAaiAPIA4gESAQEB4hCwwBCyACIARqIQggBCAKEAcgAkERTwRAIARBEGohAgNAIAIgCkEQaiIKEAcgAkEQaiICIAhJDQALCyAIIAlrIQIgByATNgJcIAkgCCAOa0sEQCAJIAggEWtLBEBBbCELDAILIBAgAiAOayICaiIKIANqIBBNBEAgCCAKIAMQDxoMAgsgCCAKQQAgAmsQDyEIIAcgAiADaiIDNgJkIAggAmshCCAOIQILIAlBEE8EQCADIAhqIQMDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALDAELAkAgCUEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgCUECdCIDQcAeaigCAGoiAhAXIAIgA0HgHmooAgBrIQIgBygCZCEDDAELIAggAhAMCyADQQlJDQAgAyAIaiEDIAhBCGoiCCACQQhqIgJrQQ9MBEADQCAIIAIQDCACQQhqIQIgCEEIaiIIIANJDQAMAgALAAsDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALCyAHQRhqEAQaIAsgDCALEAMiAhshDCAEIAQgC2ogAhshBCAFQX9qIgUNAAsgDBADDQFBbCEMIAdBGGoQBEECSQ0BQQAhCANAIAhBA0cEQCAAIAhBAnQiAmpBrNABaiACIAdqKAJENgIAIAhBAWohCAwBCwsgBygCXCEIC0G6fyEMIA8gCGsiACANIARrSw0AIAQEfyAEIAggABALIABqBUEACyABayEMCyAHQfAAaiQAIAwLkRcCFn8FfiMAQdABayIHJAAgByAAKALw4QEiCDYCvAEgASACaiESIAggACgCgOIBaiETAkACQCAFRQRAIAEhAwwBCyAAKALE4AEhESAAKALA4AEhFSAAKAK84AEhDyAAQQE2AozhAUEAIQgDQCAIQQNHBEAgByAIQQJ0IgJqIAAgAmpBrNABaigCADYCVCAIQQFqIQgMAQsLIAcgETYCZCAHIA82AmAgByABIA9rNgJoQWwhECAHQShqIAMgBBAGEAMNASAFQQQgBUEESBshFyAHQTxqIAdBKGogACgCABATIAdBxABqIAdBKGogACgCCBATIAdBzABqIAdBKGogACgCBBATQQAhBCAHQeAAaiEMIAdB5ABqIQoDQCAHQShqEARBAksgBCAXTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEJIAcoAkggBygCREEDdGopAgAiH0IgiKchCCAeQiCIISAgHUIgiKchAgJAIB9CEIinQf8BcSIDQQJPBEACQCAGRSADQRlJckUEQCAIIAdBKGogA0EgIAcoAixrIg0gDSADSxsiDRAFIAMgDWsiA3RqIQggB0EoahAEGiADRQ0BIAdBKGogAxAFIAhqIQgMAQsgB0EoaiADEAUgCGohCCAHQShqEAQaCyAHKQJUISEgByAINgJUIAcgITcDWAwBCwJAIANFBEAgAgRAIAcoAlQhCAwDCyAHKAJYIQgMAQsCQAJAIAdBKGpBARAFIAggAkVqaiIDQQNGBEAgBygCVEF/aiIDIANFaiEIDAELIANBAnQgB2ooAlQiCCAIRWohCCADQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAg2AlQLICCnIQMgCQRAIAdBKGogCRAFIANqIQMLIAkgC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgAmohAgsgB0EoahAEGiAHIAcoAmggAmoiCSADajYCaCAKIAwgCCAJSxsoAgAhDSAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogB0EoaiAfQhiIp0H/AXEQCCEOIAdB8ABqIARBBHRqIgsgCSANaiAIazYCDCALIAg2AgggCyADNgIEIAsgAjYCACAHIA4gH6dB//8DcWo2AkQgBEEBaiEEDAELCyAEIBdIDQEgEkFgaiEYIAdB4ABqIRogB0HkAGohGyABIQMDQCAHQShqEARBAksgBCAFTnJFBEAgBygCQCAHKAI8QQN0aikCACIdQhCIp0H/AXEhCyAHKAJQIAcoAkxBA3RqKQIAIh5CEIinQf8BcSEIIAcoAkggBygCREEDdGopAgAiH0IgiKchCSAeQiCIISAgHUIgiKchDAJAIB9CEIinQf8BcSICQQJPBEACQCAGRSACQRlJckUEQCAJIAdBKGogAkEgIAcoAixrIgogCiACSxsiChAFIAIgCmsiAnRqIQkgB0EoahAEGiACRQ0BIAdBKGogAhAFIAlqIQkMAQsgB0EoaiACEAUgCWohCSAHQShqEAQaCyAHKQJUISEgByAJNgJUIAcgITcDWAwBCwJAIAJFBEAgDARAIAcoAlQhCQwDCyAHKAJYIQkMAQsCQAJAIAdBKGpBARAFIAkgDEVqaiICQQNGBEAgBygCVEF/aiICIAJFaiEJDAELIAJBAnQgB2ooAlQiCSAJRWohCSACQQFGDQELIAcgBygCWDYCXAsLIAcgBygCVDYCWCAHIAk2AlQLICCnIRQgCARAIAdBKGogCBAFIBRqIRQLIAggC2pBFE8EQCAHQShqEAQaCyALBEAgB0EoaiALEAUgDGohDAsgB0EoahAEGiAHIAcoAmggDGoiGSAUajYCaCAbIBogCSAZSxsoAgAhHCAHIAdBKGogHUIYiKdB/wFxEAggHadB//8DcWo2AjwgByAHQShqIB5CGIinQf8BcRAIIB6nQf//A3FqNgJMIAdBKGoQBBogByAHQShqIB9CGIinQf8BcRAIIB+nQf//A3FqNgJEIAcgB0HwAGogBEEDcUEEdGoiDSkDCCIdNwPIASAHIA0pAwAiHjcDwAECQAJAAkAgBygCvAEiDiAepyICaiIWIBNLDQAgAyAHKALEASIKIAJqIgtqIBhLDQAgEiADayALQSBqTw0BCyAHIAcpA8gBNwMQIAcgBykDwAE3AwggAyASIAdBCGogB0G8AWogEyAPIBUgERAeIQsMAQsgAiADaiEIIAMgDhAHIAJBEU8EQCADQRBqIQIDQCACIA5BEGoiDhAHIAJBEGoiAiAISQ0ACwsgCCAdpyIOayECIAcgFjYCvAEgDiAIIA9rSwRAIA4gCCAVa0sEQEFsIQsMAgsgESACIA9rIgJqIhYgCmogEU0EQCAIIBYgChAPGgwCCyAIIBZBACACaxAPIQggByACIApqIgo2AsQBIAggAmshCCAPIQILIA5BEE8EQCAIIApqIQoDQCAIIAIQByACQRBqIQIgCEEQaiIIIApJDQALDAELAkAgDkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgDkECdCIKQcAeaigCAGoiAhAXIAIgCkHgHmooAgBrIQIgBygCxAEhCgwBCyAIIAIQDAsgCkEJSQ0AIAggCmohCiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAKSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAKSQ0ACwsgCxADBEAgCyEQDAQFIA0gDDYCACANIBkgHGogCWs2AgwgDSAJNgIIIA0gFDYCBCAEQQFqIQQgAyALaiEDDAILAAsLIAQgBUgNASAEIBdrIQtBACEEA0AgCyAFSARAIAcgB0HwAGogC0EDcUEEdGoiAikDCCIdNwPIASAHIAIpAwAiHjcDwAECQAJAAkAgBygCvAEiDCAepyICaiIKIBNLDQAgAyAHKALEASIJIAJqIhBqIBhLDQAgEiADayAQQSBqTw0BCyAHIAcpA8gBNwMgIAcgBykDwAE3AxggAyASIAdBGGogB0G8AWogEyAPIBUgERAeIRAMAQsgAiADaiEIIAMgDBAHIAJBEU8EQCADQRBqIQIDQCACIAxBEGoiDBAHIAJBEGoiAiAISQ0ACwsgCCAdpyIGayECIAcgCjYCvAEgBiAIIA9rSwRAIAYgCCAVa0sEQEFsIRAMAgsgESACIA9rIgJqIgwgCWogEU0EQCAIIAwgCRAPGgwCCyAIIAxBACACaxAPIQggByACIAlqIgk2AsQBIAggAmshCCAPIQILIAZBEE8EQCAIIAlqIQYDQCAIIAIQByACQRBqIQIgCEEQaiIIIAZJDQALDAELAkAgBkEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgBkECdCIGQcAeaigCAGoiAhAXIAIgBkHgHmooAgBrIQIgBygCxAEhCQwBCyAIIAIQDAsgCUEJSQ0AIAggCWohBiAIQQhqIgggAkEIaiICa0EPTARAA0AgCCACEAwgAkEIaiECIAhBCGoiCCAGSQ0ADAIACwALA0AgCCACEAcgAkEQaiECIAhBEGoiCCAGSQ0ACwsgEBADDQMgC0EBaiELIAMgEGohAwwBCwsDQCAEQQNHBEAgACAEQQJ0IgJqQazQAWogAiAHaigCVDYCACAEQQFqIQQMAQsLIAcoArwBIQgLQbp/IRAgEyAIayIAIBIgA2tLDQAgAwR/IAMgCCAAEAsgAGoFQQALIAFrIRALIAdB0AFqJAAgEAslACAAQgA3AgAgAEEAOwEIIABBADoACyAAIAE2AgwgACACOgAKC7QFAQN/IwBBMGsiBCQAIABB/wFqIgVBfWohBgJAIAMvAQIEQCAEQRhqIAEgAhAGIgIQAw0BIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahASOgAAIAMgBEEIaiAEQRhqEBI6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0FIAEgBEEQaiAEQRhqEBI6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBSABIARBCGogBEEYahASOgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEjoAACABIAJqIABrIQIMAwsgAyAEQRBqIARBGGoQEjoAAiADIARBCGogBEEYahASOgADIANBBGohAwwAAAsACyAEQRhqIAEgAhAGIgIQAw0AIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahAROgAAIAMgBEEIaiAEQRhqEBE6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0EIAEgBEEQaiAEQRhqEBE6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBCABIARBCGogBEEYahAROgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEToAACABIAJqIABrIQIMAgsgAyAEQRBqIARBGGoQEToAAiADIARBCGogBEEYahAROgADIANBBGohAwwAAAsACyAEQTBqJAAgAgtpAQF/An8CQAJAIAJBB00NACABKAAAQbfIwuF+Rw0AIAAgASgABDYCmOIBQWIgAEEQaiABIAIQPiIDEAMNAhogAEKBgICAEDcDiOEBIAAgASADaiACIANrECoMAQsgACABIAIQKgtBAAsLrQMBBn8jAEGAAWsiAyQAQWIhCAJAIAJBCUkNACAAQZjQAGogAUEIaiIEIAJBeGogAEGY0AAQMyIFEAMiBg0AIANBHzYCfCADIANB/ABqIANB+ABqIAQgBCAFaiAGGyIEIAEgAmoiAiAEaxAVIgUQAw0AIAMoAnwiBkEfSw0AIAMoAngiB0EJTw0AIABBiCBqIAMgBkGAC0GADCAHEBggA0E0NgJ8IAMgA0H8AGogA0H4AGogBCAFaiIEIAIgBGsQFSIFEAMNACADKAJ8IgZBNEsNACADKAJ4IgdBCk8NACAAQZAwaiADIAZBgA1B4A4gBxAYIANBIzYCfCADIANB/ABqIANB+ABqIAQgBWoiBCACIARrEBUiBRADDQAgAygCfCIGQSNLDQAgAygCeCIHQQpPDQAgACADIAZBwBBB0BEgBxAYIAQgBWoiBEEMaiIFIAJLDQAgAiAFayEFQQAhAgNAIAJBA0cEQCAEKAAAIgZBf2ogBU8NAiAAIAJBAnRqQZzQAWogBjYCACACQQFqIQIgBEEEaiEEDAELCyAEIAFrIQgLIANBgAFqJAAgCAtGAQN/IABBCGohAyAAKAIEIQJBACEAA0AgACACdkUEQCABIAMgAEEDdGotAAJBFktqIQEgAEEBaiEADAELCyABQQggAmt0C4YDAQV/Qbh/IQcCQCADRQ0AIAItAAAiBEUEQCABQQA2AgBBAUG4fyADQQFGGw8LAn8gAkEBaiIFIARBGHRBGHUiBkF/Sg0AGiAGQX9GBEAgA0EDSA0CIAUvAABBgP4BaiEEIAJBA2oMAQsgA0ECSA0BIAItAAEgBEEIdHJBgIB+aiEEIAJBAmoLIQUgASAENgIAIAVBAWoiASACIANqIgNLDQBBbCEHIABBEGogACAFLQAAIgVBBnZBI0EJIAEgAyABa0HAEEHQEUHwEiAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBmCBqIABBCGogBUEEdkEDcUEfQQggASABIAZqIAgbIgEgAyABa0GAC0GADEGAFyAAKAKM4QEgACgCnOIBIAQQHyIGEAMiCA0AIABBoDBqIABBBGogBUECdkEDcUE0QQkgASABIAZqIAgbIgEgAyABa0GADUHgDkGQGSAAKAKM4QEgACgCnOIBIAQQHyIAEAMNACAAIAFqIAJrIQcLIAcLrQMBCn8jAEGABGsiCCQAAn9BUiACQf8BSw0AGkFUIANBDEsNABogAkEBaiELIABBBGohCUGAgAQgA0F/anRBEHUhCkEAIQJBASEEQQEgA3QiB0F/aiIMIQUDQCACIAtGRQRAAkAgASACQQF0Ig1qLwEAIgZB//8DRgRAIAkgBUECdGogAjoAAiAFQX9qIQVBASEGDAELIARBACAKIAZBEHRBEHVKGyEECyAIIA1qIAY7AQAgAkEBaiECDAELCyAAIAQ7AQIgACADOwEAIAdBA3YgB0EBdmpBA2ohBkEAIQRBACECA0AgBCALRkUEQCABIARBAXRqLgEAIQpBACEAA0AgACAKTkUEQCAJIAJBAnRqIAQ6AAIDQCACIAZqIAxxIgIgBUsNAAsgAEEBaiEADAELCyAEQQFqIQQMAQsLQX8gAg0AGkEAIQIDfyACIAdGBH9BAAUgCCAJIAJBAnRqIgAtAAJBAXRqIgEgAS8BACIBQQFqOwEAIAAgAyABEBRrIgU6AAMgACABIAVB/wFxdCAHazsBACACQQFqIQIMAQsLCyEFIAhBgARqJAAgBQvjBgEIf0FsIQcCQCACQQNJDQACQAJAAkACQCABLQAAIgNBA3EiCUEBaw4DAwEAAgsgACgCiOEBDQBBYg8LIAJBBUkNAkEDIQYgASgAACEFAn8CQAJAIANBAnZBA3EiCEF+aiIEQQFNBEAgBEEBaw0BDAILIAVBDnZB/wdxIQQgBUEEdkH/B3EhAyAIRQwCCyAFQRJ2IQRBBCEGIAVBBHZB//8AcSEDQQAMAQsgBUEEdkH//w9xIgNBgIAISw0DIAEtAARBCnQgBUEWdnIhBEEFIQZBAAshBSAEIAZqIgogAksNAgJAIANBgQZJDQAgACgCnOIBRQ0AQQAhAgNAIAJBg4ABSw0BIAJBQGshAgwAAAsACwJ/IAlBA0YEQCABIAZqIQEgAEHw4gFqIQIgACgCDCEGIAUEQCACIAMgASAEIAYQXwwCCyACIAMgASAEIAYQXQwBCyAAQbjQAWohAiABIAZqIQEgAEHw4gFqIQYgAEGo0ABqIQggBQRAIAggBiADIAEgBCACEF4MAQsgCCAGIAMgASAEIAIQXAsQAw0CIAAgAzYCgOIBIABBATYCiOEBIAAgAEHw4gFqNgLw4QEgCUECRgRAIAAgAEGo0ABqNgIMCyAAIANqIgBBiOMBakIANwAAIABBgOMBakIANwAAIABB+OIBakIANwAAIABB8OIBakIANwAAIAoPCwJ/AkACQAJAIANBAnZBA3FBf2oiBEECSw0AIARBAWsOAgACAQtBASEEIANBA3YMAgtBAiEEIAEvAABBBHYMAQtBAyEEIAEQIUEEdgsiAyAEaiIFQSBqIAJLBEAgBSACSw0CIABB8OIBaiABIARqIAMQCyEBIAAgAzYCgOIBIAAgATYC8OEBIAEgA2oiAEIANwAYIABCADcAECAAQgA3AAggAEIANwAAIAUPCyAAIAM2AoDiASAAIAEgBGo2AvDhASAFDwsCfwJAAkACQCADQQJ2QQNxQX9qIgRBAksNACAEQQFrDgIAAgELQQEhByADQQN2DAILQQIhByABLwAAQQR2DAELIAJBBEkgARAhIgJBj4CAAUtyDQFBAyEHIAJBBHYLIQIgAEHw4gFqIAEgB2otAAAgAkEgahAQIQEgACACNgKA4gEgACABNgLw4QEgB0EBaiEHCyAHC0sAIABC+erQ0OfJoeThADcDICAAQgA3AxggAELP1tO+0ser2UI3AxAgAELW64Lu6v2J9eAANwMIIABCADcDACAAQShqQQBBKBAQGgviAgICfwV+IABBKGoiASAAKAJIaiECAn4gACkDACIDQiBaBEAgACkDECIEQgeJIAApAwgiBUIBiXwgACkDGCIGQgyJfCAAKQMgIgdCEol8IAUQGSAEEBkgBhAZIAcQGQwBCyAAKQMYQsXP2bLx5brqJ3wLIAN8IQMDQCABQQhqIgAgAk0EQEIAIAEpAAAQCSADhUIbiUKHla+vmLbem55/fkLj3MqV/M7y9YV/fCEDIAAhAQwBCwsCQCABQQRqIgAgAksEQCABIQAMAQsgASgAAK1Ch5Wvr5i23puef34gA4VCF4lCz9bTvtLHq9lCfkL5893xmfaZqxZ8IQMLA0AgACACSQRAIAAxAABCxc/ZsvHluuonfiADhUILiUKHla+vmLbem55/fiEDIABBAWohAAwBCwsgA0IhiCADhULP1tO+0ser2UJ+IgNCHYggA4VC+fPd8Zn2masWfiIDQiCIIAOFC+8CAgJ/BH4gACAAKQMAIAKtfDcDAAJAAkAgACgCSCIDIAJqIgRBH00EQCABRQ0BIAAgA2pBKGogASACECAgACgCSCACaiEEDAELIAEgAmohAgJ/IAMEQCAAQShqIgQgA2ogAUEgIANrECAgACAAKQMIIAQpAAAQCTcDCCAAIAApAxAgACkAMBAJNwMQIAAgACkDGCAAKQA4EAk3AxggACAAKQMgIABBQGspAAAQCTcDICAAKAJIIQMgAEEANgJIIAEgA2tBIGohAQsgAUEgaiACTQsEQCACQWBqIQMgACkDICEFIAApAxghBiAAKQMQIQcgACkDCCEIA0AgCCABKQAAEAkhCCAHIAEpAAgQCSEHIAYgASkAEBAJIQYgBSABKQAYEAkhBSABQSBqIgEgA00NAAsgACAFNwMgIAAgBjcDGCAAIAc3AxAgACAINwMICyABIAJPDQEgAEEoaiABIAIgAWsiBBAgCyAAIAQ2AkgLCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQEBogAwVBun8LCy8BAX8gAEUEQEG2f0EAIAMbDwtBun8hBCADIAFNBH8gACACIAMQCxogAwVBun8LC6gCAQZ/IwBBEGsiByQAIABB2OABaikDAEKAgIAQViEIQbh/IQUCQCAEQf//B0sNACAAIAMgBBBCIgUQAyIGDQAgACgCnOIBIQkgACAHQQxqIAMgAyAFaiAGGyIKIARBACAFIAYbayIGEEAiAxADBEAgAyEFDAELIAcoAgwhBCABRQRAQbp/IQUgBEEASg0BCyAGIANrIQUgAyAKaiEDAkAgCQRAIABBADYCnOIBDAELAkACQAJAIARBBUgNACAAQdjgAWopAwBCgICACFgNAAwBCyAAQQA2ApziAQwBCyAAKAIIED8hBiAAQQA2ApziASAGQRRPDQELIAAgASACIAMgBSAEIAgQOSEFDAELIAAgASACIAMgBSAEIAgQOiEFCyAHQRBqJAAgBQtnACAAQdDgAWogASACIAAoAuzhARAuIgEQAwRAIAEPC0G4fyECAkAgAQ0AIABB7OABaigCACIBBEBBYCECIAAoApjiASABRw0BC0EAIQIgAEHw4AFqKAIARQ0AIABBkOEBahBDCyACCycBAX8QVyIERQRAQUAPCyAEIAAgASACIAMgBBBLEE8hACAEEFYgAAs/AQF/AkACQAJAIAAoAqDiAUEBaiIBQQJLDQAgAUEBaw4CAAECCyAAEDBBAA8LIABBADYCoOIBCyAAKAKU4gELvAMCB38BfiMAQRBrIgkkAEG4fyEGAkAgBCgCACIIQQVBCSAAKALs4QEiBRtJDQAgAygCACIHQQFBBSAFGyAFEC8iBRADBEAgBSEGDAELIAggBUEDakkNACAAIAcgBRBJIgYQAw0AIAEgAmohCiAAQZDhAWohCyAIIAVrIQIgBSAHaiEHIAEhBQNAIAcgAiAJECwiBhADDQEgAkF9aiICIAZJBEBBuH8hBgwCCyAJKAIAIghBAksEQEFsIQYMAgsgB0EDaiEHAn8CQAJAAkAgCEEBaw4CAgABCyAAIAUgCiAFayAHIAYQSAwCCyAFIAogBWsgByAGEEcMAQsgBSAKIAVrIActAAAgCSgCCBBGCyIIEAMEQCAIIQYMAgsgACgC8OABBEAgCyAFIAgQRQsgAiAGayECIAYgB2ohByAFIAhqIQUgCSgCBEUNAAsgACkD0OABIgxCf1IEQEFsIQYgDCAFIAFrrFINAQsgACgC8OABBEBBaiEGIAJBBEkNASALEEQhDCAHKAAAIAynRw0BIAdBBGohByACQXxqIQILIAMgBzYCACAEIAI2AgAgBSABayEGCyAJQRBqJAAgBgsuACAAECsCf0EAQQAQAw0AGiABRSACRXJFBEBBYiAAIAEgAhA9EAMNARoLQQALCzcAIAEEQCAAIAAoAsTgASABKAIEIAEoAghqRzYCnOIBCyAAECtBABADIAFFckUEQCAAIAEQWwsL0QIBB38jAEEQayIGJAAgBiAENgIIIAYgAzYCDCAFBEAgBSgCBCEKIAUoAgghCQsgASEIAkACQANAIAAoAuzhARAWIQsCQANAIAQgC0kNASADKAAAQXBxQdDUtMIBRgRAIAMgBBAiIgcQAw0EIAQgB2shBCADIAdqIQMMAQsLIAYgAzYCDCAGIAQ2AggCQCAFBEAgACAFEE5BACEHQQAQA0UNAQwFCyAAIAogCRBNIgcQAw0ECyAAIAgQUCAMQQFHQQAgACAIIAIgBkEMaiAGQQhqEEwiByIDa0EAIAMQAxtBCkdyRQRAQbh/IQcMBAsgBxADDQMgAiAHayECIAcgCGohCEEBIQwgBigCDCEDIAYoAgghBAwBCwsgBiADNgIMIAYgBDYCCEG4fyEHIAQNASAIIAFrIQcMAQsgBiADNgIMIAYgBDYCCAsgBkEQaiQAIAcLRgECfyABIAAoArjgASICRwRAIAAgAjYCxOABIAAgATYCuOABIAAoArzgASEDIAAgATYCvOABIAAgASADIAJrajYCwOABCwutAgIEfwF+IwBBQGoiBCQAAkACQCACQQhJDQAgASgAAEFwcUHQ1LTCAUcNACABIAIQIiEBIABCADcDCCAAQQA2AgQgACABNgIADAELIARBGGogASACEC0iAxADBEAgACADEBoMAQsgAwRAIABBuH8QGgwBCyACIAQoAjAiA2shAiABIANqIQMDQAJAIAAgAyACIARBCGoQLCIFEAMEfyAFBSACIAVBA2oiBU8NAUG4fwsQGgwCCyAGQQFqIQYgAiAFayECIAMgBWohAyAEKAIMRQ0ACyAEKAI4BEAgAkEDTQRAIABBuH8QGgwCCyADQQRqIQMLIAQoAighAiAEKQMYIQcgAEEANgIEIAAgAyABazYCACAAIAIgBmytIAcgB0J/URs3AwgLIARBQGskAAslAQF/IwBBEGsiAiQAIAIgACABEFEgAigCACEAIAJBEGokACAAC30BBH8jAEGQBGsiBCQAIARB/wE2AggCQCAEQRBqIARBCGogBEEMaiABIAIQFSIGEAMEQCAGIQUMAQtBVCEFIAQoAgwiB0EGSw0AIAMgBEEQaiAEKAIIIAcQQSIFEAMNACAAIAEgBmogAiAGayADEDwhBQsgBEGQBGokACAFC4cBAgJ/An5BABAWIQMCQANAIAEgA08EQAJAIAAoAABBcHFB0NS0wgFGBEAgACABECIiAhADRQ0BQn4PCyAAIAEQVSIEQn1WDQMgBCAFfCIFIARUIQJCfiEEIAINAyAAIAEQUiICEAMNAwsgASACayEBIAAgAmohAAwBCwtCfiAFIAEbIQQLIAQLPwIBfwF+IwBBMGsiAiQAAn5CfiACQQhqIAAgARAtDQAaQgAgAigCHEEBRg0AGiACKQMICyEDIAJBMGokACADC40BAQJ/IwBBMGsiASQAAkAgAEUNACAAKAKI4gENACABIABB/OEBaigCADYCKCABIAApAvThATcDICAAEDAgACgCqOIBIQIgASABKAIoNgIYIAEgASkDIDcDECACIAFBEGoQGyAAQQA2AqjiASABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALKgECfyMAQRBrIgAkACAAQQA2AgggAEIANwMAIAAQWCEBIABBEGokACABC4cBAQN/IwBBEGsiAiQAAkAgACgCAEUgACgCBEVzDQAgAiAAKAIINgIIIAIgACkCADcDAAJ/IAIoAgAiAQRAIAIoAghBqOMJIAERBQAMAQtBqOMJECgLIgFFDQAgASAAKQIANwL04QEgAUH84QFqIAAoAgg2AgAgARBZIAEhAwsgAkEQaiQAIAMLywEBAn8jAEEgayIBJAAgAEGBgIDAADYCtOIBIABBADYCiOIBIABBADYC7OEBIABCADcDkOIBIABBADYCpOMJIABBADYC3OIBIABCADcCzOIBIABBADYCvOIBIABBADYCxOABIABCADcCnOIBIABBpOIBakIANwIAIABBrOIBakEANgIAIAFCADcCECABQgA3AhggASABKQMYNwMIIAEgASkDEDcDACABKAIIQQh2QQFxIQIgAEEANgLg4gEgACACNgKM4gEgAUEgaiQAC3YBA38jAEEwayIBJAAgAARAIAEgAEHE0AFqIgIoAgA2AiggASAAKQK80AE3AyAgACgCACEDIAEgAigCADYCGCABIAApArzQATcDECADIAFBEGoQGyABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALzAEBAX8gACABKAK00AE2ApjiASAAIAEoAgQiAjYCwOABIAAgAjYCvOABIAAgAiABKAIIaiICNgK44AEgACACNgLE4AEgASgCuNABBEAgAEKBgICAEDcDiOEBIAAgAUGk0ABqNgIMIAAgAUGUIGo2AgggACABQZwwajYCBCAAIAFBDGo2AgAgAEGs0AFqIAFBqNABaigCADYCACAAQbDQAWogAUGs0AFqKAIANgIAIABBtNABaiABQbDQAWooAgA2AgAPCyAAQgA3A4jhAQs7ACACRQRAQbp/DwsgBEUEQEFsDwsgAiAEEGAEQCAAIAEgAiADIAQgBRBhDwsgACABIAIgAyAEIAUQZQtGAQF/IwBBEGsiBSQAIAVBCGogBBAOAn8gBS0ACQRAIAAgASACIAMgBBAyDAELIAAgASACIAMgBBA0CyEAIAVBEGokACAACzQAIAAgAyAEIAUQNiIFEAMEQCAFDwsgBSAESQR/IAEgAiADIAVqIAQgBWsgABA1BUG4fwsLRgEBfyMAQRBrIgUkACAFQQhqIAQQDgJ/IAUtAAkEQCAAIAEgAiADIAQQYgwBCyAAIAEgAiADIAQQNQshACAFQRBqJAAgAAtZAQF/QQ8hAiABIABJBEAgAUEEdCAAbiECCyAAQQh2IgEgAkEYbCIAQYwIaigCAGwgAEGICGooAgBqIgJBA3YgAmogAEGACGooAgAgAEGECGooAgAgAWxqSQs3ACAAIAMgBCAFQYAQEDMiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQMgVBuH8LC78DAQN/IwBBIGsiBSQAIAVBCGogAiADEAYiAhADRQRAIAAgAWoiB0F9aiEGIAUgBBAOIARBBGohAiAFLQACIQMDQEEAIAAgBkkgBUEIahAEGwRAIAAgAiAFQQhqIAMQAkECdGoiBC8BADsAACAFQQhqIAQtAAIQASAAIAQtAANqIgQgAiAFQQhqIAMQAkECdGoiAC8BADsAACAFQQhqIAAtAAIQASAEIAAtAANqIQAMAQUgB0F+aiEEA0AgBUEIahAEIAAgBEtyRQRAIAAgAiAFQQhqIAMQAkECdGoiBi8BADsAACAFQQhqIAYtAAIQASAAIAYtAANqIQAMAQsLA0AgACAES0UEQCAAIAIgBUEIaiADEAJBAnRqIgYvAQA7AAAgBUEIaiAGLQACEAEgACAGLQADaiEADAELCwJAIAAgB08NACAAIAIgBUEIaiADEAIiA0ECdGoiAC0AADoAACAALQADQQFGBEAgBUEIaiAALQACEAEMAQsgBSgCDEEfSw0AIAVBCGogAiADQQJ0ai0AAhABIAUoAgxBIUkNACAFQSA2AgwLIAFBbCAFQQhqEAobIQILCwsgBUEgaiQAIAILkgIBBH8jAEFAaiIJJAAgCSADQTQQCyEDAkAgBEECSA0AIAMgBEECdGooAgAhCSADQTxqIAgQIyADQQE6AD8gAyACOgA+QQAhBCADKAI8IQoDQCAEIAlGDQEgACAEQQJ0aiAKNgEAIARBAWohBAwAAAsAC0EAIQkDQCAGIAlGRQRAIAMgBSAJQQF0aiIKLQABIgtBAnRqIgwoAgAhBCADQTxqIAotAABBCHQgCGpB//8DcRAjIANBAjoAPyADIAcgC2siCiACajoAPiAEQQEgASAKa3RqIQogAygCPCELA0AgACAEQQJ0aiALNgEAIARBAWoiBCAKSQ0ACyAMIAo2AgAgCUEBaiEJDAELCyADQUBrJAALowIBCX8jAEHQAGsiCSQAIAlBEGogBUE0EAsaIAcgBmshDyAHIAFrIRADQAJAIAMgCkcEQEEBIAEgByACIApBAXRqIgYtAAEiDGsiCGsiC3QhDSAGLQAAIQ4gCUEQaiAMQQJ0aiIMKAIAIQYgCyAPTwRAIAAgBkECdGogCyAIIAUgCEE0bGogCCAQaiIIQQEgCEEBShsiCCACIAQgCEECdGooAgAiCEEBdGogAyAIayAHIA4QYyAGIA1qIQgMAgsgCUEMaiAOECMgCUEBOgAPIAkgCDoADiAGIA1qIQggCSgCDCELA0AgBiAITw0CIAAgBkECdGogCzYBACAGQQFqIQYMAAALAAsgCUHQAGokAA8LIAwgCDYCACAKQQFqIQoMAAALAAs0ACAAIAMgBCAFEDYiBRADBEAgBQ8LIAUgBEkEfyABIAIgAyAFaiAEIAVrIAAQNAVBuH8LCyMAIAA/AEEQdGtB//8DakEQdkAAQX9GBEBBAA8LQQAQAEEBCzsBAX8gAgRAA0AgACABIAJBgCAgAkGAIEkbIgMQCyEAIAFBgCBqIQEgAEGAIGohACACIANrIgINAAsLCwYAIAAQAwsLqBUJAEGICAsNAQAAAAEAAAACAAAAAgBBoAgLswYBAAAAAQAAAAIAAAACAAAAJgAAAIIAAAAhBQAASgAAAGcIAAAmAAAAwAEAAIAAAABJBQAASgAAAL4IAAApAAAALAIAAIAAAABJBQAASgAAAL4IAAAvAAAAygIAAIAAAACKBQAASgAAAIQJAAA1AAAAcwMAAIAAAACdBQAASgAAAKAJAAA9AAAAgQMAAIAAAADrBQAASwAAAD4KAABEAAAAngMAAIAAAABNBgAASwAAAKoKAABLAAAAswMAAIAAAADBBgAATQAAAB8NAABNAAAAUwQAAIAAAAAjCAAAUQAAAKYPAABUAAAAmQQAAIAAAABLCQAAVwAAALESAABYAAAA2gQAAIAAAABvCQAAXQAAACMUAABUAAAARQUAAIAAAABUCgAAagAAAIwUAABqAAAArwUAAIAAAAB2CQAAfAAAAE4QAAB8AAAA0gIAAIAAAABjBwAAkQAAAJAHAACSAAAAAAAAAAEAAAABAAAABQAAAA0AAAAdAAAAPQAAAH0AAAD9AAAA/QEAAP0DAAD9BwAA/Q8AAP0fAAD9PwAA/X8AAP3/AAD9/wEA/f8DAP3/BwD9/w8A/f8fAP3/PwD9/38A/f//AP3//wH9//8D/f//B/3//w/9//8f/f//P/3//38AAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAeAAAAHwAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACUAAAAnAAAAKQAAACsAAAAvAAAAMwAAADsAAABDAAAAUwAAAGMAAACDAAAAAwEAAAMCAAADBAAAAwgAAAMQAAADIAAAA0AAAAOAAAADAAEAQeAPC1EBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAEAAAABQAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0AAAAOAAAADwAAABAAQcQQC4sBAQAAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAABIAAAAUAAAAFgAAABgAAAAcAAAAIAAAACgAAAAwAAAAQAAAAIAAAAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAQAAAAIAAAAAAAQBBkBIL5gQBAAAAAQAAAAEAAAABAAAAAgAAAAIAAAADAAAAAwAAAAQAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAAEAAAAAEAAAAEAAAACAAAAAAAAAABAAEBBgAAAAAAAAQAAAAAEAAABAAAAAAgAAAFAQAAAAAAAAUDAAAAAAAABQQAAAAAAAAFBgAAAAAAAAUHAAAAAAAABQkAAAAAAAAFCgAAAAAAAAUMAAAAAAAABg4AAAAAAAEFEAAAAAAAAQUUAAAAAAABBRYAAAAAAAIFHAAAAAAAAwUgAAAAAAAEBTAAAAAgAAYFQAAAAAAABwWAAAAAAAAIBgABAAAAAAoGAAQAAAAADAYAEAAAIAAABAAAAAAAAAAEAQAAAAAAAAUCAAAAIAAABQQAAAAAAAAFBQAAACAAAAUHAAAAAAAABQgAAAAgAAAFCgAAAAAAAAULAAAAAAAABg0AAAAgAAEFEAAAAAAAAQUSAAAAIAABBRYAAAAAAAIFGAAAACAAAwUgAAAAAAADBSgAAAAAAAYEQAAAABAABgRAAAAAIAAHBYAAAAAAAAkGAAIAAAAACwYACAAAMAAABAAAAAAQAAAEAQAAACAAAAUCAAAAIAAABQMAAAAgAAAFBQAAACAAAAUGAAAAIAAABQgAAAAgAAAFCQAAACAAAAULAAAAIAAABQwAAAAAAAAGDwAAACAAAQUSAAAAIAABBRQAAAAgAAIFGAAAACAAAgUcAAAAIAADBSgAAAAgAAQFMAAAAAAAEAYAAAEAAAAPBgCAAAAAAA4GAEAAAAAADQYAIABBgBcLhwIBAAEBBQAAAAAAAAUAAAAAAAAGBD0AAAAAAAkF/QEAAAAADwX9fwAAAAAVBf3/HwAAAAMFBQAAAAAABwR9AAAAAAAMBf0PAAAAABIF/f8DAAAAFwX9/38AAAAFBR0AAAAAAAgE/QAAAAAADgX9PwAAAAAUBf3/DwAAAAIFAQAAABAABwR9AAAAAAALBf0HAAAAABEF/f8BAAAAFgX9/z8AAAAEBQ0AAAAQAAgE/QAAAAAADQX9HwAAAAATBf3/BwAAAAEFAQAAABAABgQ9AAAAAAAKBf0DAAAAABAF/f8AAAAAHAX9//8PAAAbBf3//wcAABoF/f//AwAAGQX9//8BAAAYBf3//wBBkBkLhgQBAAEBBgAAAAAAAAYDAAAAAAAABAQAAAAgAAAFBQAAAAAAAAUGAAAAAAAABQgAAAAAAAAFCQAAAAAAAAULAAAAAAAABg0AAAAAAAAGEAAAAAAAAAYTAAAAAAAABhYAAAAAAAAGGQAAAAAAAAYcAAAAAAAABh8AAAAAAAAGIgAAAAAAAQYlAAAAAAABBikAAAAAAAIGLwAAAAAAAwY7AAAAAAAEBlMAAAAAAAcGgwAAAAAACQYDAgAAEAAABAQAAAAAAAAEBQAAACAAAAUGAAAAAAAABQcAAAAgAAAFCQAAAAAAAAUKAAAAAAAABgwAAAAAAAAGDwAAAAAAAAYSAAAAAAAABhUAAAAAAAAGGAAAAAAAAAYbAAAAAAAABh4AAAAAAAAGIQAAAAAAAQYjAAAAAAABBicAAAAAAAIGKwAAAAAAAwYzAAAAAAAEBkMAAAAAAAUGYwAAAAAACAYDAQAAIAAABAQAAAAwAAAEBAAAABAAAAQFAAAAIAAABQcAAAAgAAAFCAAAACAAAAUKAAAAIAAABQsAAAAAAAAGDgAAAAAAAAYRAAAAAAAABhQAAAAAAAAGFwAAAAAAAAYaAAAAAAAABh0AAAAAAAAGIAAAAAAAEAYDAAEAAAAPBgOAAAAAAA4GA0AAAAAADQYDIAAAAAAMBgMQAAAAAAsGAwgAAAAACgYDBABBpB0L2QEBAAAAAwAAAAcAAAAPAAAAHwAAAD8AAAB/AAAA/wAAAP8BAAD/AwAA/wcAAP8PAAD/HwAA/z8AAP9/AAD//wAA//8BAP//AwD//wcA//8PAP//HwD//z8A//9/AP///wD///8B////A////wf///8P////H////z////9/AAAAAAEAAAACAAAABAAAAAAAAAACAAAABAAAAAgAAAAAAAAAAQAAAAIAAAABAAAABAAAAAQAAAAEAAAABAAAAAgAAAAIAAAACAAAAAcAAAAIAAAACQAAAAoAAAALAEGgIAsDwBBQ"
vendor: 18,012 bytes, lines 35812-36220
35812;
35813
35814	const DisplayP3ColorSpace = 'display-p3';
35815	const LinearDisplayP3ColorSpace = 'display-p3-linear';
35816
35817	const _taskCache = new WeakMap();
35818	let _activeLoaders = 0;
35819	let _zstd;
35820	class KTX2Loader extends Loader {
35821	    setTranscoderPath(path) {
35822	        this.transcoderPath = path;
35823	        return this;
35824	    }
35825	    setWorkerLimit(num) {
35826	        this.workerPool.setWorkerLimit(num);
35827	        return this;
35828	    }
35829	    async detectSupportAsync(renderer) {
35830	        this.workerConfig = {
35831	            astcSupported: await renderer.hasFeatureAsync('texture-compression-astc'),
35832	            astcHDRSupported: false,
35833	            etc1Supported: await renderer.hasFeatureAsync('texture-compression-etc1'),
35834	            etc2Supported: await renderer.hasFeatureAsync('texture-compression-etc2'),
35835	            dxtSupported: await renderer.hasFeatureAsync('texture-compression-bc'),
35836	            bptcSupported: await renderer.hasFeatureAsync('texture-compression-bptc'),
35837	            pvrtcSupported: await renderer.hasFeatureAsync('texture-compression-pvrtc')
35838	        };
35839	        return this;
35840	    }
35841	    detectSupport(renderer) {
35842	        if (renderer.isWebGPURenderer === true) {
35843	            this.workerConfig = {
35844	                astcSupported: renderer.hasFeature('texture-compression-astc'),
35845	                astcHDRSupported: false,
35846	                etc1Supported: renderer.hasFeature('texture-compression-etc1'),
35847	                etc2Supported: renderer.hasFeature('texture-compression-etc2'),
35848	                dxtSupported: renderer.hasFeature('texture-compression-bc'),
35849	                bptcSupported: renderer.hasFeature('texture-compression-bptc'),
35850	                pvrtcSupported: renderer.hasFeature('texture-compression-pvrtc')
35851	            };
35852	        } else {
35853	            this.workerConfig = {
35854	                astcSupported: renderer.extensions.has('WEBGL_compressed_texture_astc'),
35855	                astcHDRSupported: renderer.extensions.has('WEBGL_compressed_texture_astc') && renderer.extensions.get('WEBGL_compressed_texture_astc').getSupportedProfiles().includes('hdr'),
35856	                etc1Supported: renderer.extensions.has('WEBGL_compressed_texture_etc1'),
35857	                etc2Supported: renderer.extensions.has('WEBGL_compressed_texture_etc'),
35858	                dxtSupported: renderer.extensions.has('WEBGL_compressed_texture_s3tc'),
35859	                bptcSupported: renderer.extensions.has('EXT_texture_compression_bptc'),
35860	                pvrtcSupported: renderer.extensions.has('WEBGL_compressed_texture_pvrtc') || renderer.extensions.has('WEBKIT_WEBGL_compressed_texture_pvrtc')
35861	            };
35862	        }
35863	        return this;
35864	    }
35865	    init() {
35866	        if (!this.transcoderPending) {
35867	            // Load transcoder wrapper.
35868	            const jsLoader = new FileLoader(this.manager);
35869	            jsLoader.setPath(this.transcoderPath);
35870	            jsLoader.setWithCredentials(this.withCredentials);
35871	            const jsContent = jsLoader.loadAsync('basis_transcoder.js');
35872	            // Load transcoder WASM binary.
35873	            const binaryLoader = new FileLoader(this.manager);
35874	            binaryLoader.setPath(this.transcoderPath);
35875	            binaryLoader.setResponseType('arraybuffer');
35876	            binaryLoader.setWithCredentials(this.withCredentials);
35877	            const binaryContent = binaryLoader.loadAsync('basis_transcoder.wasm');
35878	            this.transcoderPending = Promise.all([
35879	                jsContent,
35880	                binaryContent
35881	            ]).then(([jsContent, binaryContent])=>{
35882	                const fn = KTX2Loader.BasisWorker.toString();
35883	                const body = [
35884	                    '/* constants */',
35885	                    'let _EngineFormat = ' + JSON.stringify(KTX2Loader.EngineFormat),
35886	                    'let _EngineType = ' + JSON.stringify(KTX2Loader.EngineType),
35887	                    'let _TranscoderFormat = ' + JSON.stringify(KTX2Loader.TranscoderFormat),
35888	                    'let _BasisFormat = ' + JSON.stringify(KTX2Loader.BasisFormat),
35889	                    '/* basis_transcoder.js */',
35890	                    jsContent,
35891	                    '/* worker */',
35892	                    fn.substring(fn.indexOf('{') + 1, fn.lastIndexOf('}'))
35893	                ].join('\n');
35894	                this.workerSourceURL = URL.createObjectURL(new Blob([
35895	                    body
35896	                ]));
35897	                this.transcoderBinary = binaryContent;
35898	                this.workerPool.setWorkerCreator(()=>{
35899	                    const worker = new Worker(this.workerSourceURL);
35900	                    const transcoderBinary = this.transcoderBinary.slice(0);
35901	                    worker.postMessage({
35902	                        type: 'init',
35903	                        config: this.workerConfig,
35904	                        transcoderBinary
35905	                    }, [
35906	                        transcoderBinary
35907	                    ]);
35908	                    return worker;
35909	                });
35910	            });
35911	            if (_activeLoaders > 0) {
35912	                // Each instance loads a transcoder and allocates workers, increasing network and memory cost.
35913	                console.warn('THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues.' + ' Use a single KTX2Loader instance, or call .dispose() on old instances.');
35914	            }
35915	            _activeLoaders++;
35916	        }
35917	        return this.transcoderPending;
35918	    }
35919	    load(url, onLoad, onProgress, onError) {
35920	        if (this.workerConfig === null) {
35921	            throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.');
35922	        }
35923	        const loader = new FileLoader(this.manager);
35924	        loader.setResponseType('arraybuffer');
35925	        loader.setWithCredentials(this.withCredentials);
35926	        loader.load(url, (buffer)=>{
35927	            this.parse(buffer, onLoad, onError);
35928	        }, onProgress, onError);
35929	    }
35930	    parse(buffer, onLoad, onError) {
35931	        if (this.workerConfig === null) {
35932	            throw new Error('THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.');
35933	        }
35934	        // Check for an existing task using this buffer. A transferred buffer cannot be transferred
35935	        // again from this thread.
35936	        if (_taskCache.has(buffer)) {
35937	            const cachedTask = _taskCache.get(buffer);
35938	            return cachedTask.promise.then(onLoad).catch(onError);
35939	        }
35940	        this._createTexture(buffer).then((texture)=>onLoad ? onLoad(texture) : null).catch(onError);
35941	    }
35942	    _createTextureFrom(transcodeResult, container) {
35943	        const { type: messageType, error, data: { faces, width, height, format, type, dfdFlags } } = transcodeResult;
35944	        if (messageType === 'error') return Promise.reject(error);
35945	        let texture;
35946	        if (container.faceCount === 6) {
35947	            texture = new CompressedCubeTexture(faces, format, type);
35948	        } else {
35949	            const mipmaps = faces[0].mipmaps;
35950	            texture = container.layerCount > 1 ? new CompressedArrayTexture(mipmaps, width, height, container.layerCount, format, type) : new CompressedTexture(mipmaps, width, height, format, type);
35951	        }
35952	        texture.minFilter = faces[0].mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
35953	        texture.magFilter = LinearFilter;
35954	        texture.generateMipmaps = false;
35955	        texture.needsUpdate = true;
35956	        texture.colorSpace = parseColorSpace(container);
35957	        texture.premultiplyAlpha = !!(dfdFlags & g$1);
35958	        return texture;
35959	    }
35960	    /**
35961		 * @param {ArrayBuffer} buffer
35962		 * @param {?Object} config
35963		 * @return {Promise<CompressedTexture|CompressedArrayTexture|DataTexture|Data3DTexture>}
35964		 */ async _createTexture(buffer, config = {}) {
35965	        const container = Pi(new Uint8Array(buffer));
35966	        // Basis UASTC HDR is a subset of ASTC, which can be transcoded efficiently
35967	        // to BC6H. To detect whether a KTX2 file uses Basis UASTC HDR, or default
35968	        // ASTC, inspect the DFD color model.
35969	        //
35970	        // Source: https://github.com/BinomialLLC/basis_universal/issues/381
35971	        const isBasisHDR = container.vkFormat === pi && container.dataFormatDescriptor[0].colorModel === 0xA7;
35972	        // If the device supports ASTC, Basis UASTC HDR requires no transcoder.
35973	        const needsTranscoder = container.vkFormat === it || isBasisHDR && !this.workerConfig.astcHDRSupported;
35974	        if (!needsTranscoder) {
35975	            return createRawTexture(container);
35976	        }
35977	        //
35978	        const taskConfig = config;
35979	        const texturePending = this.init().then(()=>{
35980	            return this.workerPool.postMessage({
35981	                type: 'transcode',
35982	                buffer,
35983	                taskConfig: taskConfig
35984	            }, [
35985	                buffer
35986	            ]);
35987	        }).then((e)=>this._createTextureFrom(e.data, container));
35988	        // Cache the task result.
35989	        _taskCache.set(buffer, {
35990	            promise: texturePending
35991	        });
35992	        return texturePending;
35993	    }
35994	    dispose() {
35995	        this.workerPool.dispose();
35996	        if (this.workerSourceURL) URL.revokeObjectURL(this.workerSourceURL);
35997	        _activeLoaders--;
35998	        return this;
35999	    }
36000	    constructor(manager){
36001	        super(manager);
36002	        this.transcoderPath = '';
36003	        this.transcoderBinary = null;
36004	        this.transcoderPending = null;
36005	        this.workerPool = new WorkerPool();
36006	        this.workerSourceURL = '';
36007	        this.workerConfig = null;
36008	        if (typeof MSC_TRANSCODER !== 'undefined') {
36009	            console.warn('THREE.KTX2Loader: Please update to latest "basis_transcoder".' + ' "msc_basis_transcoder" is no longer supported in three.js r125+.');
36010	        }
36011	    }
36012	}
36013	/* CONSTANTS */ KTX2Loader.BasisFormat = {
36014	    ETC1S: 0,
36015	    UASTC: 1,
36016	    UASTC_HDR: 2
36017	};
36018	// Source: https://github.com/BinomialLLC/basis_universal/blob/master/webgl/texture_test/index.html
36019	KTX2Loader.TranscoderFormat = {
36020	    ETC1: 0,
36021	    ETC2: 1,
36022	    BC1: 2,
36023	    BC3: 3,
36024	    BC4: 4,
36025	    BC5: 5,
36026	    BC7_M6_OPAQUE_ONLY: 6,
36027	    BC7_M5: 7,
36028	    PVRTC1_4_RGB: 8,
36029	    PVRTC1_4_RGBA: 9,
36030	    ASTC_4x4: 10,
36031	    ATC_RGB: 11,
36032	    ATC_RGBA_INTERPOLATED_ALPHA: 12,
36033	    RGBA32: 13,
36034	    RGB565: 14,
36035	    BGR565: 15,
36036	    RGBA4444: 16,
36037	    BC6H: 22,
36038	    RGB_HALF: 24,
36039	    RGBA_HALF: 25
36040	};
36041	KTX2Loader.EngineFormat = {
36042	    RGBAFormat: RGBAFormat,
36043	    RGBA_ASTC_4x4_Format: RGBA_ASTC_4x4_Format,
36044	    RGB_BPTC_UNSIGNED_Format: RGB_BPTC_UNSIGNED_Format,
36045	    RGBA_BPTC_Format: RGBA_BPTC_Format,
36046	    RGBA_ETC2_EAC_Format: RGBA_ETC2_EAC_Format,
36047	    RGBA_PVRTC_4BPPV1_Format: RGBA_PVRTC_4BPPV1_Format,
36048	    RGBA_S3TC_DXT5_Format: RGBA_S3TC_DXT5_Format,
36049	    RGB_ETC1_Format: RGB_ETC1_Format,
36050	    RGB_ETC2_Format: RGB_ETC2_Format,
36051	    RGB_PVRTC_4BPPV1_Format: RGB_PVRTC_4BPPV1_Format,
36052	    RGBA_S3TC_DXT1_Format: RGBA_S3TC_DXT1_Format
36053	};
36054	KTX2Loader.EngineType = {
36055	    UnsignedByteType: UnsignedByteType,
36056	    HalfFloatType: HalfFloatType,
36057	    FloatType: FloatType
36058	};
36059	/* WEB WORKER */ KTX2Loader.BasisWorker = function() {
36060	    let config;
36061	    let transcoderPending;
36062	    let BasisModule;
36063	    const EngineFormat = _EngineFormat; // eslint-disable-line no-undef
36064	    const EngineType = _EngineType; // eslint-disable-line no-undef
36065	    const TranscoderFormat = _TranscoderFormat; // eslint-disable-line no-undef
36066	    const BasisFormat = _BasisFormat; // eslint-disable-line no-undef
36067	    self.addEventListener('message', function(e) {
36068	        const message = e.data;
36069	        switch(message.type){
36070	            case 'init':
36071	                config = message.config;
36072	                init(message.transcoderBinary);
36073	                break;
36074	            case 'transcode':
36075	                transcoderPending.then(()=>{
36076	                    try {
36077	                        const { faces, buffers, width, height, hasAlpha, format, type, dfdFlags } = transcode(message.buffer);
36078	                        self.postMessage({
36079	                            type: 'transcode',
36080	                            id: message.id,
36081	                            data: {
36082	                                faces,
36083	                                width,
36084	                                height,
36085	                                hasAlpha,
36086	                                format,
36087	                                type,
36088	                                dfdFlags
36089	                            }
36090	                        }, buffers);
36091	                    } catch (error) {
36092	                        console.error(error);
36093	                        self.postMessage({
36094	                            type: 'error',
36095	                            id: message.id,
36096	                            error: error.message
36097	                        });
36098	                    }
36099	                });
36100	                break;
36101	        }
36102	    });
36103	    function init(wasmBinary) {
36104	        transcoderPending = new Promise((resolve)=>{
36105	            BasisModule = {
36106	                wasmBinary,
36107	                onRuntimeInitialized: resolve
36108	            };
36109	            BASIS(BasisModule); // eslint-disable-line no-undef
36110	        }).then(()=>{
36111	            BasisModule.initializeBasis();
36112	            if (BasisModule.KTX2File === undefined) {
36113	                console.warn('THREE.KTX2Loader: Please update Basis Universal transcoder.');
36114	            }
36115	        });
36116	    }
36117	    function transcode(buffer) {
36118	        const ktx2File = new BasisModule.KTX2File(new Uint8Array(buffer));
36119	        function cleanup() {
36120	            ktx2File.close();
36121	            ktx2File.delete();
36122	        }
36123	        if (!ktx2File.isValid()) {
36124	            cleanup();
36125	            throw new Error('THREE.KTX2Loader:	Invalid or unsupported .ktx2 file');
36126	        }
36127	        let basisFormat;
36128	        if (ktx2File.isUASTC()) {
36129	            basisFormat = BasisFormat.UASTC;
36130	        } else if (ktx2File.isETC1S()) {
36131	            basisFormat = BasisFormat.ETC1S;
36132	        } else if (ktx2File.isHDR()) {
36133	            basisFormat = BasisFormat.UASTC_HDR;
36134	        } else {
36135	            throw new Error('THREE.KTX2Loader: Unknown Basis encoding');
36136	        }
36137	        const width = ktx2File.getWidth();
36138	        const height = ktx2File.getHeight();
36139	        const layerCount = ktx2File.getLayers() || 1;
36140	        const levelCount = ktx2File.getLevels();
36141	        const faceCount = ktx2File.getFaces();
36142	        const hasAlpha = ktx2File.getHasAlpha();
36143	        const dfdFlags = ktx2File.getDFDFlags();
36144	        const { transcoderFormat, engineFormat, engineType } = getTranscoderFormat(basisFormat, width, height, hasAlpha);
36145	        if (!width || !height || !levelCount) {
36146	            cleanup();
36147	            throw new Error('THREE.KTX2Loader:	Invalid texture');
36148	        }
36149	        if (!ktx2File.startTranscoding()) {
36150	            cleanup();
36151	            throw new Error('THREE.KTX2Loader: .startTranscoding failed');
36152	        }
36153	        const faces = [];
36154	        const buffers = [];
36155	        for(let face = 0; face < faceCount; face++){
36156	            const mipmaps = [];
36157	            for(let mip = 0; mip < levelCount; mip++){
36158	                const layerMips = [];
36159	                let mipWidth, mipHeight;
36160	                for(let layer = 0; layer < layerCount; layer++){
36161	                    const levelInfo = ktx2File.getImageLevelInfo(mip, layer, face);
36162	                    if (face === 0 && mip === 0 && layer === 0 && (levelInfo.origWidth % 4 !== 0 || levelInfo.origHeight % 4 !== 0)) {
36163	                        console.warn('THREE.KTX2Loader: ETC1S and UASTC textures should use multiple-of-four dimensions.');
36164	                    }
36165	                    if (levelCount > 1) {
36166	                        mipWidth = levelInfo.origWidth;
36167	                        mipHeight = levelInfo.origHeight;
36168	                    } else {
36169	                        // Handles non-multiple-of-four dimensions in textures without mipmaps. Textures with
36170	                        // mipmaps must use multiple-of-four dimensions, for some texture formats and APIs.
36171	                        // See mrdoob/three.js#25908.
36172	                        mipWidth = levelInfo.width;
36173	                        mipHeight = levelInfo.height;
36174	                    }
36175	                    let dst = new Uint8Array(ktx2File.getImageTranscodedSizeInBytes(mip, layer, 0, transcoderFormat));
36176	                    const status = ktx2File.transcodeImage(dst, mip, layer, face, transcoderFormat, 0, -1, -1);
36177	                    if (engineType === EngineType.HalfFloatType) {
36178	                        dst = new Uint16Array(dst.buffer, dst.byteOffset, dst.byteLength / Uint16Array.BYTES_PER_ELEMENT);
36179	                    }
36180	                    if (!status) {
36181	                        cleanup();
36182	                        throw new Error('THREE.KTX2Loader: .transcodeImage failed.');
36183	                    }
36184	                    layerMips.push(dst);
36185	                }
36186	                const mipData = concat(layerMips);
36187	                mipmaps.push({
36188	                    data: mipData,
36189	                    width: mipWidth,
36190	                    height: mipHeight
36191	                });
36192	                buffers.push(mipData.buffer);
36193	            }
36194	            faces.push({
36195	                mipmaps,
36196	                width,
36197	                height,
36198	                format: engineFormat,
36199	                type: engineType
36200	            });
36201	        }
36202	        cleanup();
36203	        return {
36204	            faces,
36205	            buffers,
36206	            width,
36207	            height,
36208	            hasAlpha,
36209	            dfdFlags,
36210	            format: engineFormat,
36211	            type: engineType
36212	        };
36213	    }
36214	    //
36215	    // Optimal choice of a transcoder target format depends on the Basis format (ETC1S, UASTC, or
36216	    // UASTC HDR), device capabilities, and texture dimensions. The list below ranks the formats
36217	    // separately for each format. Currently, priority is assigned based on:
36218	    //
36219	    //   high quality > low quality > uncompressed
36220	    //
vendor: 5,465 bytes, lines 36221-36400
36221	    // Prioritization may be revisited, or exposed for configuration, in the future.
36222	    //
36223	    // Reference: https://github.com/KhronosGroup/3D-Formats-Guidelines/blob/main/KTXDeveloperGuide.md
36224	    const FORMAT_OPTIONS = [
36225	        {
36226	            if: 'astcSupported',
36227	            basisFormat: [
36228	                BasisFormat.UASTC
36229	            ],
36230	            transcoderFormat: [
36231	                TranscoderFormat.ASTC_4x4,
36232	                TranscoderFormat.ASTC_4x4
36233	            ],
36234	            engineFormat: [
36235	                EngineFormat.RGBA_ASTC_4x4_Format,
36236	                EngineFormat.RGBA_ASTC_4x4_Format
36237	            ],
36238	            engineType: [
36239	                EngineType.UnsignedByteType
36240	            ],
36241	            priorityETC1S: Infinity,
36242	            priorityUASTC: 1,
36243	            needsPowerOfTwo: false
36244	        },
36245	        {
36246	            if: 'bptcSupported',
36247	            basisFormat: [
36248	                BasisFormat.ETC1S,
36249	                BasisFormat.UASTC
36250	            ],
36251	            transcoderFormat: [
36252	                TranscoderFormat.BC7_M5,
36253	                TranscoderFormat.BC7_M5
36254	            ],
36255	            engineFormat: [
36256	                EngineFormat.RGBA_BPTC_Format,
36257	                EngineFormat.RGBA_BPTC_Format
36258	            ],
36259	            engineType: [
36260	                EngineType.UnsignedByteType
36261	            ],
36262	            priorityETC1S: 3,
36263	            priorityUASTC: 2,
36264	            needsPowerOfTwo: false
36265	        },
36266	        {
36267	            if: 'dxtSupported',
36268	            basisFormat: [
36269	                BasisFormat.ETC1S,
36270	                BasisFormat.UASTC
36271	            ],
36272	            transcoderFormat: [
36273	                TranscoderFormat.BC1,
36274	                TranscoderFormat.BC3
36275	            ],
36276	            engineFormat: [
36277	                EngineFormat.RGBA_S3TC_DXT1_Format,
36278	                EngineFormat.RGBA_S3TC_DXT5_Format
36279	            ],
36280	            engineType: [
36281	                EngineType.UnsignedByteType
36282	            ],
36283	            priorityETC1S: 4,
36284	            priorityUASTC: 5,
36285	            needsPowerOfTwo: false
36286	        },
36287	        {
36288	            if: 'etc2Supported',
36289	            basisFormat: [
36290	                BasisFormat.ETC1S,
36291	                BasisFormat.UASTC
36292	            ],
36293	            transcoderFormat: [
36294	                TranscoderFormat.ETC1,
36295	                TranscoderFormat.ETC2
36296	            ],
36297	            engineFormat: [
36298	                EngineFormat.RGB_ETC2_Format,
36299	                EngineFormat.RGBA_ETC2_EAC_Format
36300	            ],
36301	            engineType: [
36302	                EngineType.UnsignedByteType
36303	            ],
36304	            priorityETC1S: 1,
36305	            priorityUASTC: 3,
36306	            needsPowerOfTwo: false
36307	        },
36308	        {
36309	            if: 'etc1Supported',
36310	            basisFormat: [
36311	                BasisFormat.ETC1S,
36312	                BasisFormat.UASTC
36313	            ],
36314	            transcoderFormat: [
36315	                TranscoderFormat.ETC1
36316	            ],
36317	            engineFormat: [
36318	                EngineFormat.RGB_ETC1_Format
36319	            ],
36320	            engineType: [
36321	                EngineType.UnsignedByteType
36322	            ],
36323	            priorityETC1S: 2,
36324	            priorityUASTC: 4,
36325	            needsPowerOfTwo: false
36326	        },
36327	        {
36328	            if: 'pvrtcSupported',
36329	            basisFormat: [
36330	                BasisFormat.ETC1S,
36331	                BasisFormat.UASTC
36332	            ],
36333	            transcoderFormat: [
36334	                TranscoderFormat.PVRTC1_4_RGB,
36335	                TranscoderFormat.PVRTC1_4_RGBA
36336	            ],
36337	            engineFormat: [
36338	                EngineFormat.RGB_PVRTC_4BPPV1_Format,
36339	                EngineFormat.RGBA_PVRTC_4BPPV1_Format
36340	            ],
36341	            engineType: [
36342	                EngineType.UnsignedByteType
36343	            ],
36344	            priorityETC1S: 5,
36345	            priorityUASTC: 6,
36346	            needsPowerOfTwo: true
36347	        },
36348	        {
36349	            if: 'bptcSupported',
36350	            basisFormat: [
36351	                BasisFormat.UASTC_HDR
36352	            ],
36353	            transcoderFormat: [
36354	                TranscoderFormat.BC6H
36355	            ],
36356	            engineFormat: [
36357	                EngineFormat.RGB_BPTC_UNSIGNED_Format
36358	            ],
36359	            engineType: [
36360	                EngineType.HalfFloatType
36361	            ],
36362	            priorityHDR: 1,
36363	            needsPowerOfTwo: false
36364	        },
36365	        // Uncompressed fallbacks.
36366	        {
36367	            basisFormat: [
36368	                BasisFormat.ETC1S,
36369	                BasisFormat.UASTC
36370	            ],
36371	            transcoderFormat: [
36372	                TranscoderFormat.RGBA32,
36373	                TranscoderFormat.RGBA32
36374	            ],
36375	            engineFormat: [
36376	                EngineFormat.RGBAFormat,
36377	                EngineFormat.RGBAFormat
36378	            ],
36379	            engineType: [
36380	                EngineType.UnsignedByteType,
36381	                EngineType.UnsignedByteType
36382	            ],
36383	            priorityETC1S: 100,
36384	            priorityUASTC: 100,
36385	            needsPowerOfTwo: false
36386	        },
36387	        {
36388	            basisFormat: [
36389	                BasisFormat.UASTC_HDR
36390	            ],
36391	            transcoderFormat: [
36392	                TranscoderFormat.RGBA_HALF
36393	            ],
36394	            engineFormat: [
36395	                EngineFormat.RGBAFormat
36396	            ],
36397	            engineType: [
36398	                EngineType.HalfFloatType
36399	            ],
36400	            priorityHDR: 100,
vendor: 30,567 bytes, lines 36401-37225
36401	            needsPowerOfTwo: false
36402	        }
36403	    ];
36404	    const OPTIONS = {
36405	        // TODO: For ETC1S we intentionally sort by _UASTC_ priority, preserving
36406	        // a historical accident shown to avoid performance pitfalls for Linux with
36407	        // Firefox & AMD GPU (RadeonSI). Further work needed.
36408	        // See https://github.com/mrdoob/three.js/pull/29730.
36409	        [BasisFormat.ETC1S]: FORMAT_OPTIONS.filter((opt)=>opt.basisFormat.includes(BasisFormat.ETC1S)).sort((a, b)=>a.priorityUASTC - b.priorityUASTC),
36410	        [BasisFormat.UASTC]: FORMAT_OPTIONS.filter((opt)=>opt.basisFormat.includes(BasisFormat.UASTC)).sort((a, b)=>a.priorityUASTC - b.priorityUASTC),
36411	        [BasisFormat.UASTC_HDR]: FORMAT_OPTIONS.filter((opt)=>opt.basisFormat.includes(BasisFormat.UASTC_HDR)).sort((a, b)=>a.priorityHDR - b.priorityHDR)
36412	    };
36413	    function getTranscoderFormat(basisFormat, width, height, hasAlpha) {
36414	        const options = OPTIONS[basisFormat];
36415	        for(let i = 0; i < options.length; i++){
36416	            const opt = options[i];
36417	            if (opt.if && !config[opt.if]) continue;
36418	            if (!opt.basisFormat.includes(basisFormat)) continue;
36419	            if (hasAlpha && opt.transcoderFormat.length < 2) continue;
36420	            if (opt.needsPowerOfTwo && !(isPowerOfTwo(width) && isPowerOfTwo(height))) continue;
36421	            const transcoderFormat = opt.transcoderFormat[hasAlpha ? 1 : 0];
36422	            const engineFormat = opt.engineFormat[hasAlpha ? 1 : 0];
36423	            const engineType = opt.engineType[0];
36424	            return {
36425	                transcoderFormat,
36426	                engineFormat,
36427	                engineType
36428	            };
36429	        }
36430	        throw new Error('THREE.KTX2Loader: Failed to identify transcoding target.');
36431	    }
36432	    function isPowerOfTwo(value) {
36433	        if (value <= 2) return true;
36434	        return (value & value - 1) === 0 && value !== 0;
36435	    }
36436	    /**
36437		 * Concatenates N byte arrays.
36438		 *
36439		 * @param {Uint8Array[]} arrays
36440		 * @return {Uint8Array}
36441		 */ function concat(arrays) {
36442	        if (arrays.length === 1) return arrays[0];
36443	        let totalByteLength = 0;
36444	        for(let i = 0; i < arrays.length; i++){
36445	            const array = arrays[i];
36446	            totalByteLength += array.byteLength;
36447	        }
36448	        const result = new Uint8Array(totalByteLength);
36449	        let byteOffset = 0;
36450	        for(let i = 0; i < arrays.length; i++){
36451	            const array = arrays[i];
36452	            result.set(array, byteOffset);
36453	            byteOffset += array.byteLength;
36454	        }
36455	        return result;
36456	    }
36457	};
36458	// Parsing for non-Basis textures. These textures may have supercompression
36459	// like Zstd, but they do not require transcoding.
36460	const UNCOMPRESSED_FORMATS = new Set([
36461	    RGBAFormat,
36462	    RGFormat,
36463	    RedFormat
36464	]);
36465	const FORMAT_MAP = {
36466	    [Ae]: RGBAFormat,
36467	    [ge]: RGBAFormat,
36468	    [Ft]: RGBAFormat,
36469	    [Ct]: RGBAFormat,
36470	    [we]: RGFormat,
36471	    [ae]: RGFormat,
36472	    [xt]: RGFormat,
36473	    [wt]: RGFormat,
36474	    [ue]: RedFormat,
36475	    [te$1]: RedFormat,
36476	    [yt]: RedFormat,
36477	    [ct]: RedFormat,
36478	    [pi]: RGBA_ASTC_4x4_Format,
36479	    [Sn]: RGBA_ASTC_6x6_Format,
36480	    [In]: RGBA_ASTC_6x6_Format
36481	};
36482	const TYPE_MAP = {
36483	    [Ae]: FloatType,
36484	    [ge]: HalfFloatType,
36485	    [Ft]: UnsignedByteType,
36486	    [Ct]: UnsignedByteType,
36487	    [we]: FloatType,
36488	    [ae]: HalfFloatType,
36489	    [xt]: UnsignedByteType,
36490	    [wt]: UnsignedByteType,
36491	    [ue]: FloatType,
36492	    [te$1]: HalfFloatType,
36493	    [yt]: UnsignedByteType,
36494	    [ct]: UnsignedByteType,
36495	    [pi]: HalfFloatType,
36496	    [Sn]: UnsignedByteType,
36497	    [In]: UnsignedByteType
36498	};
36499	async function createRawTexture(container) {
36500	    const { vkFormat } = container;
36501	    if (FORMAT_MAP[vkFormat] === undefined) {
36502	        throw new Error('THREE.KTX2Loader: Unsupported vkFormat.');
36503	    }
36504	    //
36505	    let zstd;
36506	    if (container.supercompressionScheme === n) {
36507	        if (!_zstd) {
36508	            _zstd = new Promise(async (resolve)=>{
36509	                const zstd = new Q();
36510	                await zstd.init();
36511	                resolve(zstd);
36512	            });
36513	        }
36514	        zstd = await _zstd;
36515	    }
36516	    //
36517	    const mipmaps = [];
36518	    for(let levelIndex = 0; levelIndex < container.levels.length; levelIndex++){
36519	        const levelWidth = Math.max(1, container.pixelWidth >> levelIndex);
36520	        const levelHeight = Math.max(1, container.pixelHeight >> levelIndex);
36521	        const levelDepth = container.pixelDepth ? Math.max(1, container.pixelDepth >> levelIndex) : 0;
36522	        const level = container.levels[levelIndex];
36523	        let levelData;
36524	        if (container.supercompressionScheme === t) {
36525	            levelData = level.levelData;
36526	        } else if (container.supercompressionScheme === n) {
36527	            levelData = zstd.decode(level.levelData, level.uncompressedByteLength);
36528	        } else {
36529	            throw new Error('THREE.KTX2Loader: Unsupported supercompressionScheme.');
36530	        }
36531	        let data;
36532	        if (TYPE_MAP[vkFormat] === FloatType) {
36533	            data = new Float32Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Float32Array.BYTES_PER_ELEMENT);
36534	        } else if (TYPE_MAP[vkFormat] === HalfFloatType) {
36535	            data = new Uint16Array(levelData.buffer, levelData.byteOffset, levelData.byteLength / Uint16Array.BYTES_PER_ELEMENT);
36536	        } else {
36537	            data = levelData;
36538	        }
36539	        mipmaps.push({
36540	            data: data,
36541	            width: levelWidth,
36542	            height: levelHeight,
36543	            depth: levelDepth
36544	        });
36545	    }
36546	    let texture;
36547	    if (UNCOMPRESSED_FORMATS.has(FORMAT_MAP[vkFormat])) {
36548	        texture = container.pixelDepth === 0 ? new DataTexture(mipmaps[0].data, container.pixelWidth, container.pixelHeight) : new Data3DTexture(mipmaps[0].data, container.pixelWidth, container.pixelHeight, container.pixelDepth);
36549	    } else {
36550	        if (container.pixelDepth > 0) throw new Error('THREE.KTX2Loader: Unsupported pixelDepth.');
36551	        texture = new CompressedTexture(mipmaps, container.pixelWidth, container.pixelHeight);
36552	        texture.minFilter = mipmaps.length === 1 ? LinearFilter : LinearMipmapLinearFilter;
36553	        texture.magFilter = LinearFilter;
36554	    }
36555	    texture.mipmaps = mipmaps;
36556	    texture.type = TYPE_MAP[vkFormat];
36557	    texture.format = FORMAT_MAP[vkFormat];
36558	    texture.colorSpace = parseColorSpace(container);
36559	    texture.needsUpdate = true;
36560	    //
36561	    return Promise.resolve(texture);
36562	}
36563	function parseColorSpace(container) {
36564	    const dfd = container.dataFormatDescriptor[0];
36565	    if (dfd.colorPrimaries === C$1) {
36566	        return dfd.transferFunction === u ? SRGBColorSpace : LinearSRGBColorSpace;
36567	    } else if (dfd.colorPrimaries === R) {
36568	        return dfd.transferFunction === u ? DisplayP3ColorSpace : LinearDisplayP3ColorSpace;
36569	    } else if (dfd.colorPrimaries === T) {
36570	        return NoColorSpace;
36571	    } else {
36572	        console.warn(`THREE.KTX2Loader: Unsupported color primaries, "${dfd.colorPrimaries}"`);
36573	        return NoColorSpace;
36574	    }
36575	}
36576
36577	var _a$9, _b$9;
36578	const $retainerCount = Symbol('retainerCount');
36579	const $recentlyUsed = Symbol('recentlyUsed');
36580	const $evict = Symbol('evict');
36581	const $evictionThreshold = Symbol('evictionThreshold');
36582	const $cache = Symbol('cache');
36583	 class CacheEvictionPolicy {
36584	 set evictionThreshold(value) {
36585	        this[$evictionThreshold] = value;
36586	        this[$evict]();
36587	    }
36588	    get evictionThreshold() {
36589	        return this[$evictionThreshold];
36590	    }
36591	 get cache() {
36592	        return this[$cache];
36593	    }
36594	 retainerCount(key) {
36595	        return this[$retainerCount].get(key) || 0;
36596	    }
36597	 reset() {
36598	        this[$retainerCount].clear();
36599	        this[$recentlyUsed] = [];
36600	    }
36601	 retain(key) {
36602	        if (!this[$retainerCount].has(key)) {
36603	            this[$retainerCount].set(key, 0);
36604	        }
36605	        this[$retainerCount].set(key, this[$retainerCount].get(key) + 1);
36606	        const recentlyUsedIndex = this[$recentlyUsed].indexOf(key);
36607	        if (recentlyUsedIndex !== -1) {
36608	            this[$recentlyUsed].splice(recentlyUsedIndex, 1);
36609	        }
36610	        this[$recentlyUsed].unshift(key);
36611	        this[$evict]();
36612	    }
36613	 release(key) {
36614	        if (this[$retainerCount].has(key)) {
36615	            this[$retainerCount].set(key, Math.max(this[$retainerCount].get(key) - 1, 0));
36616	        }
36617	        this[$evict]();
36618	    }
36619	    [(_a$9 = $retainerCount, _b$9 = $recentlyUsed, $evict)]() {
36620	        if (this[$recentlyUsed].length < this[$evictionThreshold]) {
36621	            return;
36622	        }
36623	        for(let i = this[$recentlyUsed].length - 1; i >= this[$evictionThreshold]; --i){
36624	            const key = this[$recentlyUsed][i];
36625	            const retainerCount = this[$retainerCount].get(key);
36626	            if (retainerCount === 0) {
36627	                this[$cache].delete(key);
36628	                this[$recentlyUsed].splice(i, 1);
36629	            }
36630	        }
36631	    }
36632	    constructor(cache, evictionThreshold = 5){
36633	        this[_a$9] = new Map();
36634	        this[_b$9] = [];
36635	        this[$cache] = cache;
36636	        this[$evictionThreshold] = evictionThreshold;
36637	    }
36638	}
36639
36640	const ensureUniqueNames = (variantNames)=>{
36641	    const uniqueNames = [];
36642	    const knownNames = new Set();
36643	    for (const name of variantNames){
36644	        let uniqueName = name;
36645	        let suffix = 0;
36646	        while(knownNames.has(uniqueName)){
36647	            uniqueName = name + '.' + ++suffix;
36648	        }
36649	        knownNames.add(uniqueName);
36650	        uniqueNames.push(uniqueName);
36651	    }
36652	    return uniqueNames;
36653	};
36654	 const mappingsArrayToTable = (extensionDef)=>{
36655	    const table = new Map();
36656	    for (const mapping of extensionDef.mappings){
36657	        for (const variant of mapping.variants){
36658	            table.set(variant, {
36659	                material: null,
36660	                gltfMaterialIndex: mapping.material
36661	            });
36662	        }
36663	    }
36664	    return table;
36665	};
36666	class GLTFMaterialsVariantsExtension {
36667	    afterRoot(gltf) {
36668	        const parser = this.parser;
36669	        const json = parser.json;
36670	        if (json.extensions === undefined || json.extensions[this.name] === undefined) {
36671	            return null;
36672	        }
36673	        const extensionDef = json.extensions[this.name];
36674	        const variantsDef = extensionDef.variants || [];
36675	        const variants = ensureUniqueNames(variantsDef.map((v)=>v.name));
36676	        for (const scene of gltf.scenes){
36677	            scene.traverse((object)=>{
36678	                const mesh = object;
36679	                if (!mesh.material) {
36680	                    return;
36681	                }
36682	                const association = parser.associations.get(mesh);
36683	                if (association == null || association.meshes == null || association.primitives == null) {
36684	                    return;
36685	                }
36686	                const meshDef = json.meshes[association.meshes];
36687	                const primitivesDef = meshDef.primitives;
36688	                const primitiveDef = primitivesDef[association.primitives];
36689	                const extensionsDef = primitiveDef.extensions;
36690	                if (!extensionsDef || !extensionsDef[this.name]) {
36691	                    return;
36692	                }
36693	                mesh.userData.variantMaterials = mappingsArrayToTable(extensionsDef[this.name]);
36694	            });
36695	        }
36696	        gltf.userData.variants = variants;
36697	        return Promise.resolve();
36698	    }
36699	    constructor(parser){
36700	        this.parser = parser;
36701	        this.name = 'KHR_materials_variants';
36702	    }
36703	}
36704
36705	var _a$8, _b$8;
36706	Texture$1.DEFAULT_ANISOTROPY = 4;
36707	 const loadWithLoader = (url, loader, progressCallback = ()=>{})=>{
36708	    const onProgress = (event)=>{
36709	        const fraction = event.loaded / event.total;
36710	        progressCallback(Math.max(0, Math.min(1, isFinite(fraction) ? fraction : 1)));
36711	    };
36712	    return new Promise((resolve, reject)=>{
36713	        loader.load(url, resolve, onProgress, reject);
36714	    });
36715	};
36716	 const fetchScript = (src)=>{
36717	    return new Promise((resolve, reject)=>{
36718	        const script = document.createElement('script');
36719	        document.body.appendChild(script);
36720	        script.onload = resolve;
36721	        script.onerror = reject;
36722	        script.async = true;
36723	        script.src = src;
36724	    });
36725	};
36726	const cache = new Map();
36727	const preloaded = new Map();
36728	let dracoDecoderLocation;
36729	const dracoLoader = new DRACOLoader();
36730	let ktx2TranscoderLocation;
36731	const ktx2Loader = new KTX2Loader();
36732	let meshoptDecoderLocation;
36733	let meshoptDecoder;
36734	const $loader = Symbol('loader');
36735	const $evictionPolicy = Symbol('evictionPolicy');
36736	const $GLTFInstance = Symbol('GLTFInstance');
36737	class CachingGLTFLoader extends EventDispatcher {
36738	    static setDRACODecoderLocation(url) {
36739	        dracoDecoderLocation = url;
36740	        dracoLoader.setDecoderPath(url);
36741	    }
36742	    static getDRACODecoderLocation() {
36743	        return dracoDecoderLocation;
36744	    }
36745	    static setKTX2TranscoderLocation(url) {
36746	        ktx2TranscoderLocation = url;
36747	        ktx2Loader.setTranscoderPath(url);
36748	    }
36749	    static getKTX2TranscoderLocation() {
36750	        return ktx2TranscoderLocation;
36751	    }
36752	    static setMeshoptDecoderLocation(url) {
36753	        if (meshoptDecoderLocation !== url) {
36754	            meshoptDecoderLocation = url;
36755	            meshoptDecoder = fetchScript(url).then(()=>MeshoptDecoder.ready).then(()=>MeshoptDecoder);
36756	        }
36757	    }
36758	    static getMeshoptDecoderLocation() {
36759	        return meshoptDecoderLocation;
36760	    }
36761	    static initializeKTX2Loader(renderer) {
36762	        ktx2Loader.detectSupport(renderer);
36763	    }
36764	    static get cache() {
36765	        return cache;
36766	    }
36767	     static clearCache() {
36768	        cache.forEach((_value, url)=>{
36769	            this.delete(url);
36770	        });
36771	        this[$evictionPolicy].reset();
36772	    }
36773	    static has(url) {
36774	        return cache.has(url);
36775	    }
36776	     static async delete(url) {
36777	        if (!this.has(url)) {
36778	            return;
36779	        }
36780	        const gltfLoads = cache.get(url);
36781	        preloaded.delete(url);
36782	        cache.delete(url);
36783	        const gltf = await gltfLoads;
36784	        gltf.dispose();
36785	    }
36786	 static hasFinishedLoading(url) {
36787	        return !!preloaded.get(url);
36788	    }
36789	    get [(_a$8 = $evictionPolicy, _b$8 = $loader, $evictionPolicy)]() {
36790	        return this.constructor[$evictionPolicy];
36791	    }
36792	 async preload(url, element, progressCallback = ()=>{}) {
36793	        this[$loader].setWithCredentials(element.withCredentials);
36794	        this.dispatchEvent({
36795	            type: 'preload',
36796	            element: element,
36797	            src: url
36798	        });
36799	        if (!cache.has(url)) {
36800	            if (meshoptDecoder != null) {
36801	                this[$loader].setMeshoptDecoder(await meshoptDecoder);
36802	            }
36803	            const rawGLTFLoads = loadWithLoader(url, this[$loader], (progress)=>{
36804	                progressCallback(progress * 0.8);
36805	            });
36806	            const GLTFInstance = this[$GLTFInstance];
36807	            const gltfInstanceLoads = rawGLTFLoads.then((rawGLTF)=>{
36808	                return GLTFInstance.prepare(rawGLTF);
36809	            }).then((preparedGLTF)=>{
36810	                progressCallback(0.9);
36811	                return new GLTFInstance(preparedGLTF);
36812	            }).catch((reason)=>{
36813	                console.error(reason);
36814	                return new GLTFInstance();
36815	            });
36816	            cache.set(url, gltfInstanceLoads);
36817	        }
36818	        await cache.get(url);
36819	        preloaded.set(url, true);
36820	        if (progressCallback) {
36821	            progressCallback(1.0);
36822	        }
36823	    }
36824	 async load(url, element, progressCallback = ()=>{}) {
36825	        await this.preload(url, element, progressCallback);
36826	        const gltf = await cache.get(url);
36827	        const clone = await gltf.clone();
36828	        this[$evictionPolicy].retain(url);
36829	        clone.dispose = ()=>{
36830	            this[$evictionPolicy].release(url);
36831	        };
36832	        return clone;
36833	    }
36834	    constructor(GLTFInstance){
36835	        super();
36836	        this[_b$8] = new GLTFLoader().register((parser)=>new GLTFMaterialsVariantsExtension(parser));
36837	        this[$GLTFInstance] = GLTFInstance;
36838	        this[$loader].setDRACOLoader(dracoLoader);
36839	        this[$loader].setKTX2Loader(ktx2Loader);
36840	    }
36841	}
36842	CachingGLTFLoader[_a$8] = new CacheEvictionPolicy(CachingGLTFLoader);
36843
36844	class CSS2DObject extends Object3D {
36845	    copy(source, recursive) {
36846	        super.copy(source, recursive);
36847	        this.element = source.element.cloneNode(true);
36848	        this.center = source.center;
36849	        return this;
36850	    }
36851	    constructor(element = document.createElement('div')){
36852	        super();
36853	        this.isCSS2DObject = true;
36854	        this.element = element;
36855	        this.element.style.position = 'absolute';
36856	        this.element.style.userSelect = 'none';
36857	        this.element.setAttribute('draggable', false);
36858	        this.center = new Vector2(0.5, 0.5); // ( 0, 0 ) is the lower left; ( 1, 1 ) is the top right
36859	        this.addEventListener('removed', function() {
36860	            this.traverse(function(object) {
36861	                if (object.element instanceof object.element.ownerDocument.defaultView.Element && object.element.parentNode !== null) {
36862	                    object.element.remove();
36863	                }
36864	            });
36865	        });
36866	    }
36867	}
36868	//
36869	const _vector = new Vector3();
36870	const _viewMatrix = new Matrix4();
36871	const _viewProjectionMatrix = new Matrix4();
36872	const _a$7 = new Vector3();
36873	const _b$7 = new Vector3();
36874	class CSS2DRenderer {
36875	    constructor(parameters = {}){
36876	        const _this = this;
36877	        let _width, _height;
36878	        let _widthHalf, _heightHalf;
36879	        const cache = {
36880	            objects: new WeakMap()
36881	        };
36882	        const domElement = parameters.element !== undefined ? parameters.element : document.createElement('div');
36883	        domElement.style.overflow = 'hidden';
36884	        this.domElement = domElement;
36885	        this.getSize = function() {
36886	            return {
36887	                width: _width,
36888	                height: _height
36889	            };
36890	        };
36891	        this.render = function(scene, camera) {
36892	            if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld();
36893	            if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld();
36894	            _viewMatrix.copy(camera.matrixWorldInverse);
36895	            _viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix);
36896	            renderObject(scene, scene, camera);
36897	            zOrder(scene);
36898	        };
36899	        this.setSize = function(width, height) {
36900	            _width = width;
36901	            _height = height;
36902	            _widthHalf = _width / 2;
36903	            _heightHalf = _height / 2;
36904	            domElement.style.width = width + 'px';
36905	            domElement.style.height = height + 'px';
36906	        };
36907	        function hideObject(object) {
36908	            if (object.isCSS2DObject) object.element.style.display = 'none';
36909	            for(let i = 0, l = object.children.length; i < l; i++){
36910	                hideObject(object.children[i]);
36911	            }
36912	        }
36913	        function renderObject(object, scene, camera) {
36914	            if (object.visible === false) {
36915	                hideObject(object);
36916	                return;
36917	            }
36918	            if (object.isCSS2DObject) {
36919	                _vector.setFromMatrixPosition(object.matrixWorld);
36920	                _vector.applyMatrix4(_viewProjectionMatrix);
36921	                const visible = _vector.z >= -1 && _vector.z <= 1 && object.layers.test(camera.layers) === true;
36922	                const element = object.element;
36923	                element.style.display = visible === true ? '' : 'none';
36924	                if (visible === true) {
36925	                    object.onBeforeRender(_this, scene, camera);
36926	                    element.style.transform = 'translate(' + -100 * object.center.x + '%,' + -100 * object.center.y + '%)' + 'translate(' + (_vector.x * _widthHalf + _widthHalf) + 'px,' + (-_vector.y * _heightHalf + _heightHalf) + 'px)';
36927	                    if (element.parentNode !== domElement) {
36928	                        domElement.appendChild(element);
36929	                    }
36930	                    object.onAfterRender(_this, scene, camera);
36931	                }
36932	                const objectData = {
36933	                    distanceToCameraSquared: getDistanceToSquared(camera, object)
36934	                };
36935	                cache.objects.set(object, objectData);
36936	            }
36937	            for(let i = 0, l = object.children.length; i < l; i++){
36938	                renderObject(object.children[i], scene, camera);
36939	            }
36940	        }
36941	        function getDistanceToSquared(object1, object2) {
36942	            _a$7.setFromMatrixPosition(object1.matrixWorld);
36943	            _b$7.setFromMatrixPosition(object2.matrixWorld);
36944	            return _a$7.distanceToSquared(_b$7);
36945	        }
36946	        function filterAndFlatten(scene) {
36947	            const result = [];
36948	            scene.traverseVisible(function(object) {
36949	                if (object.isCSS2DObject) result.push(object);
36950	            });
36951	            return result;
36952	        }
36953	        function zOrder(scene) {
36954	            const sorted = filterAndFlatten(scene).sort(function(a, b) {
36955	                if (a.renderOrder !== b.renderOrder) {
36956	                    return b.renderOrder - a.renderOrder;
36957	                }
36958	                const distanceA = cache.objects.get(a).distanceToCameraSquared;
36959	                const distanceB = cache.objects.get(b).distanceToCameraSquared;
36960	                return distanceA - distanceB;
36961	            });
36962	            const zMax = sorted.length;
36963	            for(let i = 0, l = sorted.length; i < l; i++){
36964	                sorted[i].element.style.zIndex = zMax - i;
36965	            }
36966	        }
36967	    }
36968	}
36969
36970	function reduceVertices(object, func, initialValue) {
36971	    let value = initialValue;
36972	    const vertex = new Vector3();
36973	    object.updateWorldMatrix(true, true);
36974	    object.traverseVisible((child)=>{
36975	        const { geometry } = child;
36976	        if (geometry !== undefined) {
36977	            const { position } = geometry.attributes;
36978	            if (position !== undefined) {
36979	                for(let i = 0, l = position.count; i < l; i++){
36980	                    if (child.isMesh) {
36981	                        child.getVertexPosition(i, vertex);
36982	                    } else {
36983	                        vertex.fromBufferAttribute(position, i);
36984	                    }
36985	                    if (!child.isSkinnedMesh) {
36986	                        vertex.applyMatrix4(child.matrixWorld);
36987	                    }
36988	                    value = func(value, vertex);
36989	                }
36990	            }
36991	        }
36992	    });
36993	    return value;
36994	}
36995
36996	/**
36997	 * The KHR_mesh_quantization extension allows these extra attribute component types
36998	 *
36999	 * @see https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md#extending-mesh-attributes
37000	 */ const KHR_mesh_quantization_ExtraAttrTypes = {
37001	    POSITION: [
37002	        'byte',
37003	        'byte normalized',
37004	        'unsigned byte',
37005	        'unsigned byte normalized',
37006	        'short',
37007	        'short normalized',
37008	        'unsigned short',
37009	        'unsigned short normalized'
37010	    ],
37011	    NORMAL: [
37012	        'byte normalized',
37013	        'short normalized'
37014	    ],
37015	    TANGENT: [
37016	        'byte normalized',
37017	        'short normalized'
37018	    ],
37019	    TEXCOORD: [
37020	        'byte',
37021	        'byte normalized',
37022	        'unsigned byte',
37023	        'short',
37024	        'short normalized',
37025	        'unsigned short'
37026	    ]
37027	};
37028	class GLTFExporter {
37029	    register(callback) {
37030	        if (this.pluginCallbacks.indexOf(callback) === -1) {
37031	            this.pluginCallbacks.push(callback);
37032	        }
37033	        return this;
37034	    }
37035	    unregister(callback) {
37036	        if (this.pluginCallbacks.indexOf(callback) !== -1) {
37037	            this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
37038	        }
37039	        return this;
37040	    }
37041	    setTextureUtils(utils) {
37042	        this.textureUtils = utils;
37043	        return this;
37044	    }
37045	    /**
37046		 * Parse scenes and generate GLTF output
37047		 *
37048		 * @param  {Scene|Array<Scene>} input   Scene or Array of THREE.Scenes
37049		 * @param  {Function} onDone  Callback on completed
37050		 * @param  {Function} onError  Callback on errors
37051		 * @param  {Object} options options
37052		 */ parse(input, onDone, onError, options) {
37053	        const writer = new GLTFWriter();
37054	        const plugins = [];
37055	        for(let i = 0, il = this.pluginCallbacks.length; i < il; i++){
37056	            plugins.push(this.pluginCallbacks[i](writer));
37057	        }
37058	        writer.setPlugins(plugins);
37059	        writer.setTextureUtils(this.textureUtils);
37060	        writer.writeAsync(input, onDone, options).catch(onError);
37061	    }
37062	    parseAsync(input, options) {
37063	        const scope = this;
37064	        return new Promise(function(resolve, reject) {
37065	            scope.parse(input, resolve, reject, options);
37066	        });
37067	    }
37068	    constructor(){
37069	        this.textureUtils = null;
37070	        this.pluginCallbacks = [];
37071	        this.register(function(writer) {
37072	            return new GLTFLightExtension(writer);
37073	        });
37074	        this.register(function(writer) {
37075	            return new GLTFMaterialsUnlitExtension(writer);
37076	        });
37077	        this.register(function(writer) {
37078	            return new GLTFMaterialsTransmissionExtension(writer);
37079	        });
37080	        this.register(function(writer) {
37081	            return new GLTFMaterialsVolumeExtension(writer);
37082	        });
37083	        this.register(function(writer) {
37084	            return new GLTFMaterialsIorExtension(writer);
37085	        });
37086	        this.register(function(writer) {
37087	            return new GLTFMaterialsSpecularExtension(writer);
37088	        });
37089	        this.register(function(writer) {
37090	            return new GLTFMaterialsClearcoatExtension(writer);
37091	        });
37092	        this.register(function(writer) {
37093	            return new GLTFMaterialsDispersionExtension(writer);
37094	        });
37095	        this.register(function(writer) {
37096	            return new GLTFMaterialsIridescenceExtension(writer);
37097	        });
37098	        this.register(function(writer) {
37099	            return new GLTFMaterialsSheenExtension(writer);
37100	        });
37101	        this.register(function(writer) {
37102	            return new GLTFMaterialsAnisotropyExtension(writer);
37103	        });
37104	        this.register(function(writer) {
37105	            return new GLTFMaterialsEmissiveStrengthExtension(writer);
37106	        });
37107	        this.register(function(writer) {
37108	            return new GLTFMaterialsBumpExtension(writer);
37109	        });
37110	        this.register(function(writer) {
37111	            return new GLTFMeshGpuInstancing(writer);
37112	        });
37113	    }
37114	}
37115	//------------------------------------------------------------------------------
37116	// Constants
37117	//------------------------------------------------------------------------------
37118	const WEBGL_CONSTANTS = {
37119	    POINTS: 0x0000,
37120	    LINES: 0x0001,
37121	    LINE_LOOP: 0x0002,
37122	    LINE_STRIP: 0x0003,
37123	    TRIANGLES: 0x0004,
37124	    BYTE: 0x1400,
37125	    UNSIGNED_BYTE: 0x1401,
37126	    SHORT: 0x1402,
37127	    UNSIGNED_SHORT: 0x1403,
37128	    INT: 0x1404,
37129	    UNSIGNED_INT: 0x1405,
37130	    FLOAT: 0x1406,
37131	    ARRAY_BUFFER: 0x8892,
37132	    ELEMENT_ARRAY_BUFFER: 0x8893,
37133	    NEAREST: 0x2600,
37134	    LINEAR: 0x2601,
37135	    NEAREST_MIPMAP_NEAREST: 0x2700,
37136	    LINEAR_MIPMAP_NEAREST: 0x2701,
37137	    NEAREST_MIPMAP_LINEAR: 0x2702,
37138	    LINEAR_MIPMAP_LINEAR: 0x2703,
37139	    CLAMP_TO_EDGE: 33071,
37140	    MIRRORED_REPEAT: 33648,
37141	    REPEAT: 10497
37142	};
37143	const KHR_MESH_QUANTIZATION = 'KHR_mesh_quantization';
37144	const THREE_TO_WEBGL = {};
37145	THREE_TO_WEBGL[NearestFilter] = WEBGL_CONSTANTS.NEAREST;
37146	THREE_TO_WEBGL[NearestMipmapNearestFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_NEAREST;
37147	THREE_TO_WEBGL[NearestMipmapLinearFilter] = WEBGL_CONSTANTS.NEAREST_MIPMAP_LINEAR;
37148	THREE_TO_WEBGL[LinearFilter] = WEBGL_CONSTANTS.LINEAR;
37149	THREE_TO_WEBGL[LinearMipmapNearestFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_NEAREST;
37150	THREE_TO_WEBGL[LinearMipmapLinearFilter] = WEBGL_CONSTANTS.LINEAR_MIPMAP_LINEAR;
37151	THREE_TO_WEBGL[ClampToEdgeWrapping] = WEBGL_CONSTANTS.CLAMP_TO_EDGE;
37152	THREE_TO_WEBGL[RepeatWrapping] = WEBGL_CONSTANTS.REPEAT;
37153	THREE_TO_WEBGL[MirroredRepeatWrapping] = WEBGL_CONSTANTS.MIRRORED_REPEAT;
37154	const PATH_PROPERTIES = {
37155	    scale: 'scale',
37156	    position: 'translation',
37157	    quaternion: 'rotation',
37158	    morphTargetInfluences: 'weights'
37159	};
37160	const DEFAULT_SPECULAR_COLOR = new Color();
37161	// GLB constants
37162	// https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
37163	const GLB_HEADER_BYTES = 12;
37164	const GLB_HEADER_MAGIC = 0x46546C67;
37165	const GLB_VERSION = 2;
37166	const GLB_CHUNK_PREFIX_BYTES = 8;
37167	const GLB_CHUNK_TYPE_JSON = 0x4E4F534A;
37168	const GLB_CHUNK_TYPE_BIN = 0x004E4942;
37169	//------------------------------------------------------------------------------
37170	// Utility functions
37171	//------------------------------------------------------------------------------
37172	/**
37173	 * Compare two arrays
37174	 * @param  {Array} array1 Array 1 to compare
37175	 * @param  {Array} array2 Array 2 to compare
37176	 * @return {boolean}        Returns true if both arrays are equal
37177	 */ function equalArray(array1, array2) {
37178	    return array1.length === array2.length && array1.every(function(element, index) {
37179	        return element === array2[index];
37180	    });
37181	}
37182	/**
37183	 * Converts a string to an ArrayBuffer.
37184	 * @param  {string} text
37185	 * @return {ArrayBuffer}
37186	 */ function stringToArrayBuffer(text) {
37187	    return new TextEncoder().encode(text).buffer;
37188	}
37189	/**
37190	 * Is identity matrix
37191	 *
37192	 * @param {Matrix4} matrix
37193	 * @returns {boolean} Returns true, if parameter is identity matrix
37194	 */ function isIdentityMatrix(matrix) {
37195	    return equalArray(matrix.elements, [
37196	        1,
37197	        0,
37198	        0,
37199	        0,
37200	        0,
37201	        1,
37202	        0,
37203	        0,
37204	        0,
37205	        0,
37206	        1,
37207	        0,
37208	        0,
37209	        0,
37210	        0,
37211	        1
37212	    ]);
37213	}
37214	/**
37215	 * Get the min and max vectors from the given attribute
37216	 *
37217	 * @param  {BufferAttribute} attribute Attribute to find the min/max in range from start to start + count
37218	 * @param  {number} start Start index
37219	 * @param  {number} count Range to cover
37220	 * @return {Object} Object containing the `min` and `max` values (As an array of attribute.itemSize components)
37221	 */ function getMinMax(attribute, start, count) {
37222	    const output = {
37223	        min: new Array(attribute.itemSize).fill(Number.POSITIVE_INFINITY),
37224	        max: new Array(attribute.itemSize).fill(Number.NEGATIVE_INFINITY)
37225	    };
vendor: 10,845 bytes, lines 37226-37485
37226	    for(let i = start; i < start + count; i++){
37227	        for(let a = 0; a < attribute.itemSize; a++){
37228	            let value;
37229	            if (attribute.itemSize > 4) {
37230	                // no support for interleaved data for itemSize > 4
37231	                value = attribute.array[i * attribute.itemSize + a];
37232	            } else {
37233	                if (a === 0) value = attribute.getX(i);
37234	                else if (a === 1) value = attribute.getY(i);
37235	                else if (a === 2) value = attribute.getZ(i);
37236	                else if (a === 3) value = attribute.getW(i);
37237	                if (attribute.normalized === true) {
37238	                    value = MathUtils.normalize(value, attribute.array);
37239	                }
37240	            }
37241	            output.min[a] = Math.min(output.min[a], value);
37242	            output.max[a] = Math.max(output.max[a], value);
37243	        }
37244	    }
37245	    return output;
37246	}
37247	/**
37248	 * Get the required size + padding for a buffer, rounded to the next 4-byte boundary.
37249	 * https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
37250	 *
37251	 * @param {number} bufferSize The size the original buffer. Should be an integer.
37252	 * @returns {number} new buffer size with required padding as an integer.
37253	 *
37254	 */ function getPaddedBufferSize(bufferSize) {
37255	    return Math.ceil(bufferSize / 4) * 4;
37256	}
37257	/**
37258	 * Returns a buffer aligned to 4-byte boundary.
37259	 *
37260	 * @param {ArrayBuffer} arrayBuffer Buffer to pad
37261	 * @param {number} [paddingByte=0] Should be an integer
37262	 * @returns {ArrayBuffer} The same buffer if it's already aligned to 4-byte boundary or a new buffer
37263	 */ function getPaddedArrayBuffer(arrayBuffer, paddingByte = 0) {
37264	    const paddedLength = getPaddedBufferSize(arrayBuffer.byteLength);
37265	    if (paddedLength !== arrayBuffer.byteLength) {
37266	        const array = new Uint8Array(paddedLength);
37267	        array.set(new Uint8Array(arrayBuffer));
37268	        if (paddingByte !== 0) {
37269	            for(let i = arrayBuffer.byteLength; i < paddedLength; i++){
37270	                array[i] = paddingByte;
37271	            }
37272	        }
37273	        return array.buffer;
37274	    }
37275	    return arrayBuffer;
37276	}
37277	function getCanvas() {
37278	    if (typeof document === 'undefined' && typeof OffscreenCanvas !== 'undefined') {
37279	        return new OffscreenCanvas(1, 1);
37280	    }
37281	    return document.createElement('canvas');
37282	}
37283	function getToBlobPromise(canvas, mimeType) {
37284	    if (canvas.toBlob !== undefined) {
37285	        return new Promise((resolve)=>canvas.toBlob(resolve, mimeType));
37286	    }
37287	    let quality;
37288	    // Blink's implementation of convertToBlob seems to default to a quality level of 100%
37289	    // Use the Blink default quality levels of toBlob instead so that file sizes are comparable.
37290	    if (mimeType === 'image/jpeg') {
37291	        quality = 0.92;
37292	    } else if (mimeType === 'image/webp') {
37293	        quality = 0.8;
37294	    }
37295	    return canvas.convertToBlob({
37296	        type: mimeType,
37297	        quality: quality
37298	    });
37299	}
37300	/**
37301	 * Writer
37302	 */ class GLTFWriter {
37303	    setPlugins(plugins) {
37304	        this.plugins = plugins;
37305	    }
37306	    setTextureUtils(utils) {
37307	        this.textureUtils = utils;
37308	    }
37309	    /**
37310		 * Parse scenes and generate GLTF output
37311		 *
37312		 * @param {Scene|Array<Scene>} input Scene or Array of THREE.Scenes
37313		 * @param {Function} onDone Callback on completed
37314		 * @param {Object} options options
37315		 */ async writeAsync(input, onDone, options = {}) {
37316	        this.options = Object.assign({
37317	            // default options
37318	            binary: false,
37319	            trs: false,
37320	            onlyVisible: true,
37321	            maxTextureSize: Infinity,
37322	            animations: [],
37323	            includeCustomExtensions: false
37324	        }, options);
37325	        if (this.options.animations.length > 0) {
37326	            // Only TRS properties, and not matrices, may be targeted by animation.
37327	            this.options.trs = true;
37328	        }
37329	        await this.processInputAsync(input);
37330	        await Promise.all(this.pending);
37331	        const writer = this;
37332	        const buffers = writer.buffers;
37333	        const json = writer.json;
37334	        options = writer.options;
37335	        const extensionsUsed = writer.extensionsUsed;
37336	        const extensionsRequired = writer.extensionsRequired;
37337	        // Merge buffers.
37338	        const blob = new Blob(buffers, {
37339	            type: 'application/octet-stream'
37340	        });
37341	        // Declare extensions.
37342	        const extensionsUsedList = Object.keys(extensionsUsed);
37343	        const extensionsRequiredList = Object.keys(extensionsRequired);
37344	        if (extensionsUsedList.length > 0) json.extensionsUsed = extensionsUsedList;
37345	        if (extensionsRequiredList.length > 0) json.extensionsRequired = extensionsRequiredList;
37346	        // Update bytelength of the single buffer.
37347	        if (json.buffers && json.buffers.length > 0) json.buffers[0].byteLength = blob.size;
37348	        if (options.binary === true) {
37349	            // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-file-format-specification
37350	            const reader = new FileReader();
37351	            reader.readAsArrayBuffer(blob);
37352	            reader.onloadend = function() {
37353	                // Binary chunk.
37354	                const binaryChunk = getPaddedArrayBuffer(reader.result);
37355	                const binaryChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
37356	                binaryChunkPrefix.setUint32(0, binaryChunk.byteLength, true);
37357	                binaryChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_BIN, true);
37358	                // JSON chunk.
37359	                const jsonChunk = getPaddedArrayBuffer(stringToArrayBuffer(JSON.stringify(json)), 0x20);
37360	                const jsonChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
37361	                jsonChunkPrefix.setUint32(0, jsonChunk.byteLength, true);
37362	                jsonChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_JSON, true);
37363	                // GLB header.
37364	                const header = new ArrayBuffer(GLB_HEADER_BYTES);
37365	                const headerView = new DataView(header);
37366	                headerView.setUint32(0, GLB_HEADER_MAGIC, true);
37367	                headerView.setUint32(4, GLB_VERSION, true);
37368	                const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength;
37369	                headerView.setUint32(8, totalByteLength, true);
37370	                const glbBlob = new Blob([
37371	                    header,
37372	                    jsonChunkPrefix,
37373	                    jsonChunk,
37374	                    binaryChunkPrefix,
37375	                    binaryChunk
37376	                ], {
37377	                    type: 'application/octet-stream'
37378	                });
37379	                const glbReader = new FileReader();
37380	                glbReader.readAsArrayBuffer(glbBlob);
37381	                glbReader.onloadend = function() {
37382	                    onDone(glbReader.result);
37383	                };
37384	            };
37385	        } else {
37386	            if (json.buffers && json.buffers.length > 0) {
37387	                const reader = new FileReader();
37388	                reader.readAsDataURL(blob);
37389	                reader.onloadend = function() {
37390	                    const base64data = reader.result;
37391	                    json.buffers[0].uri = base64data;
37392	                    onDone(json);
37393	                };
37394	            } else {
37395	                onDone(json);
37396	            }
37397	        }
37398	    }
37399	    /**
37400		 * Serializes a userData.
37401		 *
37402		 * @param {THREE.Object3D|THREE.Material} object
37403		 * @param {Object} objectDef
37404		 */ serializeUserData(object, objectDef) {
37405	        if (Object.keys(object.userData).length === 0) return;
37406	        const options = this.options;
37407	        const extensionsUsed = this.extensionsUsed;
37408	        try {
37409	            const json = JSON.parse(JSON.stringify(object.userData));
37410	            if (options.includeCustomExtensions && json.gltfExtensions) {
37411	                if (objectDef.extensions === undefined) objectDef.extensions = {};
37412	                for(const extensionName in json.gltfExtensions){
37413	                    objectDef.extensions[extensionName] = json.gltfExtensions[extensionName];
37414	                    extensionsUsed[extensionName] = true;
37415	                }
37416	                delete json.gltfExtensions;
37417	            }
37418	            if (Object.keys(json).length > 0) objectDef.extras = json;
37419	        } catch (error) {
37420	            console.warn('THREE.GLTFExporter: userData of \'' + object.name + '\' ' + 'won\'t be serialized because of JSON.stringify error - ' + error.message);
37421	        }
37422	    }
37423	    /**
37424		 * Returns ids for buffer attributes.
37425		 *
37426		 * @param  {Object} attribute
37427		 * @param {boolean} [isRelativeCopy=false]
37428		 * @return {number} An integer
37429		 */ getUID(attribute, isRelativeCopy = false) {
37430	        if (this.uids.has(attribute) === false) {
37431	            const uids = new Map();
37432	            uids.set(true, this.uid++);
37433	            uids.set(false, this.uid++);
37434	            this.uids.set(attribute, uids);
37435	        }
37436	        const uids = this.uids.get(attribute);
37437	        return uids.get(isRelativeCopy);
37438	    }
37439	    /**
37440		 * Checks if normal attribute values are normalized.
37441		 *
37442		 * @param {BufferAttribute} normal
37443		 * @returns {boolean}
37444		 */ isNormalizedNormalAttribute(normal) {
37445	        const cache = this.cache;
37446	        if (cache.attributesNormalized.has(normal)) return false;
37447	        const v = new Vector3();
37448	        for(let i = 0, il = normal.count; i < il; i++){
37449	            // 0.0005 is from glTF-validator
37450	            if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1.0) > 0.0005) return false;
37451	        }
37452	        return true;
37453	    }
37454	    /**
37455		 * Creates normalized normal buffer attribute.
37456		 *
37457		 * @param {BufferAttribute} normal
37458		 * @returns {BufferAttribute}
37459		 *
37460		 */ createNormalizedNormalAttribute(normal) {
37461	        const cache = this.cache;
37462	        if (cache.attributesNormalized.has(normal)) return cache.attributesNormalized.get(normal);
37463	        const attribute = normal.clone();
37464	        const v = new Vector3();
37465	        for(let i = 0, il = attribute.count; i < il; i++){
37466	            v.fromBufferAttribute(attribute, i);
37467	            if (v.x === 0 && v.y === 0 && v.z === 0) {
37468	                // if values can't be normalized set (1, 0, 0)
37469	                v.setX(1.0);
37470	            } else {
37471	                v.normalize();
37472	            }
37473	            attribute.setXYZ(i, v.x, v.y, v.z);
37474	        }
37475	        cache.attributesNormalized.set(normal, attribute);
37476	        return attribute;
37477	    }
37478	    /**
37479		 * Applies a texture transform, if present, to the map definition. Requires
37480		 * the KHR_texture_transform extension.
37481		 *
37482		 * @param {Object} mapDef
37483		 * @param {THREE.Texture} texture
37484		 */ applyTextureTransform(mapDef, texture) {
37485	        let didTransform = false;
vendor: 17,489 bytes, lines 37486-37860
37486	        const transformDef = {};
37487	        if (texture.offset.x !== 0 || texture.offset.y !== 0) {
37488	            transformDef.offset = texture.offset.toArray();
37489	            didTransform = true;
37490	        }
37491	        if (texture.rotation !== 0) {
37492	            transformDef.rotation = texture.rotation;
37493	            didTransform = true;
37494	        }
37495	        if (texture.repeat.x !== 1 || texture.repeat.y !== 1) {
37496	            transformDef.scale = texture.repeat.toArray();
37497	            didTransform = true;
37498	        }
37499	        if (didTransform) {
37500	            mapDef.extensions = mapDef.extensions || {};
37501	            mapDef.extensions['KHR_texture_transform'] = transformDef;
37502	            this.extensionsUsed['KHR_texture_transform'] = true;
37503	        }
37504	    }
37505	    async buildMetalRoughTextureAsync(metalnessMap, roughnessMap) {
37506	        if (metalnessMap === roughnessMap) return metalnessMap;
37507	        function getEncodingConversion(map) {
37508	            if (map.colorSpace === SRGBColorSpace) {
37509	                return function SRGBToLinear(c) {
37510	                    return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
37511	                };
37512	            }
37513	            return function LinearToLinear(c) {
37514	                return c;
37515	            };
37516	        }
37517	        if (metalnessMap instanceof CompressedTexture) {
37518	            metalnessMap = await this.decompressTextureAsync(metalnessMap);
37519	        }
37520	        if (roughnessMap instanceof CompressedTexture) {
37521	            roughnessMap = await this.decompressTextureAsync(roughnessMap);
37522	        }
37523	        const metalness = metalnessMap ? metalnessMap.image : null;
37524	        const roughness = roughnessMap ? roughnessMap.image : null;
37525	        const width = Math.max(metalness ? metalness.width : 0, roughness ? roughness.width : 0);
37526	        const height = Math.max(metalness ? metalness.height : 0, roughness ? roughness.height : 0);
37527	        const canvas = getCanvas();
37528	        canvas.width = width;
37529	        canvas.height = height;
37530	        const context = canvas.getContext('2d', {
37531	            willReadFrequently: true
37532	        });
37533	        context.fillStyle = '#00ffff';
37534	        context.fillRect(0, 0, width, height);
37535	        const composite = context.getImageData(0, 0, width, height);
37536	        if (metalness) {
37537	            context.drawImage(metalness, 0, 0, width, height);
37538	            const convert = getEncodingConversion(metalnessMap);
37539	            const data = context.getImageData(0, 0, width, height).data;
37540	            for(let i = 2; i < data.length; i += 4){
37541	                composite.data[i] = convert(data[i] / 256) * 256;
37542	            }
37543	        }
37544	        if (roughness) {
37545	            context.drawImage(roughness, 0, 0, width, height);
37546	            const convert = getEncodingConversion(roughnessMap);
37547	            const data = context.getImageData(0, 0, width, height).data;
37548	            for(let i = 1; i < data.length; i += 4){
37549	                composite.data[i] = convert(data[i] / 256) * 256;
37550	            }
37551	        }
37552	        context.putImageData(composite, 0, 0);
37553	        //
37554	        const reference = metalnessMap || roughnessMap;
37555	        const texture = reference.clone();
37556	        texture.source = new Source(canvas);
37557	        texture.colorSpace = NoColorSpace;
37558	        texture.channel = (metalnessMap || roughnessMap).channel;
37559	        if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
37560	            console.warn('THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.');
37561	        }
37562	        console.warn('THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.');
37563	        return texture;
37564	    }
37565	    async decompressTextureAsync(texture, maxTextureSize = Infinity) {
37566	        if (this.textureUtils === null) {
37567	            throw new Error('THREE.GLTFExporter: setTextureUtils() must be called to process compressed textures.');
37568	        }
37569	        return await this.textureUtils.decompress(texture, maxTextureSize);
37570	    }
37571	    /**
37572		 * Process a buffer to append to the default one.
37573		 * @param  {ArrayBuffer} buffer
37574		 * @return {0}
37575		 */ processBuffer(buffer) {
37576	        const json = this.json;
37577	        const buffers = this.buffers;
37578	        if (!json.buffers) json.buffers = [
37579	            {
37580	                byteLength: 0
37581	            }
37582	        ];
37583	        // All buffers are merged before export.
37584	        buffers.push(buffer);
37585	        return 0;
37586	    }
37587	    /**
37588		 * Process and generate a BufferView
37589		 * @param {BufferAttribute} attribute
37590		 * @param {number} componentType
37591		 * @param {number} start
37592		 * @param {number} count
37593		 * @param {?number} target Target usage of the BufferView
37594		 * @return {Object}
37595		 */ processBufferView(attribute, componentType, start, count, target) {
37596	        const json = this.json;
37597	        if (!json.bufferViews) json.bufferViews = [];
37598	        // Create a new dataview and dump the attribute's array into it
37599	        let componentSize;
37600	        switch(componentType){
37601	            case WEBGL_CONSTANTS.BYTE:
37602	            case WEBGL_CONSTANTS.UNSIGNED_BYTE:
37603	                componentSize = 1;
37604	                break;
37605	            case WEBGL_CONSTANTS.SHORT:
37606	            case WEBGL_CONSTANTS.UNSIGNED_SHORT:
37607	                componentSize = 2;
37608	                break;
37609	            default:
37610	                componentSize = 4;
37611	        }
37612	        let byteStride = attribute.itemSize * componentSize;
37613	        if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
37614	            // Each element of a vertex attribute MUST be aligned to 4-byte boundaries
37615	            // inside a bufferView
37616	            byteStride = Math.ceil(byteStride / 4) * 4;
37617	        }
37618	        const byteLength = getPaddedBufferSize(count * byteStride);
37619	        const dataView = new DataView(new ArrayBuffer(byteLength));
37620	        let offset = 0;
37621	        for(let i = start; i < start + count; i++){
37622	            for(let a = 0; a < attribute.itemSize; a++){
37623	                let value;
37624	                if (attribute.itemSize > 4) {
37625	                    // no support for interleaved data for itemSize > 4
37626	                    value = attribute.array[i * attribute.itemSize + a];
37627	                } else {
37628	                    if (a === 0) value = attribute.getX(i);
37629	                    else if (a === 1) value = attribute.getY(i);
37630	                    else if (a === 2) value = attribute.getZ(i);
37631	                    else if (a === 3) value = attribute.getW(i);
37632	                    if (attribute.normalized === true) {
37633	                        value = MathUtils.normalize(value, attribute.array);
37634	                    }
37635	                }
37636	                if (componentType === WEBGL_CONSTANTS.FLOAT) {
37637	                    dataView.setFloat32(offset, value, true);
37638	                } else if (componentType === WEBGL_CONSTANTS.INT) {
37639	                    dataView.setInt32(offset, value, true);
37640	                } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_INT) {
37641	                    dataView.setUint32(offset, value, true);
37642	                } else if (componentType === WEBGL_CONSTANTS.SHORT) {
37643	                    dataView.setInt16(offset, value, true);
37644	                } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_SHORT) {
37645	                    dataView.setUint16(offset, value, true);
37646	                } else if (componentType === WEBGL_CONSTANTS.BYTE) {
37647	                    dataView.setInt8(offset, value);
37648	                } else if (componentType === WEBGL_CONSTANTS.UNSIGNED_BYTE) {
37649	                    dataView.setUint8(offset, value);
37650	                }
37651	                offset += componentSize;
37652	            }
37653	            if (offset % byteStride !== 0) {
37654	                offset += byteStride - offset % byteStride;
37655	            }
37656	        }
37657	        const bufferViewDef = {
37658	            buffer: this.processBuffer(dataView.buffer),
37659	            byteOffset: this.byteOffset,
37660	            byteLength: byteLength
37661	        };
37662	        if (target !== undefined) bufferViewDef.target = target;
37663	        if (target === WEBGL_CONSTANTS.ARRAY_BUFFER) {
37664	            // Only define byteStride for vertex attributes.
37665	            bufferViewDef.byteStride = byteStride;
37666	        }
37667	        this.byteOffset += byteLength;
37668	        json.bufferViews.push(bufferViewDef);
37669	        // @TODO Merge bufferViews where possible.
37670	        const output = {
37671	            id: json.bufferViews.length - 1,
37672	            byteLength: 0
37673	        };
37674	        return output;
37675	    }
37676	    /**
37677		 * Process and generate a BufferView from an image Blob.
37678		 * @param {Blob} blob
37679		 * @return {Promise<number>} An integer
37680		 */ processBufferViewImage(blob) {
37681	        const writer = this;
37682	        const json = writer.json;
37683	        if (!json.bufferViews) json.bufferViews = [];
37684	        return new Promise(function(resolve) {
37685	            const reader = new FileReader();
37686	            reader.readAsArrayBuffer(blob);
37687	            reader.onloadend = function() {
37688	                const buffer = getPaddedArrayBuffer(reader.result);
37689	                const bufferViewDef = {
37690	                    buffer: writer.processBuffer(buffer),
37691	                    byteOffset: writer.byteOffset,
37692	                    byteLength: buffer.byteLength
37693	                };
37694	                writer.byteOffset += buffer.byteLength;
37695	                resolve(json.bufferViews.push(bufferViewDef) - 1);
37696	            };
37697	        });
37698	    }
37699	    /**
37700		 * Process attribute to generate an accessor
37701		 * @param {BufferAttribute} attribute Attribute to process
37702		 * @param {?BufferGeometry} geometry Geometry used for truncated draw range
37703		 * @param {number} [start=0]
37704		 * @param {number} [count=Infinity]
37705		 * @return {?number} Index of the processed accessor on the "accessors" array
37706		 */ processAccessor(attribute, geometry, start, count) {
37707	        const json = this.json;
37708	        const types = {
37709	            1: 'SCALAR',
37710	            2: 'VEC2',
37711	            3: 'VEC3',
37712	            4: 'VEC4',
37713	            9: 'MAT3',
37714	            16: 'MAT4'
37715	        };
37716	        let componentType;
37717	        // Detect the component type of the attribute array
37718	        if (attribute.array.constructor === Float32Array) {
37719	            componentType = WEBGL_CONSTANTS.FLOAT;
37720	        } else if (attribute.array.constructor === Int32Array) {
37721	            componentType = WEBGL_CONSTANTS.INT;
37722	        } else if (attribute.array.constructor === Uint32Array) {
37723	            componentType = WEBGL_CONSTANTS.UNSIGNED_INT;
37724	        } else if (attribute.array.constructor === Int16Array) {
37725	            componentType = WEBGL_CONSTANTS.SHORT;
37726	        } else if (attribute.array.constructor === Uint16Array) {
37727	            componentType = WEBGL_CONSTANTS.UNSIGNED_SHORT;
37728	        } else if (attribute.array.constructor === Int8Array) {
37729	            componentType = WEBGL_CONSTANTS.BYTE;
37730	        } else if (attribute.array.constructor === Uint8Array) {
37731	            componentType = WEBGL_CONSTANTS.UNSIGNED_BYTE;
37732	        } else {
37733	            throw new Error('THREE.GLTFExporter: Unsupported bufferAttribute component type: ' + attribute.array.constructor.name);
37734	        }
37735	        if (start === undefined) start = 0;
37736	        if (count === undefined || count === Infinity) count = attribute.count;
37737	        // Skip creating an accessor if the attribute doesn't have data to export
37738	        if (count === 0) return null;
37739	        const minMax = getMinMax(attribute, start, count);
37740	        let bufferViewTarget;
37741	        // If geometry isn't provided, don't infer the target usage of the bufferView. For
37742	        // animation samplers, target must not be set.
37743	        if (geometry !== undefined) {
37744	            bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS.ARRAY_BUFFER;
37745	        }
37746	        const bufferView = this.processBufferView(attribute, componentType, start, count, bufferViewTarget);
37747	        const accessorDef = {
37748	            bufferView: bufferView.id,
37749	            byteOffset: bufferView.byteOffset,
37750	            componentType: componentType,
37751	            count: count,
37752	            max: minMax.max,
37753	            min: minMax.min,
37754	            type: types[attribute.itemSize]
37755	        };
37756	        if (attribute.normalized === true) accessorDef.normalized = true;
37757	        if (!json.accessors) json.accessors = [];
37758	        return json.accessors.push(accessorDef) - 1;
37759	    }
37760	    /**
37761		 * Process image
37762		 * @param  {Image} image to process
37763		 * @param  {number} format Identifier of the format (RGBAFormat)
37764		 * @param  {boolean} flipY before writing out the image
37765		 * @param  {string} mimeType export format
37766		 * @return {number}     Index of the processed texture in the "images" array
37767		 */ processImage(image, format, flipY, mimeType = 'image/png') {
37768	        if (image !== null) {
37769	            const writer = this;
37770	            const cache = writer.cache;
37771	            const json = writer.json;
37772	            const options = writer.options;
37773	            const pending = writer.pending;
37774	            if (!cache.images.has(image)) cache.images.set(image, {});
37775	            const cachedImages = cache.images.get(image);
37776	            const key = mimeType + ':flipY/' + flipY.toString();
37777	            if (cachedImages[key] !== undefined) return cachedImages[key];
37778	            if (!json.images) json.images = [];
37779	            const imageDef = {
37780	                mimeType: mimeType
37781	            };
37782	            const canvas = getCanvas();
37783	            canvas.width = Math.min(image.width, options.maxTextureSize);
37784	            canvas.height = Math.min(image.height, options.maxTextureSize);
37785	            const ctx = canvas.getContext('2d', {
37786	                willReadFrequently: true
37787	            });
37788	            if (flipY === true) {
37789	                ctx.translate(0, canvas.height);
37790	                ctx.scale(1, -1);
37791	            }
37792	            if (image.data !== undefined) {
37793	                if (format !== RGBAFormat) {
37794	                    console.error('GLTFExporter: Only RGBAFormat is supported.', format);
37795	                }
37796	                if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
37797	                    console.warn('GLTFExporter: Image size is bigger than maxTextureSize', image);
37798	                }
37799	                const data = new Uint8ClampedArray(image.height * image.width * 4);
37800	                for(let i = 0; i < data.length; i += 4){
37801	                    data[i + 0] = image.data[i + 0];
37802	                    data[i + 1] = image.data[i + 1];
37803	                    data[i + 2] = image.data[i + 2];
37804	                    data[i + 3] = image.data[i + 3];
37805	                }
37806	                ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
37807	            } else {
37808	                if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas) {
37809	                    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
37810	                } else {
37811	                    throw new Error('THREE.GLTFExporter: Invalid image type. Use HTMLImageElement, HTMLCanvasElement, ImageBitmap or OffscreenCanvas.');
37812	                }
37813	            }
37814	            if (options.binary === true) {
37815	                pending.push(getToBlobPromise(canvas, mimeType).then((blob)=>writer.processBufferViewImage(blob)).then((bufferViewIndex)=>{
37816	                    imageDef.bufferView = bufferViewIndex;
37817	                }));
37818	            } else {
37819	                if (canvas.toDataURL !== undefined) {
37820	                    imageDef.uri = canvas.toDataURL(mimeType);
37821	                } else {
37822	                    pending.push(getToBlobPromise(canvas, mimeType).then((blob)=>new FileReader().readAsDataURL(blob)).then((dataURL)=>{
37823	                        imageDef.uri = dataURL;
37824	                    }));
37825	                }
37826	            }
37827	            const index = json.images.push(imageDef) - 1;
37828	            cachedImages[key] = index;
37829	            return index;
37830	        } else {
37831	            throw new Error('THREE.GLTFExporter: No valid image data found. Unable to process texture.');
37832	        }
37833	    }
37834	    /**
37835		 * Process sampler
37836		 * @param  {Texture} map Texture to process
37837		 * @return {number}      Index of the processed texture in the "samplers" array
37838		 */ processSampler(map) {
37839	        const json = this.json;
37840	        if (!json.samplers) json.samplers = [];
37841	        const samplerDef = {
37842	            magFilter: THREE_TO_WEBGL[map.magFilter],
37843	            minFilter: THREE_TO_WEBGL[map.minFilter],
37844	            wrapS: THREE_TO_WEBGL[map.wrapS],
37845	            wrapT: THREE_TO_WEBGL[map.wrapT]
37846	        };
37847	        return json.samplers.push(samplerDef) - 1;
37848	    }
37849	    /**
37850		 * Process texture
37851		 * @param  {Texture} map Map to process
37852		 * @return {Promise<number>} Index of the processed texture in the "textures" array
37853		 */ async processTextureAsync(map) {
37854	        const writer = this;
37855	        const options = writer.options;
37856	        const cache = this.cache;
37857	        const json = this.json;
37858	        if (cache.textures.has(map)) return cache.textures.get(map);
37859	        if (!json.textures) json.textures = [];
37860	        // make non-readable textures (e.g. CompressedTexture) readable by blitting them into a 
vendor: 5,024 bytes, lines 37860-37967
37860new texture
37861	        if (map instanceof CompressedTexture) {
37862	            map = await this.decompressTextureAsync(map, options.maxTextureSize);
37863	        }
37864	        let mimeType = map.userData.mimeType;
37865	        if (mimeType === 'image/webp') mimeType = 'image/png';
37866	        const textureDef = {
37867	            sampler: this.processSampler(map),
37868	            source: this.processImage(map.image, map.format, map.flipY, mimeType)
37869	        };
37870	        if (map.name) textureDef.name = map.name;
37871	        await this._invokeAllAsync(async function(ext) {
37872	            ext.writeTexture && await ext.writeTexture(map, textureDef);
37873	        });
37874	        const index = json.textures.push(textureDef) - 1;
37875	        cache.textures.set(map, index);
37876	        return index;
37877	    }
37878	    /**
37879		 * Process material
37880		 * @param  {THREE.Material} material Material to process
37881		 * @return {Promise<number|null>} Index of the processed material in the "materials" array
37882		 */ async processMaterialAsync(material) {
37883	        const cache = this.cache;
37884	        const json = this.json;
37885	        if (cache.materials.has(material)) return cache.materials.get(material);
37886	        if (material.isShaderMaterial) {
37887	            console.warn('GLTFExporter: THREE.ShaderMaterial not supported.');
37888	            return null;
37889	        }
37890	        if (!json.materials) json.materials = [];
37891	        // @QUESTION Should we avoid including any attribute that has the default value?
37892	        const materialDef = {
37893	            pbrMetallicRoughness: {}
37894	        };
37895	        if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
37896	            console.warn('GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.');
37897	        }
37898	        // pbrMetallicRoughness.baseColorFactor
37899	        const color = material.color.toArray().concat([
37900	            material.opacity
37901	        ]);
37902	        if (!equalArray(color, [
37903	            1,
37904	            1,
37905	            1,
37906	            1
37907	        ])) {
37908	            materialDef.pbrMetallicRoughness.baseColorFactor = color;
37909	        }
37910	        if (material.isMeshStandardMaterial) {
37911	            materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
37912	            materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
37913	        } else {
37914	            materialDef.pbrMetallicRoughness.metallicFactor = 0;
37915	            materialDef.pbrMetallicRoughness.roughnessFactor = 1;
37916	        }
37917	        // pbrMetallicRoughness.metallicRoughnessTexture
37918	        if (material.metalnessMap || material.roughnessMap) {
37919	            const metalRoughTexture = await this.buildMetalRoughTextureAsync(material.metalnessMap, material.roughnessMap);
37920	            const metalRoughMapDef = {
37921	                index: await this.processTextureAsync(metalRoughTexture),
37922	                texCoord: metalRoughTexture.channel
37923	            };
37924	            this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
37925	            materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
37926	        }
37927	        // pbrMetallicRoughness.baseColorTexture
37928	        if (material.map) {
37929	            const baseColorMapDef = {
37930	                index: await this.processTextureAsync(material.map),
37931	                texCoord: material.map.channel
37932	            };
37933	            this.applyTextureTransform(baseColorMapDef, material.map);
37934	            materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
37935	        }
37936	        if (material.emissive) {
37937	            const emissive = material.emissive;
37938	            const maxEmissiveComponent = Math.max(emissive.r, emissive.g, emissive.b);
37939	            if (maxEmissiveComponent > 0) {
37940	                materialDef.emissiveFactor = material.emissive.toArray();
37941	            }
37942	            // emissiveTexture
37943	            if (material.emissiveMap) {
37944	                const emissiveMapDef = {
37945	                    index: await this.processTextureAsync(material.emissiveMap),
37946	                    texCoord: material.emissiveMap.channel
37947	                };
37948	                this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
37949	                materialDef.emissiveTexture = emissiveMapDef;
37950	            }
37951	        }
37952	        // normalTexture
37953	        if (material.normalMap) {
37954	            const normalMapDef = {
37955	                index: await this.processTextureAsync(material.normalMap),
37956	                texCoord: material.normalMap.channel
37957	            };
37958	            if (material.normalScale && material.normalScale.x !== 1) {
37959	                // glTF normal scale is univariate. Ignore `y`, which may be flipped.
37960	                // Context: https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
37961	                normalMapDef.scale = material.normalScale.x;
37962	            }
37963	            this.applyTextureTransform(normalMapDef, material.normalMap);
37964	            materialDef.normalTexture = normalMapDef;
37965	        }
37966	        // occlusionTexture
37967	        if (material.aoMap) {
vendor: 4,402 bytes, lines 37968-38062
37968	            const occlusionMapDef = {
37969	                index: await this.processTextureAsync(material.aoMap),
37970	                texCoord: material.aoMap.channel
37971	            };
37972	            if (material.aoMapIntensity !== 1.0) {
37973	                occlusionMapDef.strength = material.aoMapIntensity;
37974	            }
37975	            this.applyTextureTransform(occlusionMapDef, material.aoMap);
37976	            materialDef.occlusionTexture = occlusionMapDef;
37977	        }
37978	        // alphaMode
37979	        if (material.transparent) {
37980	            materialDef.alphaMode = 'BLEND';
37981	        } else {
37982	            if (material.alphaTest > 0.0) {
37983	                materialDef.alphaMode = 'MASK';
37984	                materialDef.alphaCutoff = material.alphaTest;
37985	            }
37986	        }
37987	        // doubleSided
37988	        if (material.side === DoubleSide) materialDef.doubleSided = true;
37989	        if (material.name !== '') materialDef.name = material.name;
37990	        this.serializeUserData(material, materialDef);
37991	        await this._invokeAllAsync(async function(ext) {
37992	            ext.writeMaterialAsync && await ext.writeMaterialAsync(material, materialDef);
37993	        });
37994	        const index = json.materials.push(materialDef) - 1;
37995	        cache.materials.set(material, index);
37996	        return index;
37997	    }
37998	    /**
37999		 * Process mesh
38000		 * @param  {THREE.Mesh} mesh Mesh to process
38001		 * @return {Promise<number|null>} Index of the processed mesh in the "meshes" array
38002		 */ async processMeshAsync(mesh) {
38003	        const cache = this.cache;
38004	        const json = this.json;
38005	        const meshCacheKeyParts = [
38006	            mesh.geometry.uuid
38007	        ];
38008	        if (Array.isArray(mesh.material)) {
38009	            for(let i = 0, l = mesh.material.length; i < l; i++){
38010	                meshCacheKeyParts.push(mesh.material[i].uuid);
38011	            }
38012	        } else {
38013	            meshCacheKeyParts.push(mesh.material.uuid);
38014	        }
38015	        const meshCacheKey = meshCacheKeyParts.join(':');
38016	        if (cache.meshes.has(meshCacheKey)) return cache.meshes.get(meshCacheKey);
38017	        const geometry = mesh.geometry;
38018	        let mode;
38019	        // Use the correct mode
38020	        if (mesh.isLineSegments) {
38021	            mode = WEBGL_CONSTANTS.LINES;
38022	        } else if (mesh.isLineLoop) {
38023	            mode = WEBGL_CONSTANTS.LINE_LOOP;
38024	        } else if (mesh.isLine) {
38025	            mode = WEBGL_CONSTANTS.LINE_STRIP;
38026	        } else if (mesh.isPoints) {
38027	            mode = WEBGL_CONSTANTS.POINTS;
38028	        } else {
38029	            mode = mesh.material.wireframe ? WEBGL_CONSTANTS.LINES : WEBGL_CONSTANTS.TRIANGLES;
38030	        }
38031	        const meshDef = {};
38032	        const attributes = {};
38033	        const primitives = [];
38034	        const targets = [];
38035	        // Conversion between attributes names in threejs and gltf spec
38036	        const nameConversion = {
38037	            uv: 'TEXCOORD_0',
38038	            uv1: 'TEXCOORD_1',
38039	            uv2: 'TEXCOORD_2',
38040	            uv3: 'TEXCOORD_3',
38041	            color: 'COLOR_0',
38042	            skinWeight: 'WEIGHTS_0',
38043	            skinIndex: 'JOINTS_0'
38044	        };
38045	        const originalNormal = geometry.getAttribute('normal');
38046	        if (originalNormal !== undefined && !this.isNormalizedNormalAttribute(originalNormal)) {
38047	            console.warn('THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.');
38048	            geometry.setAttribute('normal', this.createNormalizedNormalAttribute(originalNormal));
38049	        }
38050	        // @QUESTION Detect if .vertexColors = true?
38051	        // For every attribute create an accessor
38052	        let modifiedAttribute = null;
38053	        for(let attributeName in geometry.attributes){
38054	            // Ignore morph target attributes, which are exported later.
38055	            if (attributeName.slice(0, 5) === 'morph') continue;
38056	            const attribute = geometry.attributes[attributeName];
38057	            attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
38058	            // Prefix all geometry attributes except the ones specifically
38059	            // listed in the spec; non-spec attributes are considered custom.
38060	            const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
38061	            if (!validVertexAttributes.test(attributeName)) attributeName = '_' + attributeName;
38062	            if (cache.attributes.has(this.getUID(attribute))) {
vendor: 10,387 bytes, lines 38063-38268
38063	                attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
38064	                continue;
38065	            }
38066	            // Enforce glTF vertex attribute requirements:
38067	            // - JOINTS_0 must be UNSIGNED_BYTE or UNSIGNED_SHORT
38068	            // - Only custom attributes may be INT or UNSIGNED_INT
38069	            modifiedAttribute = null;
38070	            const array = attribute.array;
38071	            if (attributeName === 'JOINTS_0' && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
38072	                console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
38073	                modifiedAttribute = new BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
38074	            } else if ((array instanceof Uint32Array || array instanceof Int32Array) && !attributeName.startsWith('_')) {
38075	                console.warn(`GLTFExporter: Attribute "${attributeName}" converted to type FLOAT.`);
38076	                modifiedAttribute = GLTFExporter.Utils.toFloat32BufferAttribute(attribute);
38077	            }
38078	            const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
38079	            if (accessor !== null) {
38080	                if (!attributeName.startsWith('_')) {
38081	                    this.detectMeshQuantization(attributeName, attribute);
38082	                }
38083	                attributes[attributeName] = accessor;
38084	                cache.attributes.set(this.getUID(attribute), accessor);
38085	            }
38086	        }
38087	        if (originalNormal !== undefined) geometry.setAttribute('normal', originalNormal);
38088	        // Skip if no exportable attributes found
38089	        if (Object.keys(attributes).length === 0) return null;
38090	        // Morph targets
38091	        if (mesh.morphTargetInfluences !== undefined && mesh.morphTargetInfluences.length > 0) {
38092	            const weights = [];
38093	            const targetNames = [];
38094	            const reverseDictionary = {};
38095	            if (mesh.morphTargetDictionary !== undefined) {
38096	                for(const key in mesh.morphTargetDictionary){
38097	                    reverseDictionary[mesh.morphTargetDictionary[key]] = key;
38098	                }
38099	            }
38100	            for(let i = 0; i < mesh.morphTargetInfluences.length; ++i){
38101	                const target = {};
38102	                let warned = false;
38103	                for(const attributeName in geometry.morphAttributes){
38104	                    // glTF 2.0 morph supports only POSITION/NORMAL/TANGENT.
38105	                    // Three.js doesn't support TANGENT yet.
38106	                    if (attributeName !== 'position' && attributeName !== 'normal') {
38107	                        if (!warned) {
38108	                            console.warn('GLTFExporter: Only POSITION and NORMAL morph are supported.');
38109	                            warned = true;
38110	                        }
38111	                        continue;
38112	                    }
38113	                    const attribute = geometry.morphAttributes[attributeName][i];
38114	                    const gltfAttributeName = attributeName.toUpperCase();
38115	                    // Three.js morph attribute has absolute values while the one of glTF has relative values.
38116	                    //
38117	                    // glTF 2.0 Specification:
38118	                    // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#morph-targets
38119	                    const baseAttribute = geometry.attributes[attributeName];
38120	                    if (cache.attributes.has(this.getUID(attribute, true))) {
38121	                        target[gltfAttributeName] = cache.attributes.get(this.getUID(attribute, true));
38122	                        continue;
38123	                    }
38124	                    // Clones attribute not to override
38125	                    const relativeAttribute = attribute.clone();
38126	                    if (!geometry.morphTargetsRelative) {
38127	                        for(let j = 0, jl = attribute.count; j < jl; j++){
38128	                            for(let a = 0; a < attribute.itemSize; a++){
38129	                                if (a === 0) relativeAttribute.setX(j, attribute.getX(j) - baseAttribute.getX(j));
38130	                                if (a === 1) relativeAttribute.setY(j, attribute.getY(j) - baseAttribute.getY(j));
38131	                                if (a === 2) relativeAttribute.setZ(j, attribute.getZ(j) - baseAttribute.getZ(j));
38132	                                if (a === 3) relativeAttribute.setW(j, attribute.getW(j) - baseAttribute.getW(j));
38133	                            }
38134	                        }
38135	                    }
38136	                    target[gltfAttributeName] = this.processAccessor(relativeAttribute, geometry);
38137	                    cache.attributes.set(this.getUID(baseAttribute, true), target[gltfAttributeName]);
38138	                }
38139	                targets.push(target);
38140	                weights.push(mesh.morphTargetInfluences[i]);
38141	                if (mesh.morphTargetDictionary !== undefined) targetNames.push(reverseDictionary[i]);
38142	            }
38143	            meshDef.weights = weights;
38144	            if (targetNames.length > 0) {
38145	                meshDef.extras = {};
38146	                meshDef.extras.targetNames = targetNames;
38147	            }
38148	        }
38149	        const isMultiMaterial = Array.isArray(mesh.material);
38150	        if (isMultiMaterial && geometry.groups.length === 0) return null;
38151	        let didForceIndices = false;
38152	        if (isMultiMaterial && geometry.index === null) {
38153	            const indices = [];
38154	            for(let i = 0, il = geometry.attributes.position.count; i < il; i++){
38155	                indices[i] = i;
38156	            }
38157	            geometry.setIndex(indices);
38158	            didForceIndices = true;
38159	        }
38160	        const materials = isMultiMaterial ? mesh.material : [
38161	            mesh.material
38162	        ];
38163	        const groups = isMultiMaterial ? geometry.groups : [
38164	            {
38165	                materialIndex: 0,
38166	                start: undefined,
38167	                count: undefined
38168	            }
38169	        ];
38170	        for(let i = 0, il = groups.length; i < il; i++){
38171	            const primitive = {
38172	                mode: mode,
38173	                attributes: attributes
38174	            };
38175	            this.serializeUserData(geometry, primitive);
38176	            if (targets.length > 0) primitive.targets = targets;
38177	            if (geometry.index !== null) {
38178	                let cacheKey = this.getUID(geometry.index);
38179	                if (groups[i].start !== undefined || groups[i].count !== undefined) {
38180	                    cacheKey += ':' + groups[i].start + ':' + groups[i].count;
38181	                }
38182	                if (cache.attributes.has(cacheKey)) {
38183	                    primitive.indices = cache.attributes.get(cacheKey);
38184	                } else {
38185	                    primitive.indices = this.processAccessor(geometry.index, geometry, groups[i].start, groups[i].count);
38186	                    cache.attributes.set(cacheKey, primitive.indices);
38187	                }
38188	                if (primitive.indices === null) delete primitive.indices;
38189	            }
38190	            const material = await this.processMaterialAsync(materials[groups[i].materialIndex]);
38191	            if (material !== null) primitive.material = material;
38192	            primitives.push(primitive);
38193	        }
38194	        if (didForceIndices === true) {
38195	            geometry.setIndex(null);
38196	        }
38197	        meshDef.primitives = primitives;
38198	        if (!json.meshes) json.meshes = [];
38199	        await this._invokeAllAsync(function(ext) {
38200	            ext.writeMesh && ext.writeMesh(mesh, meshDef);
38201	        });
38202	        const index = json.meshes.push(meshDef) - 1;
38203	        cache.meshes.set(meshCacheKey, index);
38204	        return index;
38205	    }
38206	    /**
38207		 * If a vertex attribute with a
38208		 * [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
38209		 * is used, it is checked whether it is a valid data type according to the
38210		 * [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
38211		 * extension.
38212		 * In this case the extension is automatically added to the list of used extensions.
38213		 *
38214		 * @param {string} attributeName
38215		 * @param {THREE.BufferAttribute} attribute
38216		 */ detectMeshQuantization(attributeName, attribute) {
38217	        if (this.extensionsUsed[KHR_MESH_QUANTIZATION]) return;
38218	        let attrType = undefined;
38219	        switch(attribute.array.constructor){
38220	            case Int8Array:
38221	                attrType = 'byte';
38222	                break;
38223	            case Uint8Array:
38224	                attrType = 'unsigned byte';
38225	                break;
38226	            case Int16Array:
38227	                attrType = 'short';
38228	                break;
38229	            case Uint16Array:
38230	                attrType = 'unsigned short';
38231	                break;
38232	            default:
38233	                return;
38234	        }
38235	        if (attribute.normalized) attrType += ' normalized';
38236	        const attrNamePrefix = attributeName.split('_', 1)[0];
38237	        if (KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix] && KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix].includes(attrType)) {
38238	            this.extensionsUsed[KHR_MESH_QUANTIZATION] = true;
38239	            this.extensionsRequired[KHR_MESH_QUANTIZATION] = true;
38240	        }
38241	    }
38242	    /**
38243		 * Process camera
38244		 * @param  {THREE.Camera} camera Camera to process
38245		 * @return {number} Index of the processed mesh in the "camera" array
38246		 */ processCamera(camera) {
38247	        const json = this.json;
38248	        if (!json.cameras) json.cameras = [];
38249	        const isOrtho = camera.isOrthographicCamera;
38250	        const cameraDef = {
38251	            type: isOrtho ? 'orthographic' : 'perspective'
38252	        };
38253	        if (isOrtho) {
38254	            cameraDef.orthographic = {
38255	                xmag: camera.right * 2,
38256	                ymag: camera.top * 2,
38257	                zfar: camera.far <= 0 ? 0.001 : camera.far,
38258	                znear: camera.near < 0 ? 0 : camera.near
38259	            };
38260	        } else {
38261	            cameraDef.perspective = {
38262	                aspectRatio: camera.aspect,
38263	                yfov: MathUtils.degToRad(camera.fov),
38264	                zfar: camera.far <= 0 ? 0.001 : camera.far,
38265	                znear: camera.near < 0 ? 0 : camera.near
38266	            };
38267	        }
38268	        // Question: Is saving "type" as name intentional?
vendor: 16,384 bytes, lines 38269-38659
38269	        if (camera.name !== '') cameraDef.name = camera.type;
38270	        return json.cameras.push(cameraDef) - 1;
38271	    }
38272	    /**
38273		 * Creates glTF animation entry from AnimationClip object.
38274		 *
38275		 * Status:
38276		 * - Only properties listed in PATH_PROPERTIES may be animated.
38277		 *
38278		 * @param {THREE.AnimationClip} clip
38279		 * @param {THREE.Object3D} root
38280		 * @return {number|null}
38281		 */ processAnimation(clip, root) {
38282	        const json = this.json;
38283	        const nodeMap = this.nodeMap;
38284	        if (!json.animations) json.animations = [];
38285	        clip = GLTFExporter.Utils.mergeMorphTargetTracks(clip.clone(), root);
38286	        const tracks = clip.tracks;
38287	        const channels = [];
38288	        const samplers = [];
38289	        for(let i = 0; i < tracks.length; ++i){
38290	            const track = tracks[i];
38291	            const trackBinding = PropertyBinding.parseTrackName(track.name);
38292	            let trackNode = PropertyBinding.findNode(root, trackBinding.nodeName);
38293	            const trackProperty = PATH_PROPERTIES[trackBinding.propertyName];
38294	            if (trackBinding.objectName === 'bones') {
38295	                if (trackNode.isSkinnedMesh === true) {
38296	                    trackNode = trackNode.skeleton.getBoneByName(trackBinding.objectIndex);
38297	                } else {
38298	                    trackNode = undefined;
38299	                }
38300	            }
38301	            if (!trackNode || !trackProperty) {
38302	                console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
38303	                continue;
38304	            }
38305	            const inputItemSize = 1;
38306	            let outputItemSize = track.values.length / track.times.length;
38307	            if (trackProperty === PATH_PROPERTIES.morphTargetInfluences) {
38308	                outputItemSize /= trackNode.morphTargetInfluences.length;
38309	            }
38310	            let interpolation;
38311	            // @TODO export CubicInterpolant(InterpolateSmooth) as CUBICSPLINE
38312	            // Detecting glTF cubic spline interpolant by checking factory method's special property
38313	            // GLTFCubicSplineInterpolant is a custom interpolant and track doesn't return
38314	            // valid value from .getInterpolation().
38315	            if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
38316	                interpolation = 'CUBICSPLINE';
38317	                // itemSize of CUBICSPLINE keyframe is 9
38318	                // (VEC3 * 3: inTangent, splineVertex, and outTangent)
38319	                // but needs to be stored as VEC3 so dividing by 3 here.
38320	                outputItemSize /= 3;
38321	            } else if (track.getInterpolation() === InterpolateDiscrete) {
38322	                interpolation = 'STEP';
38323	            } else {
38324	                interpolation = 'LINEAR';
38325	            }
38326	            samplers.push({
38327	                input: this.processAccessor(new BufferAttribute(track.times, inputItemSize)),
38328	                output: this.processAccessor(new BufferAttribute(track.values, outputItemSize)),
38329	                interpolation: interpolation
38330	            });
38331	            channels.push({
38332	                sampler: samplers.length - 1,
38333	                target: {
38334	                    node: nodeMap.get(trackNode),
38335	                    path: trackProperty
38336	                }
38337	            });
38338	        }
38339	        json.animations.push({
38340	            name: clip.name || 'clip_' + json.animations.length,
38341	            samplers: samplers,
38342	            channels: channels
38343	        });
38344	        return json.animations.length - 1;
38345	    }
38346	    /**
38347		 * @param {THREE.Object3D} object
38348		 * @return {number|null}
38349		 */ processSkin(object) {
38350	        const json = this.json;
38351	        const nodeMap = this.nodeMap;
38352	        const node = json.nodes[nodeMap.get(object)];
38353	        const skeleton = object.skeleton;
38354	        if (skeleton === undefined) return null;
38355	        const rootJoint = object.skeleton.bones[0];
38356	        if (rootJoint === undefined) return null;
38357	        const joints = [];
38358	        const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
38359	        const temporaryBoneInverse = new Matrix4();
38360	        for(let i = 0; i < skeleton.bones.length; ++i){
38361	            joints.push(nodeMap.get(skeleton.bones[i]));
38362	            temporaryBoneInverse.copy(skeleton.boneInverses[i]);
38363	            temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
38364	        }
38365	        if (json.skins === undefined) json.skins = [];
38366	        json.skins.push({
38367	            inverseBindMatrices: this.processAccessor(new BufferAttribute(inverseBindMatrices, 16)),
38368	            joints: joints,
38369	            skeleton: nodeMap.get(rootJoint)
38370	        });
38371	        const skinIndex = node.skin = json.skins.length - 1;
38372	        return skinIndex;
38373	    }
38374	    /**
38375		 * Process Object3D node
38376		 * @param  {THREE.Object3D} object Object3D to processNodeAsync
38377		 * @return {Promise<number>} Index of the node in the nodes list
38378		 */ async processNodeAsync(object) {
38379	        const json = this.json;
38380	        const options = this.options;
38381	        const nodeMap = this.nodeMap;
38382	        if (!json.nodes) json.nodes = [];
38383	        const nodeDef = {};
38384	        if (options.trs) {
38385	            const rotation = object.quaternion.toArray();
38386	            const position = object.position.toArray();
38387	            const scale = object.scale.toArray();
38388	            if (!equalArray(rotation, [
38389	                0,
38390	                0,
38391	                0,
38392	                1
38393	            ])) {
38394	                nodeDef.rotation = rotation;
38395	            }
38396	            if (!equalArray(position, [
38397	                0,
38398	                0,
38399	                0
38400	            ])) {
38401	                nodeDef.translation = position;
38402	            }
38403	            if (!equalArray(scale, [
38404	                1,
38405	                1,
38406	                1
38407	            ])) {
38408	                nodeDef.scale = scale;
38409	            }
38410	        } else {
38411	            if (object.matrixAutoUpdate) {
38412	                object.updateMatrix();
38413	            }
38414	            if (isIdentityMatrix(object.matrix) === false) {
38415	                nodeDef.matrix = object.matrix.elements;
38416	            }
38417	        }
38418	        // We don't export empty strings name because it represents no-name in Three.js.
38419	        if (object.name !== '') nodeDef.name = String(object.name);
38420	        this.serializeUserData(object, nodeDef);
38421	        if (object.isMesh || object.isLine || object.isPoints) {
38422	            const meshIndex = await this.processMeshAsync(object);
38423	            if (meshIndex !== null) nodeDef.mesh = meshIndex;
38424	        } else if (object.isCamera) {
38425	            nodeDef.camera = this.processCamera(object);
38426	        }
38427	        if (object.isSkinnedMesh) this.skins.push(object);
38428	        if (object.children.length > 0) {
38429	            const children = [];
38430	            for(let i = 0, l = object.children.length; i < l; i++){
38431	                const child = object.children[i];
38432	                if (child.visible || options.onlyVisible === false) {
38433	                    const nodeIndex = await this.processNodeAsync(child);
38434	                    if (nodeIndex !== null) children.push(nodeIndex);
38435	                }
38436	            }
38437	            if (children.length > 0) nodeDef.children = children;
38438	        }
38439	        await this._invokeAllAsync(function(ext) {
38440	            ext.writeNode && ext.writeNode(object, nodeDef);
38441	        });
38442	        const nodeIndex = json.nodes.push(nodeDef) - 1;
38443	        nodeMap.set(object, nodeIndex);
38444	        return nodeIndex;
38445	    }
38446	    /**
38447		 * Process Scene
38448		 * @param  {Scene} scene Scene to process
38449		 */ async processSceneAsync(scene) {
38450	        const json = this.json;
38451	        const options = this.options;
38452	        if (!json.scenes) {
38453	            json.scenes = [];
38454	            json.scene = 0;
38455	        }
38456	        const sceneDef = {};
38457	        if (scene.name !== '') sceneDef.name = scene.name;
38458	        json.scenes.push(sceneDef);
38459	        const nodes = [];
38460	        for(let i = 0, l = scene.children.length; i < l; i++){
38461	            const child = scene.children[i];
38462	            if (child.visible || options.onlyVisible === false) {
38463	                const nodeIndex = await this.processNodeAsync(child);
38464	                if (nodeIndex !== null) nodes.push(nodeIndex);
38465	            }
38466	        }
38467	        if (nodes.length > 0) sceneDef.nodes = nodes;
38468	        this.serializeUserData(scene, sceneDef);
38469	    }
38470	    /**
38471		 * Creates a Scene to hold a list of objects and parse it
38472		 * @param  {Array<THREE.Object3D>} objects List of objects to process
38473		 */ async processObjectsAsync(objects) {
38474	        const scene = new Scene();
38475	        scene.name = 'AuxScene';
38476	        for(let i = 0; i < objects.length; i++){
38477	            // We push directly to children instead of calling `add` to prevent
38478	            // modify the .parent and break its original scene and hierarchy
38479	            scene.children.push(objects[i]);
38480	        }
38481	        await this.processSceneAsync(scene);
38482	    }
38483	    /**
38484		 * @param {THREE.Object3D|Array<THREE.Object3D>} input
38485		 */ async processInputAsync(input) {
38486	        const options = this.options;
38487	        input = input instanceof Array ? input : [
38488	            input
38489	        ];
38490	        await this._invokeAllAsync(function(ext) {
38491	            ext.beforeParse && ext.beforeParse(input);
38492	        });
38493	        const objectsWithoutScene = [];
38494	        for(let i = 0; i < input.length; i++){
38495	            if (input[i] instanceof Scene) {
38496	                await this.processSceneAsync(input[i]);
38497	            } else {
38498	                objectsWithoutScene.push(input[i]);
38499	            }
38500	        }
38501	        if (objectsWithoutScene.length > 0) {
38502	            await this.processObjectsAsync(objectsWithoutScene);
38503	        }
38504	        for(let i = 0; i < this.skins.length; ++i){
38505	            this.processSkin(this.skins[i]);
38506	        }
38507	        for(let i = 0; i < options.animations.length; ++i){
38508	            this.processAnimation(options.animations[i], input[0]);
38509	        }
38510	        await this._invokeAllAsync(function(ext) {
38511	            ext.afterParse && ext.afterParse(input);
38512	        });
38513	    }
38514	    async _invokeAllAsync(func) {
38515	        for(let i = 0, il = this.plugins.length; i < il; i++){
38516	            await func(this.plugins[i]);
38517	        }
38518	    }
38519	    constructor(){
38520	        this.plugins = [];
38521	        this.options = {};
38522	        this.pending = [];
38523	        this.buffers = [];
38524	        this.byteOffset = 0;
38525	        this.buffers = [];
38526	        this.nodeMap = new Map();
38527	        this.skins = [];
38528	        this.extensionsUsed = {};
38529	        this.extensionsRequired = {};
38530	        this.uids = new Map();
38531	        this.uid = 0;
38532	        this.json = {
38533	            asset: {
38534	                version: '2.0',
38535	                generator: 'THREE.GLTFExporter r' + REVISION
38536	            }
38537	        };
38538	        this.cache = {
38539	            meshes: new Map(),
38540	            attributes: new Map(),
38541	            attributesNormalized: new Map(),
38542	            materials: new Map(),
38543	            textures: new Map(),
38544	            images: new Map()
38545	        };
38546	        this.textureUtils = null;
38547	    }
38548	}
38549	/**
38550	 * Punctual Lights Extension
38551	 *
38552	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
38553	 */ class GLTFLightExtension {
38554	    writeNode(light, nodeDef) {
38555	        if (!light.isLight) return;
38556	        if (!light.isDirectionalLight && !light.isPointLight && !light.isSpotLight) {
38557	            console.warn('THREE.GLTFExporter: Only directional, point, and spot lights are supported.', light);
38558	            return;
38559	        }
38560	        const writer = this.writer;
38561	        const json = writer.json;
38562	        const extensionsUsed = writer.extensionsUsed;
38563	        const lightDef = {};
38564	        if (light.name) lightDef.name = light.name;
38565	        lightDef.color = light.color.toArray();
38566	        lightDef.intensity = light.intensity;
38567	        if (light.isDirectionalLight) {
38568	            lightDef.type = 'directional';
38569	        } else if (light.isPointLight) {
38570	            lightDef.type = 'point';
38571	            if (light.distance > 0) lightDef.range = light.distance;
38572	        } else if (light.isSpotLight) {
38573	            lightDef.type = 'spot';
38574	            if (light.distance > 0) lightDef.range = light.distance;
38575	            lightDef.spot = {};
38576	            lightDef.spot.innerConeAngle = (1.0 - light.penumbra) * light.angle;
38577	            lightDef.spot.outerConeAngle = light.angle;
38578	        }
38579	        if (light.decay !== undefined && light.decay !== 2) {
38580	            console.warn('THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, ' + 'and expects light.decay=2.');
38581	        }
38582	        if (light.target && (light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== -1)) {
38583	            console.warn('THREE.GLTFExporter: Light direction may be lost. For best results, ' + 'make light.target a child of the light with position 0,0,-1.');
38584	        }
38585	        if (!extensionsUsed[this.name]) {
38586	            json.extensions = json.extensions || {};
38587	            json.extensions[this.name] = {
38588	                lights: []
38589	            };
38590	            extensionsUsed[this.name] = true;
38591	        }
38592	        const lights = json.extensions[this.name].lights;
38593	        lights.push(lightDef);
38594	        nodeDef.extensions = nodeDef.extensions || {};
38595	        nodeDef.extensions[this.name] = {
38596	            light: lights.length - 1
38597	        };
38598	    }
38599	    constructor(writer){
38600	        this.writer = writer;
38601	        this.name = 'KHR_lights_punctual';
38602	    }
38603	}
38604	/**
38605	 * Unlit Materials Extension
38606	 *
38607	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
38608	 */ class GLTFMaterialsUnlitExtension {
38609	    async writeMaterialAsync(material, materialDef) {
38610	        if (!material.isMeshBasicMaterial) return;
38611	        const writer = this.writer;
38612	        const extensionsUsed = writer.extensionsUsed;
38613	        materialDef.extensions = materialDef.extensions || {};
38614	        materialDef.extensions[this.name] = {};
38615	        extensionsUsed[this.name] = true;
38616	        materialDef.pbrMetallicRoughness.metallicFactor = 0.0;
38617	        materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
38618	    }
38619	    constructor(writer){
38620	        this.writer = writer;
38621	        this.name = 'KHR_materials_unlit';
38622	    }
38623	}
38624	/**
38625	 * Clearcoat Materials Extension
38626	 *
38627	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
38628	 */ class GLTFMaterialsClearcoatExtension {
38629	    async writeMaterialAsync(material, materialDef) {
38630	        if (!material.isMeshPhysicalMaterial || material.clearcoat === 0) return;
38631	        const writer = this.writer;
38632	        const extensionsUsed = writer.extensionsUsed;
38633	        const extensionDef = {};
38634	        extensionDef.clearcoatFactor = material.clearcoat;
38635	        if (material.clearcoatMap) {
38636	            const clearcoatMapDef = {
38637	                index: await writer.processTextureAsync(material.clearcoatMap),
38638	                texCoord: material.clearcoatMap.channel
38639	            };
38640	            writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
38641	            extensionDef.clearcoatTexture = clearcoatMapDef;
38642	        }
38643	        extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
38644	        if (material.clearcoatRoughnessMap) {
38645	            const clearcoatRoughnessMapDef = {
38646	                index: await writer.processTextureAsync(material.clearcoatRoughnessMap),
38647	                texCoord: material.clearcoatRoughnessMap.channel
38648	            };
38649	            writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
38650	            extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
38651	        }
38652	        if (material.clearcoatNormalMap) {
38653	            const clearcoatNormalMapDef = {
38654	                index: await writer.processTextureAsync(material.clearcoatNormalMap),
38655	                texCoord: material.clearcoatNormalMap.channel
38656	            };
38657	            if (material.clearcoatNormalScale.x !== 1) clearcoatNormalMapDef.scale = material.clearcoatNormalScale.x;
38658	            writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
38659	            extensionDef.cl
vendor: 10,643 bytes, lines 38659-38893
38659earcoatNormalTexture = clearcoatNormalMapDef;
38660	        }
38661	        materialDef.extensions = materialDef.extensions || {};
38662	        materialDef.extensions[this.name] = extensionDef;
38663	        extensionsUsed[this.name] = true;
38664	    }
38665	    constructor(writer){
38666	        this.writer = writer;
38667	        this.name = 'KHR_materials_clearcoat';
38668	    }
38669	}
38670	/**
38671	 * Materials dispersion Extension
38672	 *
38673	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_dispersion
38674	 */ class GLTFMaterialsDispersionExtension {
38675	    async writeMaterialAsync(material, materialDef) {
38676	        if (!material.isMeshPhysicalMaterial || material.dispersion === 0) return;
38677	        const writer = this.writer;
38678	        const extensionsUsed = writer.extensionsUsed;
38679	        const extensionDef = {};
38680	        extensionDef.dispersion = material.dispersion;
38681	        materialDef.extensions = materialDef.extensions || {};
38682	        materialDef.extensions[this.name] = extensionDef;
38683	        extensionsUsed[this.name] = true;
38684	    }
38685	    constructor(writer){
38686	        this.writer = writer;
38687	        this.name = 'KHR_materials_dispersion';
38688	    }
38689	}
38690	/**
38691	 * Iridescence Materials Extension
38692	 *
38693	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
38694	 */ class GLTFMaterialsIridescenceExtension {
38695	    async writeMaterialAsync(material, materialDef) {
38696	        if (!material.isMeshPhysicalMaterial || material.iridescence === 0) return;
38697	        const writer = this.writer;
38698	        const extensionsUsed = writer.extensionsUsed;
38699	        const extensionDef = {};
38700	        extensionDef.iridescenceFactor = material.iridescence;
38701	        if (material.iridescenceMap) {
38702	            const iridescenceMapDef = {
38703	                index: await writer.processTextureAsync(material.iridescenceMap),
38704	                texCoord: material.iridescenceMap.channel
38705	            };
38706	            writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
38707	            extensionDef.iridescenceTexture = iridescenceMapDef;
38708	        }
38709	        extensionDef.iridescenceIor = material.iridescenceIOR;
38710	        extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[0];
38711	        extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
38712	        if (material.iridescenceThicknessMap) {
38713	            const iridescenceThicknessMapDef = {
38714	                index: await writer.processTextureAsync(material.iridescenceThicknessMap),
38715	                texCoord: material.iridescenceThicknessMap.channel
38716	            };
38717	            writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
38718	            extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
38719	        }
38720	        materialDef.extensions = materialDef.extensions || {};
38721	        materialDef.extensions[this.name] = extensionDef;
38722	        extensionsUsed[this.name] = true;
38723	    }
38724	    constructor(writer){
38725	        this.writer = writer;
38726	        this.name = 'KHR_materials_iridescence';
38727	    }
38728	}
38729	/**
38730	 * Transmission Materials Extension
38731	 *
38732	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
38733	 */ class GLTFMaterialsTransmissionExtension {
38734	    async writeMaterialAsync(material, materialDef) {
38735	        if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
38736	        const writer = this.writer;
38737	        const extensionsUsed = writer.extensionsUsed;
38738	        const extensionDef = {};
38739	        extensionDef.transmissionFactor = material.transmission;
38740	        if (material.transmissionMap) {
38741	            const transmissionMapDef = {
38742	                index: await writer.processTextureAsync(material.transmissionMap),
38743	                texCoord: material.transmissionMap.channel
38744	            };
38745	            writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
38746	            extensionDef.transmissionTexture = transmissionMapDef;
38747	        }
38748	        materialDef.extensions = materialDef.extensions || {};
38749	        materialDef.extensions[this.name] = extensionDef;
38750	        extensionsUsed[this.name] = true;
38751	    }
38752	    constructor(writer){
38753	        this.writer = writer;
38754	        this.name = 'KHR_materials_transmission';
38755	    }
38756	}
38757	/**
38758	 * Materials Volume Extension
38759	 *
38760	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
38761	 */ class GLTFMaterialsVolumeExtension {
38762	    async writeMaterialAsync(material, materialDef) {
38763	        if (!material.isMeshPhysicalMaterial || material.transmission === 0) return;
38764	        const writer = this.writer;
38765	        const extensionsUsed = writer.extensionsUsed;
38766	        const extensionDef = {};
38767	        extensionDef.thicknessFactor = material.thickness;
38768	        if (material.thicknessMap) {
38769	            const thicknessMapDef = {
38770	                index: await writer.processTextureAsync(material.thicknessMap),
38771	                texCoord: material.thicknessMap.channel
38772	            };
38773	            writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
38774	            extensionDef.thicknessTexture = thicknessMapDef;
38775	        }
38776	        if (material.attenuationDistance !== Infinity) {
38777	            extensionDef.attenuationDistance = material.attenuationDistance;
38778	        }
38779	        extensionDef.attenuationColor = material.attenuationColor.toArray();
38780	        materialDef.extensions = materialDef.extensions || {};
38781	        materialDef.extensions[this.name] = extensionDef;
38782	        extensionsUsed[this.name] = true;
38783	    }
38784	    constructor(writer){
38785	        this.writer = writer;
38786	        this.name = 'KHR_materials_volume';
38787	    }
38788	}
38789	/**
38790	 * Materials ior Extension
38791	 *
38792	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
38793	 */ class GLTFMaterialsIorExtension {
38794	    async writeMaterialAsync(material, materialDef) {
38795	        if (!material.isMeshPhysicalMaterial || material.ior === 1.5) return;
38796	        const writer = this.writer;
38797	        const extensionsUsed = writer.extensionsUsed;
38798	        const extensionDef = {};
38799	        extensionDef.ior = material.ior;
38800	        materialDef.extensions = materialDef.extensions || {};
38801	        materialDef.extensions[this.name] = extensionDef;
38802	        extensionsUsed[this.name] = true;
38803	    }
38804	    constructor(writer){
38805	        this.writer = writer;
38806	        this.name = 'KHR_materials_ior';
38807	    }
38808	}
38809	/**
38810	 * Materials specular Extension
38811	 *
38812	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
38813	 */ class GLTFMaterialsSpecularExtension {
38814	    async writeMaterialAsync(material, materialDef) {
38815	        if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1.0 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorMap) return;
38816	        const writer = this.writer;
38817	        const extensionsUsed = writer.extensionsUsed;
38818	        const extensionDef = {};
38819	        if (material.specularIntensityMap) {
38820	            const specularIntensityMapDef = {
38821	                index: await writer.processTextureAsync(material.specularIntensityMap),
38822	                texCoord: material.specularIntensityMap.channel
38823	            };
38824	            writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
38825	            extensionDef.specularTexture = specularIntensityMapDef;
38826	        }
38827	        if (material.specularColorMap) {
38828	            const specularColorMapDef = {
38829	                index: await writer.processTextureAsync(material.specularColorMap),
38830	                texCoord: material.specularColorMap.channel
38831	            };
38832	            writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
38833	            extensionDef.specularColorTexture = specularColorMapDef;
38834	        }
38835	        extensionDef.specularFactor = material.specularIntensity;
38836	        extensionDef.specularColorFactor = material.specularColor.toArray();
38837	        materialDef.extensions = materialDef.extensions || {};
38838	        materialDef.extensions[this.name] = extensionDef;
38839	        extensionsUsed[this.name] = true;
38840	    }
38841	    constructor(writer){
38842	        this.writer = writer;
38843	        this.name = 'KHR_materials_specular';
38844	    }
38845	}
38846	/**
38847	 * Sheen Materials Extension
38848	 *
38849	 * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
38850	 */ class GLTFMaterialsSheenExtension {
38851	    async writeMaterialAsync(material, materialDef) {
38852	        if (!material.isMeshPhysicalMaterial || material.sheen == 0.0) return;
38853	        const writer = this.writer;
38854	        const extensionsUsed = writer.extensionsUsed;
38855	        const extensionDef = {};
38856	        if (material.sheenRoughnessMap) {
38857	            const sheenRoughnessMapDef = {
38858	                index: await writer.processTextureAsync(material.sheenRoughnessMap),
38859	                texCoord: material.sheenRoughnessMap.channel
38860	            };
38861	            writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
38862	            extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
38863	        }
38864	        if (material.sheenColorMap) {
38865	            const sheenColorMapDef = {
38866	                index: await writer.processTextureAsync(material.sheenColorMap),
38867	                texCoord: material.sheenColorMap.channel
38868	            };
38869	            writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
38870	            extensionDef.sheenColorTexture = sheenColorMapDef;
38871	        }
38872	        extensionDef.sheenRoughnessFactor = material.sheenRoughness;
38873	        extensionDef.sheenColorFactor = material.sheenColor.toArray();
38874	        materialDef.extensions = materialDef.extensions || {};
38875	        materialDef.extensions[this.name] = extensionDef;
38876	        extensionsUsed[this.name] = true;
38877	    }
38878	    constructor(writer){
38879	        this.writer = writer;
38880	        this.name = 'KHR_materials_sheen';
38881	    }
38882	}
38883	/**
38884	 * Anisotropy Materials Extension
38885	 *
38886	 * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_anisotropy
38887	 */ class GLTFMaterialsAnisotropyExtension {
38888	    async writeMaterialAsync(material, materialDef) {
38889	        if (!material.isMeshPhysicalMaterial || material.anisotropy == 0.0) return;
38890	        const writer = this.writer;
38891	        const extensionsUsed = writer.extensionsUsed;
38892	        const extensionDef = {};
38893	        if (material.anisotropyMap) {
vendor: 19,972 bytes, lines 38894-39316
38894	            const anisotropyMapDef = {
38895	                index: await writer.processTextureAsync(material.anisotropyMap)
38896	            };
38897	            writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
38898	            extensionDef.anisotropyTexture = anisotropyMapDef;
38899	        }
38900	        extensionDef.anisotropyStrength = material.anisotropy;
38901	        extensionDef.anisotropyRotation = material.anisotropyRotation;
38902	        materialDef.extensions = materialDef.extensions || {};
38903	        materialDef.extensions[this.name] = extensionDef;
38904	        extensionsUsed[this.name] = true;
38905	    }
38906	    constructor(writer){
38907	        this.writer = writer;
38908	        this.name = 'KHR_materials_anisotropy';
38909	    }
38910	}
38911	/**
38912	 * Materials Emissive Strength Extension
38913	 *
38914	 * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
38915	 */ class GLTFMaterialsEmissiveStrengthExtension {
38916	    async writeMaterialAsync(material, materialDef) {
38917	        if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1.0) return;
38918	        const writer = this.writer;
38919	        const extensionsUsed = writer.extensionsUsed;
38920	        const extensionDef = {};
38921	        extensionDef.emissiveStrength = material.emissiveIntensity;
38922	        materialDef.extensions = materialDef.extensions || {};
38923	        materialDef.extensions[this.name] = extensionDef;
38924	        extensionsUsed[this.name] = true;
38925	    }
38926	    constructor(writer){
38927	        this.writer = writer;
38928	        this.name = 'KHR_materials_emissive_strength';
38929	    }
38930	}
38931	/**
38932	 * Materials bump Extension
38933	 *
38934	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/EXT_materials_bump
38935	 */ class GLTFMaterialsBumpExtension {
38936	    async writeMaterialAsync(material, materialDef) {
38937	        if (!material.isMeshStandardMaterial || material.bumpScale === 1 && !material.bumpMap) return;
38938	        const writer = this.writer;
38939	        const extensionsUsed = writer.extensionsUsed;
38940	        const extensionDef = {};
38941	        if (material.bumpMap) {
38942	            const bumpMapDef = {
38943	                index: await writer.processTextureAsync(material.bumpMap),
38944	                texCoord: material.bumpMap.channel
38945	            };
38946	            writer.applyTextureTransform(bumpMapDef, material.bumpMap);
38947	            extensionDef.bumpTexture = bumpMapDef;
38948	        }
38949	        extensionDef.bumpFactor = material.bumpScale;
38950	        materialDef.extensions = materialDef.extensions || {};
38951	        materialDef.extensions[this.name] = extensionDef;
38952	        extensionsUsed[this.name] = true;
38953	    }
38954	    constructor(writer){
38955	        this.writer = writer;
38956	        this.name = 'EXT_materials_bump';
38957	    }
38958	}
38959	/**
38960	 * GPU Instancing Extension
38961	 *
38962	 * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_mesh_gpu_instancing
38963	 */ class GLTFMeshGpuInstancing {
38964	    writeNode(object, nodeDef) {
38965	        if (!object.isInstancedMesh) return;
38966	        const writer = this.writer;
38967	        const mesh = object;
38968	        const translationAttr = new Float32Array(mesh.count * 3);
38969	        const rotationAttr = new Float32Array(mesh.count * 4);
38970	        const scaleAttr = new Float32Array(mesh.count * 3);
38971	        const matrix = new Matrix4();
38972	        const position = new Vector3();
38973	        const quaternion = new Quaternion();
38974	        const scale = new Vector3();
38975	        for(let i = 0; i < mesh.count; i++){
38976	            mesh.getMatrixAt(i, matrix);
38977	            matrix.decompose(position, quaternion, scale);
38978	            position.toArray(translationAttr, i * 3);
38979	            quaternion.toArray(rotationAttr, i * 4);
38980	            scale.toArray(scaleAttr, i * 3);
38981	        }
38982	        const attributes = {
38983	            TRANSLATION: writer.processAccessor(new BufferAttribute(translationAttr, 3)),
38984	            ROTATION: writer.processAccessor(new BufferAttribute(rotationAttr, 4)),
38985	            SCALE: writer.processAccessor(new BufferAttribute(scaleAttr, 3))
38986	        };
38987	        if (mesh.instanceColor) attributes._COLOR_0 = writer.processAccessor(mesh.instanceColor);
38988	        nodeDef.extensions = nodeDef.extensions || {};
38989	        nodeDef.extensions[this.name] = {
38990	            attributes
38991	        };
38992	        writer.extensionsUsed[this.name] = true;
38993	        writer.extensionsRequired[this.name] = true;
38994	    }
38995	    constructor(writer){
38996	        this.writer = writer;
38997	        this.name = 'EXT_mesh_gpu_instancing';
38998	    }
38999	}
39000	/**
39001	 * Static utility functions
39002	 */ GLTFExporter.Utils = {
39003	    insertKeyframe: function(track, time) {
39004	        const tolerance = 0.001; // 1ms
39005	        const valueSize = track.getValueSize();
39006	        const times = new track.TimeBufferType(track.times.length + 1);
39007	        const values = new track.ValueBufferType(track.values.length + valueSize);
39008	        const interpolant = track.createInterpolant(new track.ValueBufferType(valueSize));
39009	        let index;
39010	        if (track.times.length === 0) {
39011	            times[0] = time;
39012	            for(let i = 0; i < valueSize; i++){
39013	                values[i] = 0;
39014	            }
39015	            index = 0;
39016	        } else if (time < track.times[0]) {
39017	            if (Math.abs(track.times[0] - time) < tolerance) return 0;
39018	            times[0] = time;
39019	            times.set(track.times, 1);
39020	            values.set(interpolant.evaluate(time), 0);
39021	            values.set(track.values, valueSize);
39022	            index = 0;
39023	        } else if (time > track.times[track.times.length - 1]) {
39024	            if (Math.abs(track.times[track.times.length - 1] - time) < tolerance) {
39025	                return track.times.length - 1;
39026	            }
39027	            times[times.length - 1] = time;
39028	            times.set(track.times, 0);
39029	            values.set(track.values, 0);
39030	            values.set(interpolant.evaluate(time), track.values.length);
39031	            index = times.length - 1;
39032	        } else {
39033	            for(let i = 0; i < track.times.length; i++){
39034	                if (Math.abs(track.times[i] - time) < tolerance) return i;
39035	                if (track.times[i] < time && track.times[i + 1] > time) {
39036	                    times.set(track.times.slice(0, i + 1), 0);
39037	                    times[i + 1] = time;
39038	                    times.set(track.times.slice(i + 1), i + 2);
39039	                    values.set(track.values.slice(0, (i + 1) * valueSize), 0);
39040	                    values.set(interpolant.evaluate(time), (i + 1) * valueSize);
39041	                    values.set(track.values.slice((i + 1) * valueSize), (i + 2) * valueSize);
39042	                    index = i + 1;
39043	                    break;
39044	                }
39045	            }
39046	        }
39047	        track.times = times;
39048	        track.values = values;
39049	        return index;
39050	    },
39051	    mergeMorphTargetTracks: function(clip, root) {
39052	        const tracks = [];
39053	        const mergedTracks = {};
39054	        const sourceTracks = clip.tracks;
39055	        for(let i = 0; i < sourceTracks.length; ++i){
39056	            let sourceTrack = sourceTracks[i];
39057	            const sourceTrackBinding = PropertyBinding.parseTrackName(sourceTrack.name);
39058	            const sourceTrackNode = PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
39059	            if (sourceTrackBinding.propertyName !== 'morphTargetInfluences' || sourceTrackBinding.propertyIndex === undefined) {
39060	                // Tracks that don't affect morph targets, or that affect all morph targets together, can be left as-is.
39061	                tracks.push(sourceTrack);
39062	                continue;
39063	            }
39064	            if (sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear) {
39065	                if (sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
39066	                    // This should never happen, because glTF morph target animations
39067	                    // affect all targets already.
39068	                    throw new Error('THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.');
39069	                }
39070	                console.warn('THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.');
39071	                sourceTrack = sourceTrack.clone();
39072	                sourceTrack.setInterpolation(InterpolateLinear);
39073	            }
39074	            const targetCount = sourceTrackNode.morphTargetInfluences.length;
39075	            const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
39076	            if (targetIndex === undefined) {
39077	                throw new Error('THREE.GLTFExporter: Morph target name not found: ' + sourceTrackBinding.propertyIndex);
39078	            }
39079	            let mergedTrack;
39080	            // If this is the first time we've seen this object, create a new
39081	            // track to store merged keyframe data for each morph target.
39082	            if (mergedTracks[sourceTrackNode.uuid] === undefined) {
39083	                mergedTrack = sourceTrack.clone();
39084	                const values = new mergedTrack.ValueBufferType(targetCount * mergedTrack.times.length);
39085	                for(let j = 0; j < mergedTrack.times.length; j++){
39086	                    values[j * targetCount + targetIndex] = mergedTrack.values[j];
39087	                }
39088	                // We need to take into consideration the intended target node
39089	                // of our original un-merged morphTarget animation.
39090	                mergedTrack.name = (sourceTrackBinding.nodeName || '') + '.morphTargetInfluences';
39091	                mergedTrack.values = values;
39092	                mergedTracks[sourceTrackNode.uuid] = mergedTrack;
39093	                tracks.push(mergedTrack);
39094	                continue;
39095	            }
39096	            const sourceInterpolant = sourceTrack.createInterpolant(new sourceTrack.ValueBufferType(1));
39097	            mergedTrack = mergedTracks[sourceTrackNode.uuid];
39098	            // For every existing keyframe of the merged track, write a (possibly
39099	            // interpolated) value from the source track.
39100	            for(let j = 0; j < mergedTrack.times.length; j++){
39101	                mergedTrack.values[j * targetCount + targetIndex] = sourceInterpolant.evaluate(mergedTrack.times[j]);
39102	            }
39103	            // For every existing keyframe of the source track, write a (possibly
39104	            // new) keyframe to the merged track. Values from the previous loop may
39105	            // be written again, but keyframes are de-duplicated.
39106	            for(let j = 0; j < sourceTrack.times.length; j++){
39107	                const keyframeIndex = this.insertKeyframe(mergedTrack, sourceTrack.times[j]);
39108	                mergedTrack.values[keyframeIndex * targetCount + targetIndex] = sourceTrack.values[j];
39109	            }
39110	        }
39111	        clip.tracks = tracks;
39112	        return clip;
39113	    },
39114	    toFloat32BufferAttribute: function(srcAttribute) {
39115	        const dstAttribute = new BufferAttribute(new Float32Array(srcAttribute.count * srcAttribute.itemSize), srcAttribute.itemSize, false);
39116	        if (!srcAttribute.normalized && !srcAttribute.isInterleavedBufferAttribute) {
39117	            dstAttribute.array.set(srcAttribute.array);
39118	            return dstAttribute;
39119	        }
39120	        for(let i = 0, il = srcAttribute.count; i < il; i++){
39121	            for(let j = 0; j < srcAttribute.itemSize; j++){
39122	                dstAttribute.setComponent(i, j, srcAttribute.getComponent(i, j));
39123	            }
39124	        }
39125	        return dstAttribute;
39126	    }
39127	};
39128
39129	const compatibleObject = (object)=>{
39130	    return object.material !== undefined &&
39131	    object.userData &&
39132	    object.userData.variantMaterials &&
39133	    !!Array.from(object.userData.variantMaterials.values()).filter((m)=>compatibleMaterial(m.material));
39134	};
39135	 const compatibleMaterial = (material)=>{
39136	    return material && material.isMaterial && !Array.isArray(material);
39137	};
39138	class GLTFExporterMaterialsVariantsExtension {
39139	    beforeParse(objects) {
39140	        const variantNameSet = new Set();
39141	        const addVariantNames = (o)=>{
39142	            if (!compatibleObject(o)) {
39143	                return;
39144	            }
39145	            const variantMaterials = o.userData.variantMaterials;
39146	            const variantDataMap = o.userData.variantData;
39147	            for (const [variantName, variantData] of variantDataMap){
39148	                const variantMaterial = variantMaterials.get(variantData.index);
39149	                if (variantMaterial && compatibleMaterial(variantMaterial.material)) {
39150	                    variantNameSet.add(variantName);
39151	                }
39152	            }
39153	        };
39154	        if (Array.isArray(objects)) {
39155	            for (const object of objects){
39156	                object.traverse(addVariantNames);
39157	            }
39158	        } else {
39159	            objects.traverse(addVariantNames);
39160	        }
39161	        variantNameSet.forEach((name)=>this.variantNames.push(name));
39162	    }
39163	    async writeMesh(mesh, meshDef) {
39164	        if (!compatibleObject(mesh)) {
39165	            return;
39166	        }
39167	        const userData = mesh.userData;
39168	        const variantMaterials = userData.variantMaterials;
39169	        const variantDataMap = userData.variantData;
39170	        const mappingTable = new Map();
39171	        const reIndexedVariants = new Map();
39172	        const variants = Array.from(variantDataMap.values()).sort((a, b)=>{
39173	            return a.index - b.index;
39174	        });
39175	        for (const [i, variantData] of variants.entries()){
39176	            reIndexedVariants.set(variantData.index, i);
39177	        }
39178	        for (const variantData of variantDataMap.values()){
39179	            const variantInstance = variantMaterials.get(variantData.index);
39180	            if (!variantInstance || !compatibleMaterial(variantInstance.material)) {
39181	                continue;
39182	            }
39183	            const materialIndex = await this.writer.processMaterialAsync(variantInstance.material);
39184	            if (!mappingTable.has(materialIndex)) {
39185	                mappingTable.set(materialIndex, {
39186	                    material: materialIndex,
39187	                    variants: []
39188	                });
39189	            }
39190	            mappingTable.get(materialIndex).variants.push(reIndexedVariants.get(variantData.index));
39191	        }
39192	        const mappingsDef = Array.from(mappingTable.values()).map((m)=>{
39193	            return m.variants.sort((a, b)=>a - b) && m;
39194	        }).sort((a, b)=>a.material - b.material);
39195	        if (mappingsDef.length === 0) {
39196	            return;
39197	        }
39198	        const originalMaterialIndex = compatibleMaterial(userData.originalMaterial) ? await this.writer.processMaterialAsync(userData.originalMaterial) : -1;
39199	        for (const primitiveDef of meshDef.primitives){
39200	            if (originalMaterialIndex >= 0) {
39201	                primitiveDef.material = originalMaterialIndex;
39202	            }
39203	            primitiveDef.extensions = primitiveDef.extensions || {};
39204	            primitiveDef.extensions[this.name] = {
39205	                mappings: mappingsDef
39206	            };
39207	        }
39208	    }
39209	    afterParse() {
39210	        if (this.variantNames.length === 0) {
39211	            return;
39212	        }
39213	        const root = this.writer.json;
39214	        root.extensions = root.extensions || {};
39215	        const variantsDef = this.variantNames.map((n)=>{
39216	            return {
39217	                name: n
39218	            };
39219	        });
39220	        root.extensions[this.name] = {
39221	            variants: variantsDef
39222	        };
39223	        this.writer.extensionsUsed[this.name] = true;
39224	    }
39225	    constructor(writer){
39226	        this.writer = writer;
39227	        this.name = 'KHR_materials_variants';
39228	        this.variantNames = [];
39229	    }
39230	}
39231
39232	class SessionLightProbe {
39233	    updateReflection() {
39234	        const textureProperties = this.renderer.properties.get(this.xrLight.environment);
39235	        if (textureProperties) {
39236	            const cubeMap = this.xrWebGLBinding.getReflectionCubeMap(this.lightProbe);
39237	            if (cubeMap) {
39238	                textureProperties.__webglTexture = cubeMap;
39239	                this.xrLight.environment.needsPMREMUpdate = true;
39240	            }
39241	        }
39242	    }
39243	    onXRFrame(time, xrFrame) {
39244	        // If either this object or the XREstimatedLight has been destroyed, stop
39245	        // running the frame loop.
39246	        if (!this.xrLight) {
39247	            return;
39248	        }
39249	        const session = xrFrame.session;
39250	        session.requestAnimationFrame(this.frameCallback);
39251	        const lightEstimate = xrFrame.getLightEstimate(this.lightProbe);
39252	        if (lightEstimate) {
39253	            // We can copy the estimate's spherical harmonics array directly into the light probe.
39254	            this.xrLight.lightProbe.sh.fromArray(lightEstimate.sphericalHarmonicsCoefficients);
39255	            this.xrLight.lightProbe.intensity = 1.0;
39256	            // For the directional light we have to normalize the color and set the scalar as the
39257	            // intensity, since WebXR can return color values that exceed 1.0.
39258	            const intensityScalar = Math.max(1.0, Math.max(lightEstimate.primaryLightIntensity.x, Math.max(lightEstimate.primaryLightIntensity.y, lightEstimate.primaryLightIntensity.z)));
39259	            this.xrLight.directionalLight.color.setRGB(lightEstimate.primaryLightIntensity.x / intensityScalar, lightEstimate.primaryLightIntensity.y / intensityScalar, lightEstimate.primaryLightIntensity.z / intensityScalar);
39260	            this.xrLight.directionalLight.intensity = intensityScalar;
39261	            this.xrLight.directionalLight.position.copy(lightEstimate.primaryLightDirection);
39262	            if (this.estimationStartCallback) {
39263	                this.estimationStartCallback();
39264	                this.estimationStartCallback = null;
39265	            }
39266	        }
39267	    }
39268	    dispose() {
39269	        this.xrLight = null;
39270	        this.renderer = null;
39271	        this.lightProbe = null;
39272	        this.xrWebGLBinding = null;
39273	    }
39274	    constructor(xrLight, renderer, lightProbe, environmentEstimation, estimationStartCallback){
39275	        this.xrLight = xrLight;
39276	        this.renderer = renderer;
39277	        this.lightProbe = lightProbe;
39278	        this.xrWebGLBinding = null;
39279	        this.estimationStartCallback = estimationStartCallback;
39280	        this.frameCallback = this.onXRFrame.bind(this);
39281	        const session = renderer.xr.getSession();
39282	        // If the XRWebGLBinding class is available then we can also query an
39283	        // estimated reflection cube map.
39284	        if (environmentEstimation && 'XRWebGLBinding' in window) {
39285	            // This is the simplest way I know of to initialize a WebGL cubemap in Three.
39286	            const cubeRenderTarget = new WebGLCubeRenderTarget(16);
39287	            xrLight.environment = cubeRenderTarget.texture;
39288	            const gl = renderer.getContext();
39289	            // Ensure that we have any extensions needed to use the preferred cube map format.
39290	            switch(session.preferredReflectionFormat){
39291	                case 'srgba8':
39292	                    gl.getExtension('EXT_sRGB');
39293	                    break;
39294	                case 'rgba16f':
39295	                    gl.getExtension('OES_texture_half_float');
39296	                    break;
39297	            }
39298	            this.xrWebGLBinding = new XRWebGLBinding(session, gl);
39299	            this.lightProbe.addEventListener('reflectionchange', ()=>{
39300	                this.updateReflection();
39301	            });
39302	        }
39303	        // Start monitoring the XR animation frame loop to look for lighting
39304	        // estimation changes.
39305	        session.requestAnimationFrame(this.frameCallback);
39306	    }
39307	}
39308	class XREstimatedLight extends Group {
39309	    constructor(renderer, environmentEstimation = true){
39310	        super();
39311	        this.lightProbe = new LightProbe();
39312	        this.lightProbe.intensity = 0;
39313	        this.add(this.lightProbe);
39314	        this.directionalLight = new DirectionalLight();
39315	        this.directionalLight.intensity = 0;
39316	        this.add(this.directionalLight);
vendor: 4,443 bytes, lines 39317-39422
39317	        // Will be set to a cube map in the SessionLightProbe if environment estimation is
39318	        // available and requested.
39319	        this.environment = null;
39320	        let sessionLightProbe = null;
39321	        let estimationStarted = false;
39322	        renderer.xr.addEventListener('sessionstart', ()=>{
39323	            const session = renderer.xr.getSession();
39324	            if ('requestLightProbe' in session) {
39325	                session.requestLightProbe({
39326	                    reflectionFormat: session.preferredReflectionFormat
39327	                }).then((probe)=>{
39328	                    sessionLightProbe = new SessionLightProbe(this, renderer, probe, environmentEstimation, ()=>{
39329	                        estimationStarted = true;
39330	                        // Fired to indicate that the estimated lighting values are now being updated.
39331	                        this.dispatchEvent({
39332	                            type: 'estimationstart'
39333	                        });
39334	                    });
39335	                });
39336	            }
39337	        });
39338	        renderer.xr.addEventListener('sessionend', ()=>{
39339	            if (sessionLightProbe) {
39340	                sessionLightProbe.dispose();
39341	                sessionLightProbe = null;
39342	            }
39343	            if (estimationStarted) {
39344	                // Fired to indicate that the estimated lighting values are no longer being updated.
39345	                this.dispatchEvent({
39346	                    type: 'estimationend'
39347	                });
39348	            }
39349	        });
39350	        // Done inline to provide access to sessionLightProbe.
39351	        this.dispose = ()=>{
39352	            if (sessionLightProbe) {
39353	                sessionLightProbe.dispose();
39354	                sessionLightProbe = null;
39355	            }
39356	            this.remove(this.lightProbe);
39357	            this.lightProbe = null;
39358	            this.remove(this.directionalLight);
39359	            this.directionalLight = null;
39360	            this.environment = null;
39361	        };
39362	    }
39363	}
39364
39365	const SETTLING_TIME = 10000;
39366	const MIN_DECAY_MILLISECONDS = 0.001;
39367	const DECAY_MILLISECONDS = 50;
39368	 class Damper {
39369	    setDecayTime(decayMilliseconds) {
39370	        this.naturalFrequency = 1 / Math.max(MIN_DECAY_MILLISECONDS, decayMilliseconds);
39371	    }
39372	    update(x, xGoal, timeStepMilliseconds, xNormalization) {
39373	        const nilSpeed = 0.0002 * this.naturalFrequency;
39374	        if (x == null || xNormalization === 0) {
39375	            return xGoal;
39376	        }
39377	        if (x === xGoal && this.velocity === 0) {
39378	            return xGoal;
39379	        }
39380	        if (timeStepMilliseconds < 0) {
39381	            return x;
39382	        }
39383	        const deltaX = x - xGoal;
39384	        const intermediateVelocity = this.velocity + this.naturalFrequency * deltaX;
39385	        const intermediateX = deltaX + timeStepMilliseconds * intermediateVelocity;
39386	        const decay = Math.exp(-this.naturalFrequency * timeStepMilliseconds);
39387	        const newVelocity = (intermediateVelocity - this.naturalFrequency * intermediateX) * decay;
39388	        const acceleration = -this.naturalFrequency * (newVelocity + intermediateVelocity * decay);
39389	        if (Math.abs(newVelocity) < nilSpeed * Math.abs(xNormalization) && acceleration * deltaX >= 0) {
39390	            this.velocity = 0;
39391	            return xGoal;
39392	        } else {
39393	            this.velocity = newVelocity;
39394	            return xGoal + intermediateX * decay;
39395	        }
39396	    }
39397	    constructor(decayMilliseconds = DECAY_MILLISECONDS){
39398	        this.velocity = 0;
39399	        this.naturalFrequency = 0;
39400	        this.setDecayTime(decayMilliseconds);
39401	    }
39402	}
39403
39404	const RADIUS = 0.2;
39405	const LINE_WIDTH = 0.03;
39406	const MAX_OPACITY = 0.75;
39407	const SEGMENTS = 12;
39408	const DELTA_PHI = Math.PI / (2 * SEGMENTS);
39409	const vector2$1 = new Vector2();
39410	 const addCorner = (vertices, cornerX, cornerY)=>{
39411	    let phi = cornerX > 0 ? cornerY > 0 ? 0 : -Math.PI / 2 : cornerY > 0 ? Math.PI / 2 : Math.PI;
39412	    for(let i = 0; i <= SEGMENTS; ++i){
39413	        vertices.push(cornerX + (RADIUS - LINE_WIDTH) * Math.cos(phi), cornerY + (RADIUS - LINE_WIDTH) * Math.sin(phi), 0, cornerX + RADIUS * Math.cos(phi), cornerY + RADIUS * Math.sin(phi), 0);
39414	        phi += DELTA_PHI;
39415	    }
39416	};
39417	 class PlacementBox extends Mesh {
39418	 getHit(scene, screenX, screenY) {
39419	        vector2$1.set(screenX, -screenY);
39420	        this.hitPlane.visible = true;
39421	        const hitResult = scene.positionAndNormalFromPoint(vector2$1, this.hitPlane);
39422	        this.hitPlane.visible = false;
39423	        return hitResult == null ? null : hitResult.position;
39424	    }
39425	    getExpandedHit(scene, screenX, screenY) {
39426	        this.hitPlane.scale.set(1000, 1000, 1000);
39427	        this.hitPlane.updateMatrixWorld();
39428	        const hitResult = this.getHit(scene, screenX, screenY);
39429	        this.hitPlane.scale.set(1, 1, 1);
39430	        return hitResult;
39431	    }
39432	    controllerIntersection(scene, controller) {
39433	        this.hitBox.visible = true;
39434	        const hitResult = scene.hitFromController(controller, this.hitBox);
39435	        this.hitBox.visible = false;
39436	        return hitResult;
39437	    }
39438	 set offsetHeight(offset) {
39439	        offset -= 0.001;
39440	        if (this.side === 'back') {
39441	            this.position.z = this.shadowHeight + offset;
39442	        } else {
39443	            this.position.y = this.shadowHeight + offset;
39444	        }
39445	    }
39446	    get offsetHeight() {
39447	        if (this.side === 'back') {
39448	            return this.position.z - this.shadowHeight;
39449	        } else {
39450	            return this.position.y - this.shadowHeight;
39451	        }
39452	    }
39453	 set show(visible) {
39454	        this.goalOpacity = visible ? MAX_OPACITY : 0;
39455	    }
39456	 updateOpacity(delta) {
39457	        const material = this.material;
39458	        material.opacity = this.opacityDamper.update(material.opacity, this.goalOpacity, delta, 1);
39459	        this.visible = material.opacity > 0;
39460	    }
39461	 dispose() {
39462	        const { geometry, material } = this.hitPlane;
39463	        geometry.dispose();
39464	        material.dispose();
39465	        this.hitBox.geometry.dispose();
39466	        this.hitBox.material.dispose();
39467	        this.geometry.dispose();
39468	        this.material.dispose();
39469	        this.hitBox.removeFromParent();
39470	        this.removeFromParent();
39471	    }
39472	    constructor(scene, side){
39473	        const geometry = new BufferGeometry();
39474	        const triangles = [];
39475	        const vertices = [];
39476	        const { size, boundingBox } = scene;
39477	        const x = size.x / 2;
39478	        const y = (side === 'back' ? size.y : size.z) / 2;
39479	        addCorner(vertices, x, y);
39480	        addCorner(vertices, -x, y);
39481	        addCorner(vertices, -x, -y);
39482	        addCorner(vertices, x, -y);
39483	        const numVertices = vertices.length / 3;
39484	        for(let i = 0; i < numVertices - 2; i += 2){
39485	            triangles.push(i, i + 1, i + 3, i, i + 3, i + 2);
39486	        }
39487	        const i = numVertices - 2;
39488	        triangles.push(i, i + 1, 1, i, 1, 0);
39489	        geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
39490	        geometry.setIndex(triangles);
39491	        super(geometry);
39492	        this.side = side;
39493	        const material = this.material;
39494	        material.side = DoubleSide;
39495	        material.transparent = true;
39496	        material.opacity = 0;
39497	        this.goalOpacity = 0;
39498	        this.opacityDamper = new Damper();
39499	        this.hitPlane = new Mesh(new PlaneGeometry(2 * (x + RADIUS), 2 * (y + RADIUS)));
39500	        this.hitPlane.visible = false;
39501	        this.hitPlane.material.side = DoubleSide;
39502	        this.add(this.hitPlane);
39503	        this.hitBox = new Mesh(new BoxGeometry(size.x + 2 * RADIUS, size.y + RADIUS, size.z + 2 * RADIUS));
39504	        this.hitBox.visible = false;
39505	        this.hitBox.material.side = DoubleSide;
39506	        this.add(this.hitBox);
39507	        boundingBox.getCenter(this.position);
39508	        switch(side){
39509	            case 'bottom':
39510	                this.rotateX(-Math.PI / 2);
39511	                this.shadowHeight = boundingBox.min.y;
39512	                this.position.y = this.shadowHeight;
39513	                break;
39514	            case 'back':
39515	                this.shadowHeight = boundingBox.min.z;
39516	                this.position.z = this.shadowHeight;
39517	        }
39518	        scene.target.add(this);
39519	        this.hitBox.position.y = (size.y + RADIUS) / 2 + boundingBox.min.y;
39520	        scene.target.add(this.hitBox);
39521	        this.offsetHeight = 0;
39522	    }
39523	}
39524
39525	const numberNode = (value, unit)=>({
39526	        type: 'number',
39527	        number: value,
39528	        unit
39529	    });
39530	 const parseExpressions = (()=>{
39531	    const cache = {};
39532	    const MAX_PARSE_ITERATIONS = 1000;
39533	    return (inputString)=>{
39534	        const cacheKey = inputString;
39535	        if (cacheKey in cache) {
39536	            return cache[cacheKey];
39537	        }
39538	        const expressions = [];
39539	        let parseIterations = 0;
39540	        while(inputString){
39541	            if (++parseIterations > MAX_PARSE_ITERATIONS) {
39542	                inputString = '';
39543	                break;
39544	            }
39545	            const expressionParseResult = parseExpression(inputString);
39546	            const expression = expressionParseResult.nodes[0];
39547	            if (expression == null || expression.terms.length === 0) {
39548	                break;
39549	            }
39550	            expressions.push(expression);
39551	            inputString = expressionParseResult.remainingInput;
39552	        }
39553	        return cache[cacheKey] = expressions;
39554	    };
39555	})();
39556	 const parseExpression = (()=>{
39557	    const IS_IDENT_RE = /^(\-\-|[a-z\u0240-\uffff])/i;
vendor: 24,025 bytes, lines 39558-40223
39558	    const IS_OPERATOR_RE = /^([\*\+\/]|[\-]\s)/i;
39559	    const IS_EXPRESSION_END_RE = /^[\),]/;
39560	    const FUNCTION_ARGUMENTS_FIRST_TOKEN = '(';
39561	    const HEX_FIRST_TOKEN = '#';
39562	    return (inputString)=>{
39563	        const terms = [];
39564	        while(inputString.length){
39565	            inputString = inputString.trim();
39566	            if (IS_EXPRESSION_END_RE.test(inputString)) {
39567	                break;
39568	            } else if (inputString[0] === FUNCTION_ARGUMENTS_FIRST_TOKEN) {
39569	                const { nodes, remainingInput } = parseFunctionArguments(inputString);
39570	                inputString = remainingInput;
39571	                terms.push({
39572	                    type: 'function',
39573	                    name: {
39574	                        type: 'ident',
39575	                        value: 'calc'
39576	                    },
39577	                    arguments: nodes
39578	                });
39579	            } else if (IS_IDENT_RE.test(inputString)) {
39580	                const identParseResult = parseIdent(inputString);
39581	                const identNode = identParseResult.nodes[0];
39582	                inputString = identParseResult.remainingInput;
39583	                if (inputString[0] === FUNCTION_ARGUMENTS_FIRST_TOKEN) {
39584	                    const { nodes, remainingInput } = parseFunctionArguments(inputString);
39585	                    terms.push({
39586	                        type: 'function',
39587	                        name: identNode,
39588	                        arguments: nodes
39589	                    });
39590	                    inputString = remainingInput;
39591	                } else {
39592	                    terms.push(identNode);
39593	                }
39594	            } else if (IS_OPERATOR_RE.test(inputString)) {
39595	                terms.push({
39596	                    type: 'operator',
39597	                    value: inputString[0]
39598	                });
39599	                inputString = inputString.slice(1);
39600	            } else {
39601	                const { nodes, remainingInput } = inputString[0] === HEX_FIRST_TOKEN ? parseHex(inputString) : parseNumber(inputString);
39602	                if (nodes.length === 0) {
39603	                    break;
39604	                }
39605	                terms.push(nodes[0]);
39606	                inputString = remainingInput;
39607	            }
39608	        }
39609	        return {
39610	            nodes: [
39611	                {
39612	                    type: 'expression',
39613	                    terms
39614	                }
39615	            ],
39616	            remainingInput: inputString
39617	        };
39618	    };
39619	})();
39620	 const parseIdent = (()=>{
39621	    const NOT_IDENT_RE = /[^a-z0-9_\-\u0240-\uffff]/i;
39622	    return (inputString)=>{
39623	        const match = inputString.match(NOT_IDENT_RE);
39624	        const ident = match == null ? inputString : inputString.substr(0, match.index);
39625	        const remainingInput = match == null ? '' : inputString.substr(match.index);
39626	        return {
39627	            nodes: [
39628	                {
39629	                    type: 'ident',
39630	                    value: ident
39631	                }
39632	            ],
39633	            remainingInput
39634	        };
39635	    };
39636	})();
39637	 const parseNumber = (()=>{
39638	    const VALUE_RE = /[\+\-]?(\d+[\.]\d+|\d+|[\.]\d+)([eE][\+\-]?\d+)?/;
39639	    const UNIT_RE = /^[a-z%]+/i;
39640	    const ALLOWED_UNITS = /^(m|mm|cm|rad|deg|[%])$/;
39641	    return (inputString)=>{
39642	        const valueMatch = inputString.match(VALUE_RE);
39643	        const value = valueMatch == null ? '0' : valueMatch[0];
39644	        inputString = value == null ? inputString : inputString.slice(value.length);
39645	        const unitMatch = inputString.match(UNIT_RE);
39646	        let unit = unitMatch != null && unitMatch[0] !== '' ? unitMatch[0] : null;
39647	        const remainingInput = unitMatch == null ? inputString : inputString.slice(unit.length);
39648	        if (unit != null && !ALLOWED_UNITS.test(unit)) {
39649	            unit = null;
39650	        }
39651	        return {
39652	            nodes: [
39653	                {
39654	                    type: 'number',
39655	                    number: parseFloat(value) || 0,
39656	                    unit: unit
39657	                }
39658	            ],
39659	            remainingInput
39660	        };
39661	    };
39662	})();
39663	 const parseHex = (()=>{
39664	    const HEX_RE = /^[a-f0-9]*/i;
39665	    return (inputString)=>{
39666	        inputString = inputString.slice(1).trim();
39667	        const hexMatch = inputString.match(HEX_RE);
39668	        const nodes = hexMatch == null ? [] : [
39669	            {
39670	                type: 'hex',
39671	                value: hexMatch[0]
39672	            }
39673	        ];
39674	        return {
39675	            nodes,
39676	            remainingInput: hexMatch == null ? inputString : inputString.slice(hexMatch[0].length)
39677	        };
39678	    };
39679	})();
39680	 const parseFunctionArguments = (inputString)=>{
39681	    const expressionNodes = [];
39682	    inputString = inputString.slice(1).trim();
39683	    while(inputString.length){
39684	        const expressionParseResult = parseExpression(inputString);
39685	        expressionNodes.push(expressionParseResult.nodes[0]);
39686	        inputString = expressionParseResult.remainingInput.trim();
39687	        if (inputString[0] === ',') {
39688	            inputString = inputString.slice(1).trim();
39689	        } else if (inputString[0] === ')') {
39690	            inputString = inputString.slice(1);
39691	            break;
39692	        }
39693	    }
39694	    return {
39695	        nodes: expressionNodes,
39696	        remainingInput: inputString
39697	    };
39698	};
39699	const $visitedTypes = Symbol('visitedTypes');
39700	 class ASTWalker {
39701	 walk(ast, callback) {
39702	        const remaining = ast.slice();
39703	        while(remaining.length){
39704	            const next = remaining.shift();
39705	            if (this[$visitedTypes].indexOf(next.type) > -1) {
39706	                callback(next);
39707	            }
39708	            switch(next.type){
39709	                case 'expression':
39710	                    remaining.unshift(...next.terms);
39711	                    break;
39712	                case 'function':
39713	                    remaining.unshift(next.name, ...next.arguments);
39714	                    break;
39715	            }
39716	        }
39717	    }
39718	    constructor(visitedTypes){
39719	        this[$visitedTypes] = visitedTypes;
39720	    }
39721	}
39722	const ZERO = Object.freeze({
39723	    type: 'number',
39724	    number: 0,
39725	    unit: null
39726	});
39727
39728	const degreesToRadians = (numberNode, fallbackRadianValue = 0)=>{
39729	    let { number, unit } = numberNode;
39730	    if (!isFinite(number)) {
39731	        number = fallbackRadianValue;
39732	        unit = 'rad';
39733	    } else if (numberNode.unit === 'rad' || numberNode.unit == null) {
39734	        return numberNode;
39735	    }
39736	    const valueIsDegrees = unit === 'deg' && number != null;
39737	    const value = valueIsDegrees ? number : 0;
39738	    const radians = value * Math.PI / 180;
39739	    return {
39740	        type: 'number',
39741	        number: radians,
39742	        unit: 'rad'
39743	    };
39744	};
39745	 const lengthToBaseMeters = (numberNode, fallbackMeterValue = 0)=>{
39746	    let { number, unit } = numberNode;
39747	    if (!isFinite(number)) {
39748	        number = fallbackMeterValue;
39749	        unit = 'm';
39750	    } else if (numberNode.unit === 'm') {
39751	        return numberNode;
39752	    }
39753	    let scale;
39754	    switch(unit){
39755	        default:
39756	            scale = 1;
39757	            break;
39758	        case 'cm':
39759	            scale = 1 / 100;
39760	            break;
39761	        case 'mm':
39762	            scale = 1 / 1000;
39763	            break;
39764	    }
39765	    const value = scale * number;
39766	    return {
39767	        type: 'number',
39768	        number: value,
39769	        unit: 'm'
39770	    };
39771	};
39772	 const normalizeUnit = (()=>{
39773	    const identity = (node)=>node;
39774	    const unitNormalizers = {
39775	        'rad': identity,
39776	        'deg': degreesToRadians,
39777	        'm': identity,
39778	        'mm': lengthToBaseMeters,
39779	        'cm': lengthToBaseMeters
39780	    };
39781	    return (node, fallback = ZERO)=>{
39782	        if (!isFinite(node.number)) {
39783	            node.number = fallback.number;
39784	            node.unit = fallback.unit;
39785	        }
39786	        const { unit } = node;
39787	        if (unit == null) {
39788	            return node;
39789	        }
39790	        const normalize = unitNormalizers[unit];
39791	        if (normalize == null) {
39792	            return fallback;
39793	        }
39794	        return normalize(node);
39795	    };
39796	})();
39797
39798	var _a$6, _b$6, _c$4;
39799	const $evaluate = Symbol('evaluate');
39800	const $lastValue = Symbol('lastValue');
39801	 class Evaluator {
39802	 static evaluatableFor(node, basis = ZERO) {
39803	        if (node instanceof Evaluator) {
39804	            return node;
39805	        }
39806	        if (node.type === 'number') {
39807	            if (node.unit === '%') {
39808	                return new PercentageEvaluator(node, basis);
39809	            }
39810	            return node;
39811	        }
39812	        switch(node.name.value){
39813	            case 'calc':
39814	                return new CalcEvaluator(node, basis);
39815	            case 'env':
39816	                return new EnvEvaluator(node);
39817	        }
39818	        return ZERO;
39819	    }
39820	 static evaluate(evaluatable) {
39821	        if (evaluatable instanceof Evaluator) {
39822	            return evaluatable.evaluate();
39823	        }
39824	        return evaluatable;
39825	    }
39826	 static isConstant(evaluatable) {
39827	        if (evaluatable instanceof Evaluator) {
39828	            return evaluatable.isConstant;
39829	        }
39830	        return true;
39831	    }
39832	 static applyIntrinsics(evaluated, intrinsics) {
39833	        const { basis, keywords } = intrinsics;
39834	        const { auto } = keywords;
39835	        return basis.map((basisNode, index)=>{
39836	            const autoSubstituteNode = auto[index] == null ? basisNode : auto[index];
39837	            let evaluatedNode = evaluated[index] ? evaluated[index] : autoSubstituteNode;
39838	            if (evaluatedNode.type === 'ident') {
39839	                const keyword = evaluatedNode.value;
39840	                if (keyword in keywords) {
39841	                    evaluatedNode = keywords[keyword][index];
39842	                }
39843	            }
39844	            if (evaluatedNode == null || evaluatedNode.type === 'ident') {
39845	                evaluatedNode = autoSubstituteNode;
39846	            }
39847	            if (evaluatedNode.unit === '%') {
39848	                return numberNode(evaluatedNode.number / 100 * basisNode.number, basisNode.unit);
39849	            }
39850	            evaluatedNode = normalizeUnit(evaluatedNode, basisNode);
39851	            if (evaluatedNode.unit !== basisNode.unit) {
39852	                return basisNode;
39853	            }
39854	            return evaluatedNode;
39855	        });
39856	    }
39857	 get isConstant() {
39858	        return false;
39859	    }
39860	 evaluate() {
39861	        if (!this.isConstant || this[$lastValue] == null) {
39862	            this[$lastValue] = this[$evaluate]();
39863	        }
39864	        return this[$lastValue];
39865	    }
39866	    constructor(){
39867	        this[_a$6] = null;
39868	    }
39869	}
39870	_a$6 = $lastValue;
39871	const $percentage = Symbol('percentage');
39872	const $basis = Symbol('basis');
39873	 class PercentageEvaluator extends Evaluator {
39874	    get isConstant() {
39875	        return true;
39876	    }
39877	    [$evaluate]() {
39878	        return numberNode(this[$percentage].number / 100 * this[$basis].number, this[$basis].unit);
39879	    }
39880	    constructor(percentage, basis){
39881	        super();
39882	        this[$percentage] = percentage;
39883	        this[$basis] = basis;
39884	    }
39885	}
39886	const $identNode = Symbol('identNode');
39887	 class EnvEvaluator extends Evaluator {
39888	    get isConstant() {
39889	        return false;
39890	    }
39891	    [(_b$6 = $identNode, $evaluate)]() {
39892	        if (this[$identNode] != null) {
39893	            switch(this[$identNode].value){
39894	                case 'window-scroll-y':
39895	                    const verticalScrollPosition = window.pageYOffset;
39896	                    const verticalScrollMax = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
39897	                    const scrollY = verticalScrollPosition / (verticalScrollMax - window.innerHeight) || 0;
39898	                    return {
39899	                        type: 'number',
39900	                        number: scrollY,
39901	                        unit: null
39902	                    };
39903	            }
39904	        }
39905	        return ZERO;
39906	    }
39907	    constructor(envFunction){
39908	        super();
39909	        this[_b$6] = null;
39910	        const identNode = envFunction.arguments.length ? envFunction.arguments[0].terms[0] : null;
39911	        if (identNode != null && identNode.type === 'ident') {
39912	            this[$identNode] = identNode;
39913	        }
39914	    }
39915	}
39916	const IS_MULTIPLICATION_RE = /[\*\/]/;
39917	const $evaluator = Symbol('evaluator');
39918	 class CalcEvaluator extends Evaluator {
39919	    get isConstant() {
39920	        return this[$evaluator] == null || Evaluator.isConstant(this[$evaluator]);
39921	    }
39922	    [(_c$4 = $evaluator, $evaluate)]() {
39923	        return this[$evaluator] != null ? Evaluator.evaluate(this[$evaluator]) : ZERO;
39924	    }
39925	    constructor(calcFunction, basis = ZERO){
39926	        super();
39927	        this[_c$4] = null;
39928	        if (calcFunction.arguments.length !== 1) {
39929	            return;
39930	        }
39931	        const terms = calcFunction.arguments[0].terms.slice();
39932	        const secondOrderTerms = [];
39933	        while(terms.length){
39934	            const term = terms.shift();
39935	            if (secondOrderTerms.length > 0) {
39936	                const previousTerm = secondOrderTerms[secondOrderTerms.length - 1];
39937	                if (previousTerm.type === 'operator' && IS_MULTIPLICATION_RE.test(previousTerm.value)) {
39938	                    const operator = secondOrderTerms.pop();
39939	                    const leftValue = secondOrderTerms.pop();
39940	                    if (leftValue == null) {
39941	                        return;
39942	                    }
39943	                    secondOrderTerms.push(new OperatorEvaluator(operator, Evaluator.evaluatableFor(leftValue, basis), Evaluator.evaluatableFor(term, basis)));
39944	                    continue;
39945	                }
39946	            }
39947	            secondOrderTerms.push(term.type === 'operator' ? term : Evaluator.evaluatableFor(term, basis));
39948	        }
39949	        while(secondOrderTerms.length > 2){
39950	            const [left, operator, right] = secondOrderTerms.splice(0, 3);
39951	            if (operator.type !== 'operator') {
39952	                return;
39953	            }
39954	            secondOrderTerms.unshift(new OperatorEvaluator(operator, Evaluator.evaluatableFor(left, basis), Evaluator.evaluatableFor(right, basis)));
39955	        }
39956	        if (secondOrderTerms.length === 1) {
39957	            this[$evaluator] = secondOrderTerms[0];
39958	        }
39959	    }
39960	}
39961	const $operator = Symbol('operator');
39962	const $left = Symbol('left');
39963	const $right = Symbol('right');
39964	 class OperatorEvaluator extends Evaluator {
39965	    get isConstant() {
39966	        return Evaluator.isConstant(this[$left]) && Evaluator.isConstant(this[$right]);
39967	    }
39968	    [$evaluate]() {
39969	        const leftNode = normalizeUnit(Evaluator.evaluate(this[$left]));
39970	        const rightNode = normalizeUnit(Evaluator.evaluate(this[$right]));
39971	        const { number: leftValue, unit: leftUnit } = leftNode;
39972	        const { number: rightValue, unit: rightUnit } = rightNode;
39973	        if (rightUnit != null && leftUnit != null && rightUnit != leftUnit) {
39974	            return ZERO;
39975	        }
39976	        const unit = leftUnit || rightUnit;
39977	        let value;
39978	        switch(this[$operator].value){
39979	            case '+':
39980	                value = leftValue + rightValue;
39981	                break;
39982	            case '-':
39983	                value = leftValue - rightValue;
39984	                break;
39985	            case '/':
39986	                value = leftValue / rightValue;
39987	                break;
39988	            case '*':
39989	                value = leftValue * rightValue;
39990	                break;
39991	            default:
39992	                return ZERO;
39993	        }
39994	        return {
39995	            type: 'number',
39996	            number: value,
39997	            unit
39998	        };
39999	    }
40000	    constructor(operator, left, right){
40001	        super();
40002	        this[$operator] = operator;
40003	        this[$left] = left;
40004	        this[$right] = right;
40005	    }
40006	}
40007	const $evaluatables = Symbol('evaluatables');
40008	const $intrinsics = Symbol('intrinsics');
40009	 class StyleEvaluator extends Evaluator {
40010	    get isConstant() {
40011	        for (const evaluatable of this[$evaluatables]){
40012	            if (!Evaluator.isConstant(evaluatable)) {
40013	                return false;
40014	            }
40015	        }
40016	        return true;
40017	    }
40018	    [$evaluate]() {
40019	        const evaluated = this[$evaluatables].map((evaluatable)=>Evaluator.evaluate(evaluatable));
40020	        return Evaluator.applyIntrinsics(evaluated, this[$intrinsics]).map((numberNode)=>numberNode.number);
40021	    }
40022	    constructor(expressions, intrinsics){
40023	        super();
40024	        this[$intrinsics] = intrinsics;
40025	        const firstExpression = expressions[0];
40026	        const terms = firstExpression != null ? firstExpression.terms : [];
40027	        this[$evaluatables] = intrinsics.basis.map((basisNode, index)=>{
40028	            const term = terms[index];
40029	            if (term == null) {
40030	                return {
40031	                    type: 'ident',
40032	                    value: 'auto'
40033	                };
40034	            }
40035	            if (term.type === 'ident') {
40036	                return term;
40037	            }
40038	            return Evaluator.evaluatableFor(term, basisNode);
40039	        });
40040	    }
40041	}
40042
40043	var _a$5, _b$5, _c$3, _d$2;
40044	const $instances = Symbol('instances');
40045	const $activateListener = Symbol('activateListener');
40046	const $deactivateListener = Symbol('deactivateListener');
40047	const $notifyInstances = Symbol('notifyInstances');
40048	const $notify = Symbol('notify');
40049	const $scrollCallback = Symbol('callback');
40050	 class ScrollObserver {
40051	    static [$notifyInstances]() {
40052	        for (const instance of ScrollObserver[$instances]){
40053	            instance[$notify]();
40054	        }
40055	    }
40056	    static [(_a$5 = $instances, $activateListener)]() {
40057	        window.addEventListener('scroll', this[$notifyInstances], {
40058	            passive: true
40059	        });
40060	    }
40061	    static [$deactivateListener]() {
40062	        window.removeEventListener('scroll', this[$notifyInstances]);
40063	    }
40064	 observe() {
40065	        if (ScrollObserver[$instances].size === 0) {
40066	            ScrollObserver[$activateListener]();
40067	        }
40068	        ScrollObserver[$instances].add(this);
40069	    }
40070	 disconnect() {
40071	        ScrollObserver[$instances].delete(this);
40072	        if (ScrollObserver[$instances].size === 0) {
40073	            ScrollObserver[$deactivateListener]();
40074	        }
40075	    }
40076	    [$notify]() {
40077	        this[$scrollCallback]();
40078	    }
40079	    constructor(callback){
40080	        this[$scrollCallback] = callback;
40081	    }
40082	}
40083	ScrollObserver[_a$5] = new Set();
40084	const $computeStyleCallback = Symbol('computeStyleCallback');
40085	const $astWalker = Symbol('astWalker');
40086	const $dependencies = Symbol('dependencies');
40087	const $onScroll = Symbol('onScroll');
40088	 class StyleEffector {
40089	 observeEffectsFor(ast) {
40090	        const newDependencies = {};
40091	        const oldDependencies = this[$dependencies];
40092	        this[$astWalker].walk(ast, (functionNode)=>{
40093	            const { name } = functionNode;
40094	            const firstArgument = functionNode.arguments[0];
40095	            const firstTerm = firstArgument.terms[0];
40096	            if (name.value !== 'env' || firstTerm == null || firstTerm.type !== 'ident') {
40097	                return;
40098	            }
40099	            switch(firstTerm.value){
40100	                case 'window-scroll-y':
40101	                    if (newDependencies['window-scroll'] == null) {
40102	                        const observer = 'window-scroll' in oldDependencies ? oldDependencies['window-scroll'] : new ScrollObserver(this[$onScroll]);
40103	                        observer.observe();
40104	                        delete oldDependencies['window-scroll'];
40105	                        newDependencies['window-scroll'] = observer;
40106	                    }
40107	                    break;
40108	            }
40109	        });
40110	        for(const environmentState in oldDependencies){
40111	            const observer = oldDependencies[environmentState];
40112	            observer.disconnect();
40113	        }
40114	        this[$dependencies] = newDependencies;
40115	    }
40116	 dispose() {
40117	        for(const environmentState in this[$dependencies]){
40118	            const observer = this[$dependencies][environmentState];
40119	            observer.disconnect();
40120	        }
40121	    }
40122	    constructor(callback){
40123	        this[_b$5] = {};
40124	        this[_c$3] = new ASTWalker([
40125	            'function'
40126	        ]);
40127	        this[_d$2] = ()=>{
40128	            this[$computeStyleCallback]({
40129	                relatedState: 'window-scroll'
40130	            });
40131	        };
40132	        this[$computeStyleCallback] = callback;
40133	    }
40134	}
40135	_b$5 = $dependencies, _c$3 = $astWalker, _d$2 = $onScroll;
40136
40137	const style = (config)=>{
40138	    const observeEffects = config.observeEffects || false;
40139	    const getIntrinsics = config.intrinsics instanceof Function ? config.intrinsics : ()=>config.intrinsics;
40140	    return (proto, propertyName)=>{
40141	        const originalUpdated = proto.updated;
40142	        const originalConnectedCallback = proto.connectedCallback;
40143	        const originalDisconnectedCallback = proto.disconnectedCallback;
40144	        const $styleEffector = Symbol(`${propertyName}StyleEffector`);
40145	        const $styleEvaluator = Symbol(`${propertyName}StyleEvaluator`);
40146	        const $updateEvaluator = Symbol(`${propertyName}UpdateEvaluator`);
40147	        const $evaluateAndSync = Symbol(`${propertyName}EvaluateAndSync`);
40148	        Object.defineProperties(proto, {
40149	            [$styleEffector]: {
40150	                value: null,
40151	                writable: true
40152	            },
40153	            [$styleEvaluator]: {
40154	                value: null,
40155	                writable: true
40156	            },
40157	            [$updateEvaluator]: {
40158	                value: function() {
40159	                    const ast = parseExpressions(this[propertyName]);
40160	                    this[$styleEvaluator] = new StyleEvaluator(ast, getIntrinsics(this));
40161	                    if (this[$styleEffector] == null && observeEffects) {
40162	                        this[$styleEffector] = new StyleEffector(()=>this[$evaluateAndSync]());
40163	                    }
40164	                    if (this[$styleEffector] != null) {
40165	                        this[$styleEffector].observeEffectsFor(ast);
40166	                    }
40167	                }
40168	            },
40169	            [$evaluateAndSync]: {
40170	                value: function() {
40171	                    if (this[$styleEvaluator] == null) {
40172	                        return;
40173	                    }
40174	                    const result = this[$styleEvaluator].evaluate();
40175	                    this[config.updateHandler](result);
40176	                }
40177	            },
40178	            updated: {
40179	                value: function(changedProperties) {
40180	                    if (changedProperties.has(propertyName)) {
40181	                        this[$updateEvaluator]();
40182	                        this[$evaluateAndSync]();
40183	                    }
40184	                    originalUpdated.call(this, changedProperties);
40185	                }
40186	            },
40187	            connectedCallback: {
40188	                value: function() {
40189	                    originalConnectedCallback.call(this);
40190	                    this.requestUpdate(propertyName, this[propertyName]);
40191	                }
40192	            },
40193	            disconnectedCallback: {
40194	                value: function() {
40195	                    originalDisconnectedCallback.call(this);
40196	                    if (this[$styleEffector] != null) {
40197	                        this[$styleEffector].dispose();
40198	                        this[$styleEffector] = null;
40199	                    }
40200	                }
40201	            }
40202	        });
40203	    };
40204	};
40205
40206	const easeInOutQuad = (t)=>t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
40207	 const interpolate = (start, end, ease = easeInOutQuad)=>(time)=>start + (end - start) * ease(time);
40208	 const sequence = (tracks, weights)=>{
40209	    const cumulativeSum = (sum)=>(value)=>sum += value;
40210	    const times = weights.map(cumulativeSum(0));
40211	    return (time)=>{
40212	        time = clamp(time, 0, 1);
40213	        time *= times[times.length - 1];
40214	        const i = times.findIndex((val)=>val >= time);
40215	        const start = i < 1 ? 0 : times[i - 1];
40216	        const end = times[i];
40217	        return tracks[i]((time - start) / (end - start));
40218	    };
40219	};
40220	 const timeline = (path)=>{
40221	    const tracks = [];
40222	    const weights = [];
40223	    let lastValue = path.initialValue;
vendor: 6,810 bytes, lines 40224-40453
40224	    for(let i = 0; i < path.keyframes.length; ++i){
40225	        const keyframe = path.keyframes[i];
40226	        const { value, frames } = keyframe;
40227	        const ease = keyframe.ease || easeInOutQuad;
40228	        const track = interpolate(lastValue, value, ease);
40229	        tracks.push(track);
40230	        weights.push(frames);
40231	        lastValue = value;
40232	    }
40233	    return sequence(tracks, weights);
40234	};
40235
40236	var __decorate$6 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
40237	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
40238	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
40239	    return c > 3 && r && Object.defineProperty(target, key, r), r;
40240	};
40241	const PROMPT_ANIMATION_TIME = 5000;
40242	const wiggle = timeline({
40243	    initialValue: 0,
40244	    keyframes: [
40245	        {
40246	            frames: 5,
40247	            value: -1
40248	        },
40249	        {
40250	            frames: 1,
40251	            value: -1
40252	        },
40253	        {
40254	            frames: 8,
40255	            value: 1
40256	        },
40257	        {
40258	            frames: 1,
40259	            value: 1
40260	        },
40261	        {
40262	            frames: 5,
40263	            value: 0
40264	        },
40265	        {
40266	            frames: 18,
40267	            value: 0
40268	        }
40269	    ]
40270	});
40271	const fade = timeline({
40272	    initialValue: 0,
40273	    keyframes: [
40274	        {
40275	            frames: 1,
40276	            value: 1
40277	        },
40278	        {
40279	            frames: 5,
40280	            value: 1
40281	        },
40282	        {
40283	            frames: 1,
40284	            value: 0
40285	        },
40286	        {
40287	            frames: 6,
40288	            value: 0
40289	        }
40290	    ]
40291	});
40292	const DEFAULT_FOV_DEG = 30;
40293	const DEFAULT_MIN_FOV_DEG = 12;
40294	const DEFAULT_CAMERA_ORBIT = '0deg 75deg 105%';
40295	const DEFAULT_CAMERA_TARGET = 'auto auto auto';
40296	const DEFAULT_FIELD_OF_VIEW = 'auto';
40297	const MINIMUM_RADIUS_RATIO = 2.2;
40298	const AZIMUTHAL_QUADRANT_LABELS = [
40299	    'front',
40300	    'right',
40301	    'back',
40302	    'left'
40303	];
40304	const POLAR_TRIENT_LABELS = [
40305	    'upper-',
40306	    '',
40307	    'lower-'
40308	];
40309	const DEFAULT_INTERACTION_PROMPT_THRESHOLD = 3000;
40310	const INTERACTION_PROMPT = '. Use mouse, touch or arrow keys to move.';
40311	const InteractionPromptStrategy = {
40312	    AUTO: 'auto'};
40313	const InteractionPromptStyle = {
40314	    BASIC: 'basic',
40315	    WIGGLE: 'wiggle'
40316	};
40317	const TouchAction = {
40318	    NONE: 'none'
40319	};
40320	const fieldOfViewIntrinsics = ()=>{
40321	    return {
40322	        basis: [
40323	            degreesToRadians(numberNode(DEFAULT_FOV_DEG, 'deg'))
40324	        ],
40325	        keywords: {
40326	            auto: [
40327	                null
40328	            ]
40329	        }
40330	    };
40331	};
40332	const minFieldOfViewIntrinsics = ()=>{
40333	    return {
40334	        basis: [
40335	            degreesToRadians(numberNode(DEFAULT_MIN_FOV_DEG, 'deg'))
40336	        ],
40337	        keywords: {
40338	            auto: [
40339	                null
40340	            ]
40341	        }
40342	    };
40343	};
40344	const cameraOrbitIntrinsics = (()=>{
40345	    const defaultTerms = parseExpressions(DEFAULT_CAMERA_ORBIT)[0].terms;
40346	    const theta = normalizeUnit(defaultTerms[0]);
40347	    const phi = normalizeUnit(defaultTerms[1]);
40348	    return (element)=>{
40349	        const radius = element[$scene].idealCameraDistance();
40350	        return {
40351	            basis: [
40352	                theta,
40353	                phi,
40354	                numberNode(radius, 'm')
40355	            ],
40356	            keywords: {
40357	                auto: [
40358	                    null,
40359	                    null,
40360	                    numberNode(105, '%')
40361	                ]
40362	            }
40363	        };
40364	    };
40365	})();
40366	const minCameraOrbitIntrinsics = (element)=>{
40367	    const radius = MINIMUM_RADIUS_RATIO * element[$scene].boundingSphere.radius;
40368	    return {
40369	        basis: [
40370	            numberNode(-Infinity, 'rad'),
40371	            numberNode(0, 'rad'),
40372	            numberNode(radius, 'm')
40373	        ],
40374	        keywords: {
40375	            auto: [
40376	                null,
40377	                null,
40378	                null
40379	            ]
40380	        }
40381	    };
40382	};
40383	const maxCameraOrbitIntrinsics = (element)=>{
40384	    const orbitIntrinsics = cameraOrbitIntrinsics(element);
40385	    const evaluator = new StyleEvaluator([], orbitIntrinsics);
40386	    const defaultRadius = evaluator.evaluate()[2];
40387	    return {
40388	        basis: [
40389	            numberNode(Infinity, 'rad'),
40390	            numberNode(Math.PI, 'rad'),
40391	            numberNode(defaultRadius, 'm')
40392	        ],
40393	        keywords: {
40394	            auto: [
40395	                null,
40396	                null,
40397	                null
40398	            ]
40399	        }
40400	    };
40401	};
40402	const cameraTargetIntrinsics = (element)=>{
40403	    const center = element[$scene].boundingBox.getCenter(new Vector3());
40404	    return {
40405	        basis: [
40406	            numberNode(center.x, 'm'),
40407	            numberNode(center.y, 'm'),
40408	            numberNode(center.z, 'm')
40409	        ],
40410	        keywords: {
40411	            auto: [
40412	                null,
40413	                null,
40414	                null
40415	            ]
40416	        }
40417	    };
40418	};
40419	const HALF_PI = Math.PI / 2.0;
40420	const THIRD_PI = Math.PI / 3.0;
40421	const QUARTER_PI = HALF_PI / 2.0;
40422	const TAU = 2.0 * Math.PI;
40423	const $controls = Symbol('controls');
40424	const $panElement = Symbol('panElement');
40425	const $promptElement = Symbol('promptElement');
40426	const $promptAnimatedContainer = Symbol('promptAnimatedContainer');
40427	const $fingerAnimatedContainers = Symbol('fingerAnimatedContainers');
40428	const $deferInteractionPrompt = Symbol('deferInteractionPrompt');
40429	const $updateAria = Symbol('updateAria');
40430	const $a11y = Symbol('a11y');
40431	const $updateA11y = Symbol('updateA11y');
40432	const $updateCameraForRadius = Symbol('updateCameraForRadius');
40433	const $cancelPrompts = Symbol('cancelPrompts');
40434	const $onChange = Symbol('onChange');
40435	const $onPointerChange = Symbol('onPointerChange');
40436	const $waitingToPromptUser = Symbol('waitingToPromptUser');
40437	const $userHasInteracted = Symbol('userHasInteracted');
40438	const $promptElementVisibleTime = Symbol('promptElementVisibleTime');
40439	const $lastPromptOffset = Symbol('lastPromptOffset');
40440	const $cancellationSource = Symbol('cancellationSource');
40441	const $lastSpherical = Symbol('lastSpherical');
40442	const $jumpCamera = Symbol('jumpCamera');
40443	const $initialized = Symbol('initialized');
40444	const $maintainThetaPhi = Symbol('maintainThetaPhi');
40445	const $syncCameraOrbit = Symbol('syncCameraOrbit');
40446	const $syncFieldOfView = Symbol('syncFieldOfView');
40447	const $syncCameraTarget = Symbol('syncCameraTarget');
40448	const $syncMinCameraOrbit = Symbol('syncMinCameraOrbit');
40449	const $syncMaxCameraOrbit = Symbol('syncMaxCameraOrbit');
40450	const $syncMinFieldOfView = Symbol('syncMinFieldOfView');
40451	const $syncMaxFieldOfView = Symbol('syncMaxFieldOfView');
40452	const ControlsMixin = (ModelViewerElement)=>{
40453	    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
vendor: 20,162 bytes, lines 40454-40885
40454	    class ControlsModelViewerElement extends ModelViewerElement {
40455	        get inputSensitivity() {
40456	            return this[$controls].inputSensitivity;
40457	        }
40458	        set inputSensitivity(value) {
40459	            this[$controls].inputSensitivity = value;
40460	        }
40461	        getCameraOrbit() {
40462	            const { theta, phi, radius } = this[$lastSpherical];
40463	            return {
40464	                theta,
40465	                phi,
40466	                radius,
40467	                toString () {
40468	                    return `${this.theta}rad ${this.phi}rad ${this.radius}m`;
40469	                }
40470	            };
40471	        }
40472	        getCameraTarget() {
40473	            return toVector3D(this[$renderer].isPresenting ? this[$renderer].arRenderer.target : this[$scene].getDynamicTarget());
40474	        }
40475	        getFieldOfView() {
40476	            return this[$controls].getFieldOfView();
40477	        }
40478	        getMinimumFieldOfView() {
40479	            return this[$controls].options.minimumFieldOfView;
40480	        }
40481	        getMaximumFieldOfView() {
40482	            return this[$controls].options.maximumFieldOfView;
40483	        }
40484	        getIdealAspect() {
40485	            return this[$scene].idealAspect;
40486	        }
40487	        jumpCameraToGoal() {
40488	            this[$jumpCamera] = true;
40489	            this.requestUpdate($jumpCamera, false);
40490	        }
40491	        resetInteractionPrompt() {
40492	            this[$lastPromptOffset] = 0;
40493	            this[$promptElementVisibleTime] = Infinity;
40494	            this[$userHasInteracted] = false;
40495	            this[$waitingToPromptUser] = this.interactionPrompt === InteractionPromptStrategy.AUTO && this.cameraControls;
40496	        }
40497	        zoom(keyPresses) {
40498	            const event = new WheelEvent('wheel', {
40499	                deltaY: -30 * keyPresses
40500	            });
40501	            this[$userInputElement].dispatchEvent(event);
40502	        }
40503	        connectedCallback() {
40504	            super.connectedCallback();
40505	            this[$controls].addEventListener('user-interaction', this[$cancelPrompts]);
40506	            this[$controls].addEventListener('pointer-change-start', this[$onPointerChange]);
40507	            this[$controls].addEventListener('pointer-change-end', this[$onPointerChange]);
40508	        }
40509	        disconnectedCallback() {
40510	            super.disconnectedCallback();
40511	            this[$controls].removeEventListener('user-interaction', this[$cancelPrompts]);
40512	            this[$controls].removeEventListener('pointer-change-start', this[$onPointerChange]);
40513	            this[$controls].removeEventListener('pointer-change-end', this[$onPointerChange]);
40514	        }
40515	        updated(changedProperties) {
40516	            super.updated(changedProperties);
40517	            const controls = this[$controls];
40518	            const scene = this[$scene];
40519	            if (changedProperties.has('cameraControls')) {
40520	                if (this.cameraControls) {
40521	                    controls.enableInteraction();
40522	                    if (this.interactionPrompt === InteractionPromptStrategy.AUTO) {
40523	                        this[$waitingToPromptUser] = true;
40524	                    }
40525	                } else {
40526	                    controls.disableInteraction();
40527	                    this[$deferInteractionPrompt]();
40528	                }
40529	                this[$userInputElement].setAttribute('aria-label', this[$ariaLabel]);
40530	            }
40531	            if (changedProperties.has('disableZoom')) {
40532	                controls.disableZoom = this.disableZoom;
40533	            }
40534	            if (changedProperties.has('disablePan')) {
40535	                controls.enablePan = !this.disablePan;
40536	            }
40537	            if (changedProperties.has('disableTap')) {
40538	                controls.enableTap = !this.disableTap;
40539	            }
40540	            if (changedProperties.has('interactionPrompt') || changedProperties.has('cameraControls') || changedProperties.has('src')) {
40541	                if (this.interactionPrompt === InteractionPromptStrategy.AUTO && this.cameraControls && !this[$userHasInteracted]) {
40542	                    this[$waitingToPromptUser] = true;
40543	                } else {
40544	                    this[$deferInteractionPrompt]();
40545	                }
40546	            }
40547	            if (changedProperties.has('interactionPromptStyle')) {
40548	                this[$promptAnimatedContainer].style.opacity = this.interactionPromptStyle == InteractionPromptStyle.BASIC ? '1' : '0';
40549	            }
40550	            if (changedProperties.has('touchAction')) {
40551	                const touchAction = this.touchAction;
40552	                controls.applyOptions({
40553	                    touchAction
40554	                });
40555	                controls.updateTouchActionStyle();
40556	            }
40557	            if (changedProperties.has('orbitSensitivity')) {
40558	                controls.orbitSensitivity = this.orbitSensitivity;
40559	            }
40560	            if (changedProperties.has('zoomSensitivity')) {
40561	                controls.zoomSensitivity = this.zoomSensitivity;
40562	            }
40563	            if (changedProperties.has('panSensitivity')) {
40564	                controls.panSensitivity = this.panSensitivity;
40565	            }
40566	            if (changedProperties.has('interpolationDecay')) {
40567	                controls.setDamperDecayTime(this.interpolationDecay);
40568	                scene.setTargetDamperDecayTime(this.interpolationDecay);
40569	            }
40570	            if (changedProperties.has('a11y')) {
40571	                this[$updateA11y]();
40572	            }
40573	            if (this[$jumpCamera] === true) {
40574	                Promise.resolve().then(()=>{
40575	                    controls.jumpToGoal();
40576	                    scene.jumpToGoal();
40577	                    this[$onChange]();
40578	                    this[$jumpCamera] = false;
40579	                });
40580	            }
40581	        }
40582	        async updateFraming() {
40583	            const scene = this[$scene];
40584	            const oldFramedFoV = scene.adjustedFoV(scene.framedFoVDeg);
40585	            await scene.updateFraming();
40586	            const newFramedFoV = scene.adjustedFoV(scene.framedFoVDeg);
40587	            const zoom = this[$controls].getFieldOfView() / oldFramedFoV;
40588	            this[$controls].setFieldOfView(newFramedFoV * zoom);
40589	            this[$maintainThetaPhi] = true;
40590	            this.requestUpdate('maxFieldOfView');
40591	            this.requestUpdate('fieldOfView');
40592	            this.requestUpdate('minCameraOrbit');
40593	            this.requestUpdate('maxCameraOrbit');
40594	            this.requestUpdate('cameraOrbit');
40595	            await this.updateComplete;
40596	        }
40597	        interact(duration, finger0, finger1) {
40598	            const inputElement = this[$userInputElement];
40599	            const fingerElements = this[$fingerAnimatedContainers];
40600	            if (fingerElements[0].style.opacity === '1') {
40601	                console.warn('interact() failed because an existing interaction is running.');
40602	                return;
40603	            }
40604	            const xy = new Array();
40605	            xy.push({
40606	                x: timeline(finger0.x),
40607	                y: timeline(finger0.y)
40608	            });
40609	            const positions = [
40610	                {
40611	                    x: xy[0].x(0),
40612	                    y: xy[0].y(0)
40613	                }
40614	            ];
40615	            if (finger1 != null) {
40616	                xy.push({
40617	                    x: timeline(finger1.x),
40618	                    y: timeline(finger1.y)
40619	                });
40620	                positions.push({
40621	                    x: xy[1].x(0),
40622	                    y: xy[1].y(0)
40623	                });
40624	            }
40625	            let startTime = performance.now();
40626	            const { width, height } = this[$scene];
40627	            const rect = this.getBoundingClientRect();
40628	            const dispatchTouches = (type)=>{
40629	                for (const [i, position] of positions.entries()){
40630	                    const { style } = fingerElements[i];
40631	                    style.transform = `translateX(${width * position.x}px) translateY(${height * position.y}px)`;
40632	                    if (type === 'pointerdown') {
40633	                        style.opacity = '1';
40634	                    } else if (type === 'pointerup') {
40635	                        style.opacity = '0';
40636	                    }
40637	                    const init = {
40638	                        pointerId: i - 5678,
40639	                        pointerType: 'touch',
40640	                        target: inputElement,
40641	                        clientX: width * position.x + rect.x,
40642	                        clientY: height * position.y + rect.y,
40643	                        altKey: true
40644	                    };
40645	                    inputElement.dispatchEvent(new PointerEvent(type, init));
40646	                }
40647	            };
40648	            const moveTouches = ()=>{
40649	                const changeSource = this[$cancellationSource];
40650	                if (changeSource !== ChangeSource.AUTOMATIC || !inputElement.isConnected) {
40651	                    for (const fingerElement of this[$fingerAnimatedContainers]){
40652	                        fingerElement.style.opacity = '0';
40653	                    }
40654	                    dispatchTouches('pointercancel');
40655	                    this.dispatchEvent(new CustomEvent('interact-stopped', {
40656	                        detail: {
40657	                            source: changeSource
40658	                        }
40659	                    }));
40660	                    document.removeEventListener('visibilitychange', onVisibilityChange);
40661	                    return;
40662	                }
40663	                const time = Math.min(1, (performance.now() - startTime) / duration);
40664	                for (const [i, position] of positions.entries()){
40665	                    position.x = xy[i].x(time);
40666	                    position.y = xy[i].y(time);
40667	                }
40668	                dispatchTouches('pointermove');
40669	                if (time < 1) {
40670	                    requestAnimationFrame(moveTouches);
40671	                } else {
40672	                    dispatchTouches('pointerup');
40673	                    this.dispatchEvent(new CustomEvent('interact-stopped', {
40674	                        detail: {
40675	                            source: ChangeSource.AUTOMATIC
40676	                        }
40677	                    }));
40678	                    document.removeEventListener('visibilitychange', onVisibilityChange);
40679	                }
40680	            };
40681	            const onVisibilityChange = ()=>{
40682	                let elapsed = 0;
40683	                if (document.visibilityState === 'hidden') {
40684	                    elapsed = performance.now() - startTime;
40685	                } else {
40686	                    startTime = performance.now() - elapsed;
40687	                }
40688	            };
40689	            document.addEventListener('visibilitychange', onVisibilityChange);
40690	            dispatchTouches('pointerdown');
40691	            this[$cancellationSource] = ChangeSource.AUTOMATIC;
40692	            requestAnimationFrame(moveTouches);
40693	        }
40694	        [(_a = $promptElement, _b = $promptAnimatedContainer, _c = $fingerAnimatedContainers, _d = $panElement, _e = $lastPromptOffset, _f = $promptElementVisibleTime, _g = $userHasInteracted, _h = $waitingToPromptUser, _j = $cancellationSource, _k = $controls, _l = $lastSpherical, _m = $jumpCamera, _o = $initialized, _p = $maintainThetaPhi, _q = $a11y, $syncFieldOfView)](style) {
40695	            const controls = this[$controls];
40696	            const scene = this[$scene];
40697	            scene.framedFoVDeg = style[0] * 180 / Math.PI;
40698	            controls.changeSource = ChangeSource.NONE;
40699	            controls.setFieldOfView(scene.adjustedFoV(scene.framedFoVDeg));
40700	            this[$cancelPrompts]();
40701	        }
40702	        [$syncCameraOrbit](style) {
40703	            const controls = this[$controls];
40704	            if (this[$maintainThetaPhi]) {
40705	                const { theta, phi } = this.getCameraOrbit();
40706	                style[0] = theta;
40707	                style[1] = phi;
40708	                this[$maintainThetaPhi] = false;
40709	            }
40710	            controls.changeSource = ChangeSource.NONE;
40711	            controls.setOrbit(style[0], style[1], style[2]);
40712	            this[$cancelPrompts]();
40713	        }
40714	        [$syncMinCameraOrbit](style) {
40715	            this[$controls].applyOptions({
40716	                minimumAzimuthalAngle: style[0],
40717	                minimumPolarAngle: style[1],
40718	                minimumRadius: style[2]
40719	            });
40720	            this.jumpCameraToGoal();
40721	        }
40722	        [$syncMaxCameraOrbit](style) {
40723	            this[$controls].applyOptions({
40724	                maximumAzimuthalAngle: style[0],
40725	                maximumPolarAngle: style[1],
40726	                maximumRadius: style[2]
40727	            });
40728	            this[$updateCameraForRadius](style[2]);
40729	            this.jumpCameraToGoal();
40730	        }
40731	        [$syncMinFieldOfView](style) {
40732	            this[$controls].applyOptions({
40733	                minimumFieldOfView: style[0] * 180 / Math.PI
40734	            });
40735	            this.jumpCameraToGoal();
40736	        }
40737	        [$syncMaxFieldOfView](style) {
40738	            const fov = this[$scene].adjustedFoV(style[0] * 180 / Math.PI);
40739	            this[$controls].applyOptions({
40740	                maximumFieldOfView: fov
40741	            });
40742	            this.jumpCameraToGoal();
40743	        }
40744	        [$syncCameraTarget](style) {
40745	            const [x, y, z] = style;
40746	            if (!this[$renderer].arRenderer.isPresenting) {
40747	                this[$scene].setTarget(x, y, z);
40748	            }
40749	            this[$controls].changeSource = ChangeSource.NONE;
40750	            this[$renderer].arRenderer.updateTarget();
40751	            this[$cancelPrompts]();
40752	        }
40753	        [$tick](time, delta) {
40754	            super[$tick](time, delta);
40755	            if (this[$renderer].isPresenting || !this[$getModelIsVisible]()) {
40756	                return;
40757	            }
40758	            const controls = this[$controls];
40759	            const scene = this[$scene];
40760	            const now = performance.now();
40761	            if (this[$waitingToPromptUser]) {
40762	                if (this.loaded && now > this[$loadedTime] + this.interactionPromptThreshold) {
40763	                    this[$waitingToPromptUser] = false;
40764	                    this[$promptElementVisibleTime] = now;
40765	                    this[$promptElement].classList.add('visible');
40766	                }
40767	            }
40768	            if (isFinite(this[$promptElementVisibleTime]) && this.interactionPromptStyle === InteractionPromptStyle.WIGGLE) {
40769	                const animationTime = (now - this[$promptElementVisibleTime]) / PROMPT_ANIMATION_TIME % 1;
40770	                const offset = wiggle(animationTime);
40771	                const opacity = fade(animationTime);
40772	                this[$promptAnimatedContainer].style.opacity = `${opacity}`;
40773	                if (offset !== this[$lastPromptOffset]) {
40774	                    const xOffset = offset * scene.width * 0.05;
40775	                    const deltaTheta = (offset - this[$lastPromptOffset]) * Math.PI / 16;
40776	                    this[$promptAnimatedContainer].style.transform = `translateX(${xOffset}px)`;
40777	                    controls.changeSource = ChangeSource.AUTOMATIC;
40778	                    controls.adjustOrbit(deltaTheta, 0, 0);
40779	                    this[$lastPromptOffset] = offset;
40780	                }
40781	            }
40782	            const cameraMoved = controls.update(time, delta);
40783	            const targetMoved = scene.updateTarget(delta);
40784	            if (cameraMoved || targetMoved) {
40785	                this[$onChange]();
40786	            }
40787	        }
40788	        [$deferInteractionPrompt]() {
40789	            this[$waitingToPromptUser] = false;
40790	            this[$promptElement].classList.remove('visible');
40791	            this[$promptElementVisibleTime] = Infinity;
40792	        }
40793	 [$updateCameraForRadius](radius) {
40794	            const maximumRadius = Math.max(this[$scene].farRadius(), radius);
40795	            const near = 0;
40796	            const far = Math.abs(2 * maximumRadius);
40797	            this[$controls].updateNearFar(near, far);
40798	        }
40799	        [$updateAria]() {
40800	            const { theta, phi } = this[$controls].getCameraSpherical(this[$lastSpherical]);
40801	            const azimuthalQuadrant = (4 + Math.floor((theta % TAU + QUARTER_PI) / HALF_PI)) % 4;
40802	            const polarTrient = Math.floor(phi / THIRD_PI);
40803	            const azimuthalQuadrantLabel = AZIMUTHAL_QUADRANT_LABELS[azimuthalQuadrant];
40804	            const polarTrientLabel = POLAR_TRIENT_LABELS[polarTrient];
40805	            const position = `${polarTrientLabel}${azimuthalQuadrantLabel}`;
40806	            const key = position;
40807	            if (key in this[$a11y]) {
40808	                this[$updateStatus](this[$a11y][key]);
40809	            } else {
40810	                this[$updateStatus](`View from stage ${position}`);
40811	            }
40812	        }
40813	        get [$ariaLabel]() {
40814	            let interactionPrompt = INTERACTION_PROMPT;
40815	            if ('interaction-prompt' in this[$a11y]) {
40816	                interactionPrompt = `. ${this[$a11y]['interaction-prompt']}`;
40817	            }
40818	            return super[$ariaLabel].replace(/\.$/, '') + (this.cameraControls ? interactionPrompt : '');
40819	        }
40820	        async [$onResize](event) {
40821	            const controls = this[$controls];
40822	            const scene = this[$scene];
40823	            const oldFramedFoV = scene.adjustedFoV(scene.framedFoVDeg);
40824	            super[$onResize](event);
40825	            const fovRatio = scene.adjustedFoV(scene.framedFoVDeg) / oldFramedFoV;
40826	            const fov = controls.getFieldOfView() * (isFinite(fovRatio) ? fovRatio : 1);
40827	            controls.updateAspect(this[$scene].aspect);
40828	            this.requestUpdate('maxFieldOfView', this.maxFieldOfView);
40829	            await this.updateComplete;
40830	            this[$controls].setFieldOfView(fov);
40831	            this.jumpCameraToGoal();
40832	        }
40833	        [$onModelLoad]() {
40834	            super[$onModelLoad]();
40835	            if (this[$initialized]) {
40836	                this[$maintainThetaPhi] = true;
40837	            } else {
40838	                this[$initialized] = true;
40839	            }
40840	            this.requestUpdate('maxFieldOfView', this.maxFieldOfView);
40841	            this.requestUpdate('fieldOfView', this.fieldOfView);
40842	            this.requestUpdate('minCameraOrbit', this.minCameraOrbit);
40843	            this.requestUpdate('maxCameraOrbit', this.maxCameraOrbit);
40844	            this.requestUpdate('cameraOrbit', this.cameraOrbit);
40845	            this.requestUpdate('cameraTarget', this.cameraTarget);
40846	            this.jumpCameraToGoal();
40847	        }
40848	        [(_r = $cancelPrompts, _s = $onChange, _t = $onPointerChange, $updateA11y)]() {
40849	            if (typeof this.a11y === 'string') {
40850	                if (this.a11y.startsWith('{')) {
40851	                    try {
40852	                        this[$a11y] = JSON.parse(this.a11y);
40853	                    } catch (error) {
40854	                        console.warn('Error parsing a11y JSON:', error);
40855	                    }
40856	                } else if (this.a11y.length > 0) {
40857	                    console.warn('Error not supported format, should be a JSON string:', this.a11y);
40858	                } else {
40859	                    this[$a11y] = {};
40860	                }
40861	            } else if (typeof this.a11y === 'object' && this.a11y != null) {
40862	                this[$a11y] = Object.assign({}, this.a11y);
40863	            } else {
40864	                this[$a11y] = {};
40865	            }
40866	            this[$userInputElement].setAttribute('aria-label', this[$ariaLabel]);
40867	        }
40868	        constructor(){
40869	            super(...arguments);
40870	            this.cameraControls = false;
40871	            this.cameraOrbit = DEFAULT_CAMERA_ORBIT;
40872	            this.cameraTarget = DEFAULT_CAMERA_TARGET;
40873	            this.fieldOfView = DEFAULT_FIELD_OF_VIEW;
40874	            this.minCameraOrbit = 'auto';
40875	            this.maxCameraOrbit = 'auto';
40876	            this.minFieldOfView = 'auto';
40877	            this.maxFieldOfView = 'auto';
40878	            this.interactionPromptThreshold = DEFAULT_INTERACTION_PROMPT_THRESHOLD;
40879	            this.interactionPrompt = InteractionPromptStrategy.AUTO;
40880	            this.interactionPromptStyle = InteractionPromptStyle.WIGGLE;
40881	            this.orbitSensitivity = 1;
40882	            this.zoomSensitivity = 1;
40883	            this.panSensitivity = 1;
40884	            this.touchAction = TouchAction.NONE;
40885	            this.disableZoom = false;
vendor: 7,563 bytes, lines 40886-41112
40886	            this.disablePan = false;
40887	            this.disableTap = false;
40888	            this.interpolationDecay = DECAY_MILLISECONDS;
40889	            this.a11y = null;
40890	            this[_a] = this.shadowRoot.querySelector('.interaction-prompt');
40891	            this[_b] = this.shadowRoot.querySelector('#prompt');
40892	            this[_c] = [
40893	                this.shadowRoot.querySelector('#finger0'),
40894	                this.shadowRoot.querySelector('#finger1')
40895	            ];
40896	            this[_d] = this.shadowRoot.querySelector('.pan-target');
40897	            this[_e] = 0;
40898	            this[_f] = Infinity;
40899	            this[_g] = false;
40900	            this[_h] = false;
40901	            this[_j] = ChangeSource.AUTOMATIC;
40902	            this[_k] = new SmoothControls(this[$scene].camera, this[$userInputElement], this[$scene]);
40903	            this[_l] = new Spherical();
40904	            this[_m] = false;
40905	            this[_o] = false;
40906	            this[_p] = false;
40907	            this[_q] = {};
40908	            this[_r] = ()=>{
40909	                const source = this[$controls].changeSource;
40910	                this[$cancellationSource] = source;
40911	                if (source === ChangeSource.USER_INTERACTION) {
40912	                    this[$userHasInteracted] = true;
40913	                    this[$deferInteractionPrompt]();
40914	                }
40915	            };
40916	            this[_s] = ()=>{
40917	                this[$updateAria]();
40918	                this[$needsRender]();
40919	                const source = this[$controls].changeSource;
40920	                this.dispatchEvent(new CustomEvent('camera-change', {
40921	                    detail: {
40922	                        source
40923	                    }
40924	                }));
40925	            };
40926	            this[_t] = (event)=>{
40927	                this[$container].classList.toggle('pointer-tumbling', event.type === 'pointer-change-start');
40928	            };
40929	        }
40930	    }
40931	    __decorate$6([
40932	        n$2({
40933	            type: Boolean,
40934	            attribute: 'camera-controls'
40935	        })
40936	    ], ControlsModelViewerElement.prototype, "cameraControls", void 0);
40937	    __decorate$6([
40938	        style({
40939	            intrinsics: cameraOrbitIntrinsics,
40940	            observeEffects: true,
40941	            updateHandler: $syncCameraOrbit
40942	        }),
40943	        n$2({
40944	            type: String,
40945	            attribute: 'camera-orbit',
40946	            hasChanged: ()=>true
40947	        })
40948	    ], ControlsModelViewerElement.prototype, "cameraOrbit", void 0);
40949	    __decorate$6([
40950	        style({
40951	            intrinsics: cameraTargetIntrinsics,
40952	            observeEffects: true,
40953	            updateHandler: $syncCameraTarget
40954	        }),
40955	        n$2({
40956	            type: String,
40957	            attribute: 'camera-target',
40958	            hasChanged: ()=>true
40959	        })
40960	    ], ControlsModelViewerElement.prototype, "cameraTarget", void 0);
40961	    __decorate$6([
40962	        style({
40963	            intrinsics: fieldOfViewIntrinsics,
40964	            observeEffects: true,
40965	            updateHandler: $syncFieldOfView
40966	        }),
40967	        n$2({
40968	            type: String,
40969	            attribute: 'field-of-view',
40970	            hasChanged: ()=>true
40971	        })
40972	    ], ControlsModelViewerElement.prototype, "fieldOfView", void 0);
40973	    __decorate$6([
40974	        style({
40975	            intrinsics: minCameraOrbitIntrinsics,
40976	            updateHandler: $syncMinCameraOrbit
40977	        }),
40978	        n$2({
40979	            type: String,
40980	            attribute: 'min-camera-orbit',
40981	            hasChanged: ()=>true
40982	        })
40983	    ], ControlsModelViewerElement.prototype, "minCameraOrbit", void 0);
40984	    __decorate$6([
40985	        style({
40986	            intrinsics: maxCameraOrbitIntrinsics,
40987	            updateHandler: $syncMaxCameraOrbit
40988	        }),
40989	        n$2({
40990	            type: String,
40991	            attribute: 'max-camera-orbit',
40992	            hasChanged: ()=>true
40993	        })
40994	    ], ControlsModelViewerElement.prototype, "maxCameraOrbit", void 0);
40995	    __decorate$6([
40996	        style({
40997	            intrinsics: minFieldOfViewIntrinsics,
40998	            updateHandler: $syncMinFieldOfView
40999	        }),
41000	        n$2({
41001	            type: String,
41002	            attribute: 'min-field-of-view',
41003	            hasChanged: ()=>true
41004	        })
41005	    ], ControlsModelViewerElement.prototype, "minFieldOfView", void 0);
41006	    __decorate$6([
41007	        style({
41008	            intrinsics: fieldOfViewIntrinsics,
41009	            updateHandler: $syncMaxFieldOfView
41010	        }),
41011	        n$2({
41012	            type: String,
41013	            attribute: 'max-field-of-view',
41014	            hasChanged: ()=>true
41015	        })
41016	    ], ControlsModelViewerElement.prototype, "maxFieldOfView", void 0);
41017	    __decorate$6([
41018	        n$2({
41019	            type: Number,
41020	            attribute: 'interaction-prompt-threshold'
41021	        })
41022	    ], ControlsModelViewerElement.prototype, "interactionPromptThreshold", void 0);
41023	    __decorate$6([
41024	        n$2({
41025	            type: String,
41026	            attribute: 'interaction-prompt'
41027	        })
41028	    ], ControlsModelViewerElement.prototype, "interactionPrompt", void 0);
41029	    __decorate$6([
41030	        n$2({
41031	            type: String,
41032	            attribute: 'interaction-prompt-style'
41033	        })
41034	    ], ControlsModelViewerElement.prototype, "interactionPromptStyle", void 0);
41035	    __decorate$6([
41036	        n$2({
41037	            type: Number,
41038	            attribute: 'orbit-sensitivity'
41039	        })
41040	    ], ControlsModelViewerElement.prototype, "orbitSensitivity", void 0);
41041	    __decorate$6([
41042	        n$2({
41043	            type: Number,
41044	            attribute: 'zoom-sensitivity'
41045	        })
41046	    ], ControlsModelViewerElement.prototype, "zoomSensitivity", void 0);
41047	    __decorate$6([
41048	        n$2({
41049	            type: Number,
41050	            attribute: 'pan-sensitivity'
41051	        })
41052	    ], ControlsModelViewerElement.prototype, "panSensitivity", void 0);
41053	    __decorate$6([
41054	        n$2({
41055	            type: String,
41056	            attribute: 'touch-action'
41057	        })
41058	    ], ControlsModelViewerElement.prototype, "touchAction", void 0);
41059	    __decorate$6([
41060	        n$2({
41061	            type: Boolean,
41062	            attribute: 'disable-zoom'
41063	        })
41064	    ], ControlsModelViewerElement.prototype, "disableZoom", void 0);
41065	    __decorate$6([
41066	        n$2({
41067	            type: Boolean,
41068	            attribute: 'disable-pan'
41069	        })
41070	    ], ControlsModelViewerElement.prototype, "disablePan", void 0);
41071	    __decorate$6([
41072	        n$2({
41073	            type: Boolean,
41074	            attribute: 'disable-tap'
41075	        })
41076	    ], ControlsModelViewerElement.prototype, "disableTap", void 0);
41077	    __decorate$6([
41078	        n$2({
41079	            type: Number,
41080	            attribute: 'interpolation-decay'
41081	        })
41082	    ], ControlsModelViewerElement.prototype, "interpolationDecay", void 0);
41083	    __decorate$6([
41084	        n$2()
41085	    ], ControlsModelViewerElement.prototype, "a11y", void 0);
41086	    return ControlsModelViewerElement;
41087	};
41088
41089	const PAN_SENSITIVITY = 0.018;
41090	const TAP_DISTANCE = 2;
41091	const TAP_MS = 300;
41092	const vector2 = new Vector2();
41093	const vector3$2 = new Vector3();
41094	const DEFAULT_OPTIONS = Object.freeze({
41095	    minimumRadius: 0,
41096	    maximumRadius: Infinity,
41097	    minimumPolarAngle: 0,
41098	    maximumPolarAngle: Math.PI,
41099	    minimumAzimuthalAngle: -Infinity,
41100	    maximumAzimuthalAngle: Infinity,
41101	    minimumFieldOfView: 10,
41102	    maximumFieldOfView: 45,
41103	    touchAction: 'none'
41104	});
41105	const KEYBOARD_ORBIT_INCREMENT = Math.PI / 8;
41106	const ZOOM_SENSITIVITY = 0.04;
41107	const PAN_KEY_INCREMENT = 10;
41108	const ChangeSource = {
41109	    USER_INTERACTION: 'user-interaction',
41110	    NONE: 'none',
41111	    AUTOMATIC: 'automatic'
41112	};
vendor: 9,631 bytes, lines 41113-41317
41113	 class SmoothControls extends EventDispatcher {
41114	    get interactionEnabled() {
41115	        return this._interactionEnabled;
41116	    }
41117	    enableInteraction() {
41118	        if (this._interactionEnabled === false) {
41119	            const { element } = this;
41120	            element.addEventListener('pointerdown', this.onPointerDown);
41121	            element.addEventListener('pointercancel', this.onPointerUp);
41122	            if (!this._disableZoom) {
41123	                element.addEventListener('wheel', this.onWheel);
41124	            }
41125	            element.addEventListener('keydown', this.onKeyDown);
41126	            element.addEventListener('touchmove', ()=>{}, {
41127	                passive: false
41128	            });
41129	            element.addEventListener('contextmenu', this.onContext);
41130	            this.element.style.cursor = 'grab';
41131	            this._interactionEnabled = true;
41132	            this.updateTouchActionStyle();
41133	        }
41134	    }
41135	    disableInteraction() {
41136	        if (this._interactionEnabled === true) {
41137	            const { element } = this;
41138	            element.removeEventListener('pointerdown', this.onPointerDown);
41139	            element.removeEventListener('pointermove', this.onPointerMove);
41140	            element.removeEventListener('pointerup', this.onPointerUp);
41141	            element.removeEventListener('pointercancel', this.onPointerUp);
41142	            element.removeEventListener('wheel', this.onWheel);
41143	            element.removeEventListener('keydown', this.onKeyDown);
41144	            element.removeEventListener('contextmenu', this.onContext);
41145	            element.style.cursor = '';
41146	            this.touchMode = null;
41147	            this._interactionEnabled = false;
41148	            this.updateTouchActionStyle();
41149	        }
41150	    }
41151	 get options() {
41152	        return this._options;
41153	    }
41154	    set disableZoom(disable) {
41155	        if (this._disableZoom != disable) {
41156	            this._disableZoom = disable;
41157	            if (disable === true) {
41158	                this.element.removeEventListener('wheel', this.onWheel);
41159	            } else {
41160	                this.element.addEventListener('wheel', this.onWheel);
41161	            }
41162	            this.updateTouchActionStyle();
41163	        }
41164	    }
41165	 getCameraSpherical(target = new Spherical()) {
41166	        return target.copy(this.spherical);
41167	    }
41168	 getFieldOfView() {
41169	        return this.camera.fov;
41170	    }
41171	 applyOptions(_options) {
41172	        Object.assign(this._options, _options);
41173	        this.setOrbit();
41174	        this.setFieldOfView(Math.exp(this.goalLogFov));
41175	    }
41176	 updateNearFar(nearPlane, farPlane) {
41177	        this.camera.far = farPlane === 0 ? 2 : farPlane;
41178	        this.camera.near = Math.max(nearPlane, this.camera.far / 1000);
41179	        this.camera.updateProjectionMatrix();
41180	    }
41181	 updateAspect(aspect) {
41182	        this.camera.aspect = aspect;
41183	        this.camera.updateProjectionMatrix();
41184	    }
41185	 setOrbit(goalTheta = this.goalSpherical.theta, goalPhi = this.goalSpherical.phi, goalRadius = this.goalSpherical.radius) {
41186	        const { minimumAzimuthalAngle, maximumAzimuthalAngle, minimumPolarAngle, maximumPolarAngle, minimumRadius, maximumRadius } = this._options;
41187	        const { theta, phi, radius } = this.goalSpherical;
41188	        const nextTheta = clamp(goalTheta, minimumAzimuthalAngle, maximumAzimuthalAngle);
41189	        if (!isFinite(minimumAzimuthalAngle) && !isFinite(maximumAzimuthalAngle)) {
41190	            this.spherical.theta = this.wrapAngle(this.spherical.theta - nextTheta) + nextTheta;
41191	        }
41192	        const nextPhi = clamp(goalPhi, minimumPolarAngle, maximumPolarAngle);
41193	        const nextRadius = clamp(goalRadius, minimumRadius, maximumRadius);
41194	        if (nextTheta === theta && nextPhi === phi && nextRadius === radius) {
41195	            return false;
41196	        }
41197	        if (!isFinite(nextTheta) || !isFinite(nextPhi) || !isFinite(nextRadius)) {
41198	            return false;
41199	        }
41200	        this.goalSpherical.theta = nextTheta;
41201	        this.goalSpherical.phi = nextPhi;
41202	        this.goalSpherical.radius = nextRadius;
41203	        this.goalSpherical.makeSafe();
41204	        return true;
41205	    }
41206	 setRadius(radius) {
41207	        this.goalSpherical.radius = radius;
41208	        this.setOrbit();
41209	    }
41210	 setFieldOfView(fov) {
41211	        const { minimumFieldOfView, maximumFieldOfView } = this._options;
41212	        fov = clamp(fov, minimumFieldOfView, maximumFieldOfView);
41213	        this.goalLogFov = Math.log(fov);
41214	    }
41215	 setDamperDecayTime(decayMilliseconds) {
41216	        this.thetaDamper.setDecayTime(decayMilliseconds);
41217	        this.phiDamper.setDecayTime(decayMilliseconds);
41218	        this.radiusDamper.setDecayTime(decayMilliseconds);
41219	        this.fovDamper.setDecayTime(decayMilliseconds);
41220	    }
41221	 adjustOrbit(deltaTheta, deltaPhi, deltaZoom) {
41222	        const { theta, phi, radius } = this.goalSpherical;
41223	        const { minimumRadius, maximumRadius, minimumFieldOfView, maximumFieldOfView } = this._options;
41224	        const dTheta = this.spherical.theta - theta;
41225	        const dThetaLimit = Math.PI - 0.001;
41226	        const goalTheta = theta - clamp(deltaTheta, -dThetaLimit - dTheta, dThetaLimit - dTheta);
41227	        const goalPhi = phi - deltaPhi;
41228	        const deltaRatio = deltaZoom === 0 ? 0 : ((deltaZoom > 0 ? maximumRadius : minimumRadius) - radius) / (Math.log(deltaZoom > 0 ? maximumFieldOfView : minimumFieldOfView) - this.goalLogFov);
41229	        const goalRadius = radius + deltaZoom * (isFinite(deltaRatio) ? deltaRatio : (maximumRadius - minimumRadius) * 2);
41230	        this.setOrbit(goalTheta, goalPhi, goalRadius);
41231	        if (deltaZoom !== 0) {
41232	            const goalLogFov = this.goalLogFov + deltaZoom;
41233	            this.setFieldOfView(Math.exp(goalLogFov));
41234	        }
41235	    }
41236	 jumpToGoal() {
41237	        this.update(0, SETTLING_TIME);
41238	    }
41239	 update(_time, delta) {
41240	        if (this.isStationary()) {
41241	            return false;
41242	        }
41243	        const { maximumPolarAngle, maximumRadius } = this._options;
41244	        const dTheta = this.spherical.theta - this.goalSpherical.theta;
41245	        if (Math.abs(dTheta) > Math.PI && !isFinite(this._options.minimumAzimuthalAngle) && !isFinite(this._options.maximumAzimuthalAngle)) {
41246	            this.spherical.theta -= Math.sign(dTheta) * 2 * Math.PI;
41247	        }
41248	        this.spherical.theta = this.thetaDamper.update(this.spherical.theta, this.goalSpherical.theta, delta, Math.PI);
41249	        this.spherical.phi = this.phiDamper.update(this.spherical.phi, this.goalSpherical.phi, delta, maximumPolarAngle);
41250	        this.spherical.radius = this.radiusDamper.update(this.spherical.radius, this.goalSpherical.radius, delta, maximumRadius);
41251	        this.logFov = this.fovDamper.update(this.logFov, this.goalLogFov, delta, 1);
41252	        this.moveCamera();
41253	        return true;
41254	    }
41255	    updateTouchActionStyle() {
41256	        const { style } = this.element;
41257	        if (this._interactionEnabled) {
41258	            const { touchAction } = this._options;
41259	            if (this._disableZoom && touchAction !== 'none') {
41260	                style.touchAction = 'manipulation';
41261	            } else {
41262	                style.touchAction = touchAction;
41263	            }
41264	        } else {
41265	            style.touchAction = '';
41266	        }
41267	    }
41268	    isStationary() {
41269	        return this.goalSpherical.theta === this.spherical.theta && this.goalSpherical.phi === this.spherical.phi && this.goalSpherical.radius === this.spherical.radius && this.goalLogFov === this.logFov;
41270	    }
41271	    moveCamera() {
41272	        this.spherical.makeSafe();
41273	        this.camera.position.setFromSpherical(this.spherical);
41274	        this.camera.setRotationFromEuler(new Euler(this.spherical.phi - Math.PI / 2, this.spherical.theta, 0, 'YXZ'));
41275	        if (this.camera.fov !== Math.exp(this.logFov)) {
41276	            this.camera.fov = Math.exp(this.logFov);
41277	            this.camera.updateProjectionMatrix();
41278	        }
41279	    }
41280	    userAdjustOrbit(deltaTheta, deltaPhi, deltaZoom) {
41281	        this.adjustOrbit(deltaTheta * this.orbitSensitivity * this.inputSensitivity, deltaPhi * this.orbitSensitivity * this.inputSensitivity, deltaZoom * this.inputSensitivity);
41282	    }
41283	    wrapAngle(radians) {
41284	        const normalized = (radians + Math.PI) / (2 * Math.PI);
41285	        const wrapped = normalized - Math.floor(normalized);
41286	        return wrapped * 2 * Math.PI - Math.PI;
41287	    }
41288	    pixelLengthToSphericalAngle(pixelLength) {
41289	        return 2 * Math.PI * pixelLength / this.scene.height;
41290	    }
41291	    twoTouchDistance(touchOne, touchTwo) {
41292	        const { clientX: xOne, clientY: yOne } = touchOne;
41293	        const { clientX: xTwo, clientY: yTwo } = touchTwo;
41294	        const xDelta = xTwo - xOne;
41295	        const yDelta = yTwo - yOne;
41296	        return Math.sqrt(xDelta * xDelta + yDelta * yDelta);
41297	    }
41298	    handleSinglePointerMove(dx, dy) {
41299	        const deltaTheta = this.pixelLengthToSphericalAngle(dx);
41300	        const deltaPhi = this.pixelLengthToSphericalAngle(dy);
41301	        if (this.isUserPointing === false) {
41302	            this.isUserPointing = true;
41303	            this.dispatchEvent({
41304	                type: 'pointer-change-start'
41305	            });
41306	        }
41307	        this.userAdjustOrbit(deltaTheta, deltaPhi, 0);
41308	    }
41309	    initializePan() {
41310	        const { theta, phi } = this.spherical;
41311	        const psi = theta - this.scene.yaw;
41312	        this.panPerPixel = PAN_SENSITIVITY * this.panSensitivity / this.scene.height;
41313	        this.panProjection.set(-Math.cos(psi), -Math.cos(phi) * Math.sin(psi), 0, 0, Math.sin(phi), 0, Math.sin(psi), -Math.cos(phi) * Math.cos(psi), 0);
41314	    }
41315	    movePan(dx, dy) {
41316	        const { scene } = this;
41317	        const dxy = vector3$2.set(dx, dy, 0).multiplyScalar(this.inputSensitivity);
vendor: 5,343 bytes, lines 41318-41448
41318	        const metersPerPixel = this.spherical.radius * Math.exp(this.logFov) * this.panPerPixel;
41319	        dxy.multiplyScalar(metersPerPixel);
41320	        const target = scene.getTarget();
41321	        target.add(dxy.applyMatrix3(this.panProjection));
41322	        scene.boundingSphere.clampPoint(target, target);
41323	        scene.setTarget(target.x, target.y, target.z);
41324	    }
41325	    recenter(pointer) {
41326	        if (performance.now() > this.startTime + TAP_MS || Math.abs(pointer.clientX - this.startPointerPosition.clientX) > TAP_DISTANCE || Math.abs(pointer.clientY - this.startPointerPosition.clientY) > TAP_DISTANCE) {
41327	            return;
41328	        }
41329	        const { scene } = this;
41330	        const hit = scene.positionAndNormalFromPoint(scene.getNDC(pointer.clientX, pointer.clientY));
41331	        if (hit == null) {
41332	            const { cameraTarget } = scene.element;
41333	            scene.element.cameraTarget = '';
41334	            scene.element.cameraTarget = cameraTarget;
41335	            this.userAdjustOrbit(0, 0, 1);
41336	        } else {
41337	            scene.target.worldToLocal(hit.position);
41338	            scene.setTarget(hit.position.x, hit.position.y, hit.position.z);
41339	        }
41340	    }
41341	    resetRadius() {
41342	        const { scene } = this;
41343	        const hit = scene.positionAndNormalFromPoint(vector2.set(0, 0));
41344	        if (hit == null) {
41345	            return;
41346	        }
41347	        scene.target.worldToLocal(hit.position);
41348	        const goalTarget = scene.getTarget();
41349	        const { theta, phi } = this.spherical;
41350	        const psi = theta - scene.yaw;
41351	        const n = vector3$2.set(Math.sin(phi) * Math.sin(psi), Math.cos(phi), Math.sin(phi) * Math.cos(psi));
41352	        const dr = n.dot(hit.position.sub(goalTarget));
41353	        goalTarget.add(n.multiplyScalar(dr));
41354	        scene.setTarget(goalTarget.x, goalTarget.y, goalTarget.z);
41355	        this.setOrbit(undefined, undefined, this.goalSpherical.radius - dr);
41356	    }
41357	    onTouchChange(event) {
41358	        if (this.pointers.length === 1) {
41359	            this.touchMode = this.touchModeRotate;
41360	        } else {
41361	            if (this._disableZoom) {
41362	                this.touchMode = null;
41363	                this.element.removeEventListener('touchmove', this.disableScroll);
41364	                return;
41365	            }
41366	            this.touchMode = this.touchDecided && this.touchMode === null ? null : this.touchModeZoom;
41367	            this.touchDecided = true;
41368	            this.element.addEventListener('touchmove', this.disableScroll, {
41369	                passive: false
41370	            });
41371	            this.lastSeparation = this.twoTouchDistance(this.pointers[0], this.pointers[1]);
41372	            if (this.enablePan && this.touchMode != null) {
41373	                this.initializePan();
41374	                if (!event.altKey) {
41375	                    this.scene.element[$panElement].style.opacity = 1;
41376	                }
41377	            }
41378	        }
41379	    }
41380	    onMouseDown(event) {
41381	        this.panPerPixel = 0;
41382	        if (this.enablePan && (event.button === 2 || event.ctrlKey || event.metaKey || event.shiftKey)) {
41383	            this.initializePan();
41384	            this.scene.element[$panElement].style.opacity = 1;
41385	        }
41386	        this.element.style.cursor = 'grabbing';
41387	    }
41388	 orbitZoomKeyCodeHandler(event) {
41389	        let relevantKey = true;
41390	        switch(event.key){
41391	            case 'PageUp':
41392	                this.userAdjustOrbit(0, 0, ZOOM_SENSITIVITY * this.zoomSensitivity);
41393	                break;
41394	            case 'PageDown':
41395	                this.userAdjustOrbit(0, 0, -1 * ZOOM_SENSITIVITY * this.zoomSensitivity);
41396	                break;
41397	            case 'ArrowUp':
41398	                this.userAdjustOrbit(0, -KEYBOARD_ORBIT_INCREMENT, 0);
41399	                break;
41400	            case 'ArrowDown':
41401	                this.userAdjustOrbit(0, KEYBOARD_ORBIT_INCREMENT, 0);
41402	                break;
41403	            case 'ArrowLeft':
41404	                this.userAdjustOrbit(-KEYBOARD_ORBIT_INCREMENT, 0, 0);
41405	                break;
41406	            case 'ArrowRight':
41407	                this.userAdjustOrbit(KEYBOARD_ORBIT_INCREMENT, 0, 0);
41408	                break;
41409	            default:
41410	                relevantKey = false;
41411	                break;
41412	        }
41413	        return relevantKey;
41414	    }
41415	 panKeyCodeHandler(event) {
41416	        this.initializePan();
41417	        let relevantKey = true;
41418	        switch(event.key){
41419	            case 'ArrowUp':
41420	                this.movePan(0, -1 * PAN_KEY_INCREMENT);
41421	                break;
41422	            case 'ArrowDown':
41423	                this.movePan(0, PAN_KEY_INCREMENT);
41424	                break;
41425	            case 'ArrowLeft':
41426	                this.movePan(-1 * PAN_KEY_INCREMENT, 0);
41427	                break;
41428	            case 'ArrowRight':
41429	                this.movePan(PAN_KEY_INCREMENT, 0);
41430	                break;
41431	            default:
41432	                relevantKey = false;
41433	                break;
41434	        }
41435	        return relevantKey;
41436	    }
41437	    constructor(camera, element, scene){
41438	        super();
41439	        this.camera = camera;
41440	        this.element = element;
41441	        this.scene = scene;
41442	        this.orbitSensitivity = 1;
41443	        this.zoomSensitivity = 1;
41444	        this.panSensitivity = 1;
41445	        this.inputSensitivity = 1;
41446	        this.changeSource = ChangeSource.NONE;
41447	        this._interactionEnabled = false;
41448	        this._disableZoom = false;
vendor: 11,686 bytes, lines 41449-41737
41449	        this.isUserPointing = false;
41450	        this.enablePan = true;
41451	        this.enableTap = true;
41452	        this.panProjection = new Matrix3();
41453	        this.panPerPixel = 0;
41454	        this.spherical = new Spherical();
41455	        this.goalSpherical = new Spherical();
41456	        this.thetaDamper = new Damper();
41457	        this.phiDamper = new Damper();
41458	        this.radiusDamper = new Damper();
41459	        this.logFov = Math.log(DEFAULT_OPTIONS.maximumFieldOfView);
41460	        this.goalLogFov = this.logFov;
41461	        this.fovDamper = new Damper();
41462	        this.touchMode = null;
41463	        this.pointers = [];
41464	        this.startTime = 0;
41465	        this.startPointerPosition = {
41466	            clientX: 0,
41467	            clientY: 0
41468	        };
41469	        this.lastSeparation = 0;
41470	        this.touchDecided = false;
41471	        this.onContext = (event)=>{
41472	            if (this.enablePan) {
41473	                event.preventDefault();
41474	            } else {
41475	                for (const pointer of this.pointers){
41476	                    this.onPointerUp(new PointerEvent('pointercancel', Object.assign(Object.assign({}, this.startPointerPosition), {
41477	                        pointerId: pointer.id
41478	                    })));
41479	                }
41480	            }
41481	        };
41482	        this.touchModeZoom = (dx, dy)=>{
41483	            if (!this._disableZoom) {
41484	                const touchDistance = this.twoTouchDistance(this.pointers[0], this.pointers[1]);
41485	                const deltaZoom = ZOOM_SENSITIVITY * this.zoomSensitivity * (this.lastSeparation - touchDistance) * 50 / this.scene.height;
41486	                this.lastSeparation = touchDistance;
41487	                this.userAdjustOrbit(0, 0, deltaZoom);
41488	            }
41489	            if (this.panPerPixel > 0) {
41490	                this.movePan(dx, dy);
41491	            }
41492	        };
41493	        this.disableScroll = (event)=>{
41494	            event.preventDefault();
41495	        };
41496	        this.touchModeRotate = (dx, dy)=>{
41497	            const { touchAction } = this._options;
41498	            if (!this.touchDecided && touchAction !== 'none') {
41499	                this.touchDecided = true;
41500	                const dxMag = Math.abs(dx);
41501	                const dyMag = Math.abs(dy);
41502	                if (this.changeSource === ChangeSource.USER_INTERACTION && (touchAction === 'pan-y' && dyMag > dxMag || touchAction === 'pan-x' && dxMag > dyMag)) {
41503	                    this.touchMode = null;
41504	                    return;
41505	                } else {
41506	                    this.element.addEventListener('touchmove', this.disableScroll, {
41507	                        passive: false
41508	                    });
41509	                }
41510	            }
41511	            this.handleSinglePointerMove(dx, dy);
41512	        };
41513	        this.onPointerDown = (event)=>{
41514	            if (this.pointers.length > 2) {
41515	                return;
41516	            }
41517	            const { element } = this;
41518	            if (this.pointers.length === 0) {
41519	                element.addEventListener('pointermove', this.onPointerMove);
41520	                element.addEventListener('pointerup', this.onPointerUp);
41521	                this.touchMode = null;
41522	                this.touchDecided = false;
41523	                this.startPointerPosition.clientX = event.clientX;
41524	                this.startPointerPosition.clientY = event.clientY;
41525	                this.startTime = performance.now();
41526	            }
41527	            try {
41528	                element.setPointerCapture(event.pointerId);
41529	            } catch (_a) {}
41530	            this.pointers.push({
41531	                clientX: event.clientX,
41532	                clientY: event.clientY,
41533	                id: event.pointerId
41534	            });
41535	            this.isUserPointing = false;
41536	            if (event.pointerType === 'touch') {
41537	                this.changeSource = event.altKey ? ChangeSource.AUTOMATIC : ChangeSource.USER_INTERACTION;
41538	                this.onTouchChange(event);
41539	            } else {
41540	                this.changeSource = ChangeSource.USER_INTERACTION;
41541	                this.onMouseDown(event);
41542	            }
41543	            if (this.changeSource === ChangeSource.USER_INTERACTION) {
41544	                this.dispatchEvent({
41545	                    type: 'user-interaction'
41546	                });
41547	            }
41548	        };
41549	        this.onPointerMove = (event)=>{
41550	            const pointer = this.pointers.find((pointer)=>pointer.id === event.pointerId);
41551	            if (pointer == null) {
41552	                return;
41553	            }
41554	            if (event.pointerType === 'mouse' && event.buttons === 0) {
41555	                this.onPointerUp(event);
41556	                return;
41557	            }
41558	            const numTouches = this.pointers.length;
41559	            const dx = (event.clientX - pointer.clientX) / numTouches;
41560	            const dy = (event.clientY - pointer.clientY) / numTouches;
41561	            if (dx === 0 && dy === 0) {
41562	                return;
41563	            }
41564	            pointer.clientX = event.clientX;
41565	            pointer.clientY = event.clientY;
41566	            if (event.pointerType === 'touch') {
41567	                this.changeSource = event.altKey ? ChangeSource.AUTOMATIC : ChangeSource.USER_INTERACTION;
41568	                if (this.touchMode !== null) {
41569	                    this.touchMode(dx, dy);
41570	                }
41571	            } else {
41572	                this.changeSource = ChangeSource.USER_INTERACTION;
41573	                if (this.panPerPixel > 0) {
41574	                    this.movePan(dx, dy);
41575	                } else {
41576	                    this.handleSinglePointerMove(dx, dy);
41577	                }
41578	            }
41579	        };
41580	        this.onPointerUp = (event)=>{
41581	            const { element } = this;
41582	            const index = this.pointers.findIndex((pointer)=>pointer.id === event.pointerId);
41583	            if (index !== -1) {
41584	                this.pointers.splice(index, 1);
41585	            }
41586	            if (this.panPerPixel > 0 && !event.altKey) {
41587	                this.resetRadius();
41588	            }
41589	            if (this.pointers.length === 0) {
41590	                element.removeEventListener('pointermove', this.onPointerMove);
41591	                element.removeEventListener('pointerup', this.onPointerUp);
41592	                element.removeEventListener('touchmove', this.disableScroll);
41593	                if (this.enablePan && this.enableTap) {
41594	                    this.recenter(event);
41595	                }
41596	            } else if (this.touchMode !== null) {
41597	                this.onTouchChange(event);
41598	            }
41599	            this.scene.element[$panElement].style.opacity = 0;
41600	            element.style.cursor = 'grab';
41601	            this.panPerPixel = 0;
41602	            if (this.isUserPointing) {
41603	                this.dispatchEvent({
41604	                    type: 'pointer-change-end'
41605	                });
41606	            }
41607	        };
41608	        this.onWheel = (event)=>{
41609	            this.changeSource = ChangeSource.USER_INTERACTION;
41610	            const deltaZoom = event.deltaY * (event.deltaMode == 1 ? 18 : 1) * ZOOM_SENSITIVITY * this.zoomSensitivity / 30;
41611	            this.userAdjustOrbit(0, 0, deltaZoom);
41612	            event.preventDefault();
41613	            this.dispatchEvent({
41614	                type: 'user-interaction'
41615	            });
41616	        };
41617	        this.onKeyDown = (event)=>{
41618	            const { changeSource } = this;
41619	            this.changeSource = ChangeSource.USER_INTERACTION;
41620	            const relevantKey = event.shiftKey && this.enablePan ? this.panKeyCodeHandler(event) : this.orbitZoomKeyCodeHandler(event);
41621	            if (relevantKey) {
41622	                event.preventDefault();
41623	                this.dispatchEvent({
41624	                    type: 'user-interaction'
41625	                });
41626	            } else {
41627	                this.changeSource = changeSource;
41628	            }
41629	        };
41630	        this._options = Object.assign({}, DEFAULT_OPTIONS);
41631	        this.setOrbit(0, Math.PI / 2, 1);
41632	        this.setFieldOfView(100);
41633	        this.jumpToGoal();
41634	    }
41635	}
41636
41637	const INIT_FRAMES = 30;
41638	const AR_SHADOW_INTENSITY = 0.8;
41639	const ROTATION_RATE = 1.5;
41640	const HIT_ANGLE_DEG = 20;
41641	const SCALE_SNAP = 0.2;
41642	const MIN_VIEWPORT_SCALE = 0.25;
41643	const MAX_DISTANCE = 10;
41644	const DECAY = 150;
41645	const MAX_LINE_LENGTH = 5;
41646	const BOX_SIZE = 0.1;
41647	const ARStatus = {
41648	    NOT_PRESENTING: 'not-presenting',
41649	    SESSION_STARTED: 'session-started',
41650	    OBJECT_PLACED: 'object-placed',
41651	    FAILED: 'failed'
41652	};
41653	const ARTracking = {
41654	    TRACKING: 'tracking',
41655	    NOT_TRACKING: 'not-tracking'
41656	};
41657	const vector3$1 = new Vector3();
41658	const quaternion = new Quaternion();
41659	const matrix4 = new Matrix4();
41660	const hitPosition = new Vector3();
41661	const camera = new PerspectiveCamera(45, 1, 0.1, 100);
41662	const lineGeometry = new BufferGeometry().setFromPoints([
41663	    new Vector3(0, 0, 0),
41664	    new Vector3(0, 0, -1)
41665	]);
41666	const boxGeometry = new BoxGeometry();
41667	class ARRenderer extends EventDispatcher {
41668	    async resolveARSession() {
41669	        assertIsArCandidate();
41670	        const session = await navigator.xr.requestSession('immersive-ar', {
41671	            requiredFeatures: [],
41672	            optionalFeatures: [
41673	                'hit-test',
41674	                'dom-overlay',
41675	                'light-estimation'
41676	            ],
41677	            domOverlay: this.overlay ? {
41678	                root: this.overlay
41679	            } : undefined
41680	        });
41681	        this.threeRenderer.xr.setReferenceSpaceType('local');
41682	        await this.threeRenderer.xr.setSession(session);
41683	        this.threeRenderer.xr.cameraAutoUpdate = false;
41684	        return session;
41685	    }
41686	 get presentedScene() {
41687	        return this._presentedScene;
41688	    }
41689	 async supportsPresentation() {
41690	        try {
41691	            assertIsArCandidate();
41692	            return await navigator.xr.isSessionSupported('immersive-ar');
41693	        } catch (error) {
41694	            console.warn('Request to present in WebXR denied:');
41695	            console.warn(error);
41696	            console.warn('Falling back to next ar-mode');
41697	            return false;
41698	        }
41699	    }
41700	 async present(scene, environmentEstimation = false) {
41701	        if (this.isPresenting) {
41702	            console.warn('Cannot present while a model is already presenting');
41703	        }
41704	        let waitForAnimationFrame = new Promise((resolve, _reject)=>{
41705	            requestAnimationFrame(()=>resolve());
41706	        });
41707	        scene.setHotspotsVisibility(false);
41708	        scene.queueRender();
41709	        await waitForAnimationFrame;
41710	        this._presentedScene = scene;
41711	        this.overlay = scene.element.shadowRoot.querySelector('div.default');
41712	        if (environmentEstimation === true) {
41713	            this.xrLight = new XREstimatedLight(this.threeRenderer);
41714	            this.xrLight.addEventListener('estimationstart', ()=>{
41715	                if (!this.isPresenting || this.xrLight == null) {
41716	                    return;
41717	                }
41718	                const scene = this.presentedScene;
41719	                scene.add(this.xrLight);
41720	                scene.environment = this.xrLight.environment;
41721	            });
41722	        }
41723	        const currentSession = await this.resolveARSession();
41724	        currentSession.addEventListener('end', ()=>{
41725	            this.postSessionCleanup();
41726	        }, {
41727	            once: true
41728	        });
41729	        const exitButton = scene.element.shadowRoot.querySelector('.slot.exit-webxr-ar-button');
41730	        exitButton.classList.add('enabled');
41731	        exitButton.addEventListener('click', this.onExitWebXRButtonContainerClick);
41732	        this.exitWebXRButtonContainer = exitButton;
41733	        const viewerRefSpace = await currentSession.requestReferenceSpace('viewer');
41734	        this.xrMode = currentSession.interactionMode;
41735	        this.tracking = true;
41736	        this.frames = 0;
41737	        this.initialized = false;
41738	        this.turntableRotation = scene.yaw;
41739	        this.goalYaw = scene.yaw;
41740	        this.goalScale = 1;
41741	        scene.setBackground(null);
41742	        this.oldShadowIntensity = scene.shadowIntensity;
41743	        scene.setShadowIntensity(0.01);
41744	        this.oldTarget.copy(scene.getTarget());
41745	        scene.element.addEventListener('load', this.onUpdateScene);
41746	        const radians = HIT_ANGLE_DEG * Math.PI / 180;
41747	        const ray = this.placeOnWall === true ? undefined : new XRRay(new DOMPoint(0, 0, 0), {
41748	            x: 0,
41749	            y: -Math.sin(radians),
41750	            z: -Math.cos(radians)
41751	        });
41752	        currentSession.requestHitTestSource({
41753	            space: viewerRefSpace,
41754	            offsetRay: ray
41755	        }).then((hitTestSource)=>{
41756	            this.initialHitSource = hitTestSource;
41757	        });
41758	        if (this.xrMode !== 'screen-space') {
41759	            this.setupControllers();
41760	            this.xDamper.setDecayTime(DECAY);
41761	            this.yDamper.setDecayTime(DECAY);
41762	            this.zDamper.setDecayTime(DECAY);
41763	            this.yawDamper.setDecayTime(DECAY);
41764	            this.pitchDamper.setDecayTime(DECAY);
41765	            this.rollDamper.setDecayTime(DECAY);
41766	        }
41767	        this.currentSession = currentSession;
41768	        this.placementBox = new PlacementBox(scene, this.placeOnWall ? 'back' : 'bottom');
41769	        this.placementComplete = false;
41770	        this.lastTick = performance.now();
41771	        this.dispatchEvent({
41772	            type: 'status',
41773	            status: ARStatus.SESSION_STARTED
41774	        });
41775	    }
41776	    setupControllers() {
41777	        this.controller1 = this.threeRenderer.xr.getController(0);
41778	        this.controller1.addEventListener('selectstart', this.onControllerSelectStart);
41779	        this.controller1.addEventListener('selectend', this.onControllerSelectEnd);
41780	        this.controller2 = this.threeRenderer.xr.getController(1);
41781	        this.controller2.addEventListener('selectstart', this.onControllerSelectStart);
41782	        this.controller2.addEventListener('selectend', this.onControllerSelectEnd);
41783	        const scene = this.presentedScene;
41784	        scene.add(this.controller1);
41785	        scene.add(this.controller2);
41786	        if (!this.controller1.userData.line) {
41787	            const line = new Line(lineGeometry);
41788	            line.name = 'line';
41789	            line.scale.z = MAX_LINE_LENGTH;
41790	            this.controller1.userData.turning = false;
41791	            this.controller1.userData.line = line;
41792	            this.controller1.add(line);
41793	            this.controller2.userData.turning = false;
41794	            const line2 = line.clone();
41795	            this.controller2.userData.line = line2;
41796	            this.controller2.add(line2);
41797	            this.scaleLine.name = 'scale line';
41798	            this.scaleLine.visible = false;
41799	            this.controller1.add(this.scaleLine);
41800	            const { size } = scene;
41801	            const scale = BOX_SIZE / Math.max(size.x, size.y, size.z);
41802	            const box = new Mesh(boxGeometry);
41803	            box.name = 'box';
41804	            box.scale.copy(size).multiplyScalar(scale);
41805	            box.visible = false;
41806	            this.controller1.userData.box = box;
41807	            scene.add(box);
41808	            const box2 = box.clone();
41809	            this.controller2.userData.box = box2;
41810	            scene.add(box2);
41811	        }
41812	    }
41813	    hover(controller) {
41814	        if (this.xrMode === 'screen-space' || this.selectedController == controller) {
41815	            return false;
41816	        }
41817	        const scene = this.presentedScene;
41818	        const intersection = this.placementBox.controllerIntersection(scene, controller);
41819	        controller.userData.box.visible = (intersection == null || controller.userData.turning) && !this.isTwoFingering;
41820	        controller.userData.line.scale.z = intersection == null ? MAX_LINE_LENGTH : intersection.distance;
41821	        return intersection != null;
41822	    }
41823	    controllerSeparation() {
41824	        return this.controller1.position.distanceTo(this.controller2.position);
41825	    }
41826	 async stopPresenting() {
41827	        if (!this.isPresenting) {
41828	            return;
41829	        }
41830	        const cleanupPromise = new Promise((resolve)=>{
41831	            this.resolveCleanup = resolve;
41832	        });
41833	        try {
41834	            await this.currentSession.end();
41835	            await cleanupPromise;
41836	        } catch (error) {
41837	            console.warn('Error while trying to end WebXR AR session');
41838	            console.warn(error);
41839	            this.postSessionCleanup();
41840	        }
41841	    }
41842	 get isPresenting() {
41843	        return this.presentedScene != null;
41844	    }
41845	    get target() {
41846	        return this.oldTarget;
41847	    }
41848	    updateTarget() {
41849	        const scene = this.presentedScene;
41850	        if (scene != null) {
41851	            const target = scene.getTarget();
41852	            this.oldTarget.copy(target);
41853	            if (this.placeOnWall) {
41854	                target.z = scene.boundingBox.min.z;
41855	            } else {
41856	                target.y = scene.boundingBox.min.y;
41857	            }
41858	            scene.setTarget(target.x, target.y, target.z);
41859	        }
41860	    }
41861	    postSessionCleanup() {
41862	        const session = this.currentSession;
41863	        if (session != null) {
41864	            session.removeEventListener('selectstart', this.onSelectStart);
41865	            session.removeEventListener('selectend', this.onSelectEnd);
41866	            this.currentSession = null;
41867	        }
41868	        const scene = this.presentedScene;
41869	        this._presentedScene = null;
41870	        if (scene != null) {
41871	            const { element } = scene;
vendor: 9,769 bytes, lines 41872-42102
41872	            if (this.xrLight != null) {
41873	                scene.remove(this.xrLight);
41874	                this.xrLight.dispose();
41875	                this.xrLight = null;
41876	            }
41877	            scene.add(scene.pivot);
41878	            scene.pivot.quaternion.set(0, 0, 0, 1);
41879	            scene.pivot.position.set(0, 0, 0);
41880	            scene.pivot.scale.set(1, 1, 1);
41881	            scene.setShadowOffset(0);
41882	            const yaw = this.turntableRotation;
41883	            if (yaw != null) {
41884	                scene.yaw = yaw;
41885	            }
41886	            const intensity = this.oldShadowIntensity;
41887	            if (intensity != null) {
41888	                scene.setShadowIntensity(intensity);
41889	            }
41890	            scene.setEnvironmentAndSkybox(element[$currentEnvironmentMap], element[$currentBackground]);
41891	            const point = this.oldTarget;
41892	            scene.setTarget(point.x, point.y, point.z);
41893	            scene.xrCamera = null;
41894	            scene.element.removeEventListener('load', this.onUpdateScene);
41895	            scene.orientHotspots(0);
41896	            const { width, height } = element.getBoundingClientRect();
41897	            scene.setSize(width, height);
41898	            requestAnimationFrame(()=>{
41899	                scene.element.dispatchEvent(new CustomEvent('camera-change', {
41900	                    detail: {
41901	                        source: ChangeSource.NONE
41902	                    }
41903	                }));
41904	            });
41905	        }
41906	        this.renderer.height = 0;
41907	        const exitButton = this.exitWebXRButtonContainer;
41908	        if (exitButton != null) {
41909	            exitButton.classList.remove('enabled');
41910	            exitButton.removeEventListener('click', this.onExitWebXRButtonContainerClick);
41911	            this.exitWebXRButtonContainer = null;
41912	        }
41913	        const hitSource = this.transientHitTestSource;
41914	        if (hitSource != null) {
41915	            hitSource.cancel();
41916	            this.transientHitTestSource = null;
41917	        }
41918	        const hitSourceInitial = this.initialHitSource;
41919	        if (hitSourceInitial != null) {
41920	            hitSourceInitial.cancel();
41921	            this.initialHitSource = null;
41922	        }
41923	        if (this.placementBox != null) {
41924	            this.placementBox.dispose();
41925	            this.placementBox = null;
41926	        }
41927	        if (this.xrMode !== 'screen-space') {
41928	            if (this.controller1 != null) {
41929	                this.controller1.userData.turning = false;
41930	                this.controller1.userData.box.visible = false;
41931	                this.controller1.userData.line.visible = true;
41932	                this.controller1.removeEventListener('selectstart', this.onControllerSelectStart);
41933	                this.controller1.removeEventListener('selectend', this.onControllerSelectEnd);
41934	                this.controller1.removeFromParent();
41935	                this.controller1 = null;
41936	            }
41937	            if (this.controller2 != null) {
41938	                this.controller2.userData.turning = false;
41939	                this.controller2.userData.box.visible = false;
41940	                this.controller2.userData.line.visible = true;
41941	                this.controller2.removeEventListener('selectstart', this.onControllerSelectStart);
41942	                this.controller2.removeEventListener('selectend', this.onControllerSelectEnd);
41943	                this.controller2.removeFromParent();
41944	                this.controller2 = null;
41945	            }
41946	            this.selectedController = null;
41947	            this.scaleLine.visible = false;
41948	        }
41949	        this.isTranslating = false;
41950	        this.isRotating = false;
41951	        this.isTwoFingering = false;
41952	        this.lastTick = null;
41953	        this.turntableRotation = null;
41954	        this.oldShadowIntensity = null;
41955	        this.frame = null;
41956	        this.inputSource = null;
41957	        this.overlay = null;
41958	        if (this.resolveCleanup != null) {
41959	            this.resolveCleanup();
41960	        }
41961	        this.dispatchEvent({
41962	            type: 'status',
41963	            status: ARStatus.NOT_PRESENTING
41964	        });
41965	    }
41966	    updateView(view) {
41967	        const scene = this.presentedScene;
41968	        const xr = this.threeRenderer.xr;
41969	        xr.updateCamera(camera);
41970	        scene.xrCamera = xr.getCamera();
41971	        const { elements } = scene.getCamera().matrixWorld;
41972	        scene.orientHotspots(Math.atan2(elements[1], elements[5]));
41973	        if (!this.initialized) {
41974	            this.placeInitially();
41975	            this.initialized = true;
41976	        }
41977	        if (view.requestViewportScale && view.recommendedViewportScale) {
41978	            const scale = view.recommendedViewportScale;
41979	            view.requestViewportScale(Math.max(scale, MIN_VIEWPORT_SCALE));
41980	        }
41981	        const layer = xr.getBaseLayer();
41982	        if (layer != null) {
41983	            const viewport = layer instanceof XRWebGLLayer ? layer.getViewport(view) : xr.getBinding().getViewSubImage(layer, view).viewport;
41984	            this.threeRenderer.setViewport(viewport.x, viewport.y, viewport.width, viewport.height);
41985	        }
41986	    }
41987	    placeInitially() {
41988	        const scene = this.presentedScene;
41989	        const { pivot, element } = scene;
41990	        const { position } = pivot;
41991	        const xrCamera = scene.getCamera();
41992	        const { width, height } = this.overlay.getBoundingClientRect();
41993	        scene.setSize(width, height);
41994	        xrCamera.projectionMatrixInverse.copy(xrCamera.projectionMatrix).invert();
41995	        const { theta } = element.getCameraOrbit();
41996	        const cameraDirection = xrCamera.getWorldDirection(vector3$1);
41997	        scene.yaw = Math.atan2(-cameraDirection.x, -cameraDirection.z) - theta;
41998	        this.goalYaw = scene.yaw;
41999	        const radius = Math.max(1, 2 * scene.boundingSphere.radius);
42000	        position.copy(xrCamera.position).add(cameraDirection.multiplyScalar(radius));
42001	        this.updateTarget();
42002	        const target = scene.getTarget();
42003	        position.add(target).sub(this.oldTarget);
42004	        this.goalPosition.copy(position);
42005	        scene.setHotspotsVisibility(true);
42006	        if (this.xrMode === 'screen-space') {
42007	            const { session } = this.frame;
42008	            session.addEventListener('selectstart', this.onSelectStart);
42009	            session.addEventListener('selectend', this.onSelectEnd);
42010	            session.requestHitTestSourceForTransientInput({
42011	                profile: 'generic-touchscreen'
42012	            }).then((hitTestSource)=>{
42013	                this.transientHitTestSource = hitTestSource;
42014	            });
42015	        }
42016	    }
42017	    getTouchLocation() {
42018	        const { axes } = this.inputSource.gamepad;
42019	        let location = this.placementBox.getExpandedHit(this.presentedScene, axes[0], axes[1]);
42020	        if (location != null) {
42021	            vector3$1.copy(location).sub(this.presentedScene.getCamera().position);
42022	            if (vector3$1.length() > MAX_DISTANCE) return null;
42023	        }
42024	        return location;
42025	    }
42026	    getHitPoint(hitResult) {
42027	        const refSpace = this.threeRenderer.xr.getReferenceSpace();
42028	        const pose = hitResult.getPose(refSpace);
42029	        if (pose == null) {
42030	            return null;
42031	        }
42032	        const hitMatrix = matrix4.fromArray(pose.transform.matrix);
42033	        if (this.placeOnWall === true) {
42034	            this.goalYaw = Math.atan2(hitMatrix.elements[4], hitMatrix.elements[6]);
42035	        }
42036	        return hitMatrix.elements[5] > 0.75 !== this.placeOnWall ? hitPosition.setFromMatrixPosition(hitMatrix) : null;
42037	    }
42038	    moveToFloor(frame) {
42039	        const hitSource = this.initialHitSource;
42040	        if (hitSource == null) {
42041	            return;
42042	        }
42043	        const hitTestResults = frame.getHitTestResults(hitSource);
42044	        if (hitTestResults.length == 0) {
42045	            return;
42046	        }
42047	        const hit = hitTestResults[0];
42048	        const hitPoint = this.getHitPoint(hit);
42049	        if (hitPoint == null) {
42050	            return;
42051	        }
42052	        this.placementBox.show = true;
42053	        if (!this.isTranslating) {
42054	            if (this.placeOnWall) {
42055	                this.goalPosition.copy(hitPoint);
42056	            } else {
42057	                this.goalPosition.y = hitPoint.y;
42058	            }
42059	        }
42060	        hitSource.cancel();
42061	        this.initialHitSource = null;
42062	        this.dispatchEvent({
42063	            type: 'status',
42064	            status: ARStatus.OBJECT_PLACED
42065	        });
42066	    }
42067	    fingerPolar(fingers) {
42068	        const fingerOne = fingers[0].inputSource.gamepad.axes;
42069	        const fingerTwo = fingers[1].inputSource.gamepad.axes;
42070	        const deltaX = fingerTwo[0] - fingerOne[0];
42071	        const deltaY = fingerTwo[1] - fingerOne[1];
42072	        const angle = Math.atan2(deltaY, deltaX);
42073	        let deltaYaw = this.lastAngle - angle;
42074	        if (deltaYaw > Math.PI) {
42075	            deltaYaw -= 2 * Math.PI;
42076	        } else if (deltaYaw < -Math.PI) {
42077	            deltaYaw += 2 * Math.PI;
42078	        }
42079	        this.lastAngle = angle;
42080	        return {
42081	            separation: Math.sqrt(deltaX * deltaX + deltaY * deltaY),
42082	            deltaYaw: deltaYaw
42083	        };
42084	    }
42085	    setScale(separation) {
42086	        const scale = separation / this.firstRatio;
42087	        this.goalScale = Math.abs(scale - 1) < SCALE_SNAP ? 1 : scale;
42088	    }
42089	    processInput(frame) {
42090	        const hitSource = this.transientHitTestSource;
42091	        if (hitSource == null) {
42092	            return;
42093	        }
42094	        if (!this.isTranslating && !this.isTwoFingering && !this.isRotating) {
42095	            return;
42096	        }
42097	        const fingers = frame.getHitTestResultsForTransientInput(hitSource);
42098	        const scene = this.presentedScene;
42099	        const scale = scene.pivot.scale.x;
42100	        if (this.isTwoFingering) {
42101	            if (fingers.length < 2) {
42102	                this.isTwoFingering = false;
42103	            } else {
42104	                const { separation, deltaYaw } = this.fingerPolar(fingers);
42105	                if (this.placeOnWall === false) {
42106	                    this.goalYaw += deltaYaw;
42107	                }
42108	                if (scene.canScale) {
42109	                    this.setScale(separation);
42110	                }
42111	            }
42112	            return;
42113	        } else if (fingers.length === 2) {
42114	            this.isTranslating = false;
42115	            this.isRotating = false;
42116	            this.isTwoFingering = true;
42117	            const { separation } = this.fingerPolar(fingers);
42118	            this.firstRatio = separation / scale;
42119	            return;
42120	        }
42121	        if (this.isRotating) {
42122	            const angle = this.inputSource.gamepad.axes[0] * ROTATION_RATE;
42123	            this.goalYaw += angle - this.lastAngle;
42124	            this.lastAngle = angle;
42125	        } else if (this.isTranslating) {
42126	            fingers.forEach((finger)=>{
42127	                if (finger.inputSource !== this.inputSource) {
42128	                    return;
42129	                }
42130	                let hit = null;
42131	                if (finger.results.length > 0) {
42132	                    hit = this.getHitPoint(finger.results[0]);
42133	                }
42134	                if (hit == null) {
42135	                    hit = this.getTouchLocation();
42136	                }
42137	                if (hit == null) {
42138	                    return;
42139	                }
42140	                this.goalPosition.sub(this.lastDragPosition);
42141	                if (this.placeOnWall === false) {
42142	                    const offset = hit.y - this.lastDragPosition.y;
42143	                    if (offset < 0) {
42144	                        this.placementBox.offsetHeight = offset / scale;
42145	                        this.presentedScene.setShadowOffset(offset);
42146	                        const cameraPosition = vector3$1.copy(scene.getCamera().position);
42147	                        const alpha = -offset / (cameraPosition.y - hit.y);
42148	                        cameraPosition.multiplyScalar(alpha);
42149	                        hit.multiplyScalar(1 - alpha).add(cameraPosition);
42150	                    }
42151	                }
42152	                this.goalPosition.add(hit);
42153	                this.lastDragPosition.copy(hit);
42154	            });
42155	        }
42156	    }
42157	    moveScene(delta) {
42158	        const scene = this.presentedScene;
42159	        const { pivot } = scene;
42160	        const box = this.placementBox;
42161	        box.updateOpacity(delta);
42162	        if (this.controller1) {
42163	            if (this.controller1.userData.turning) {
42164	                pivot.quaternion.copy(this.controller1.quaternion).multiply(this.relativeOrientation);
42165	                if (this.selectedController && this.selectedController === this.controller2) {
42166	                    pivot.quaternion.premultiply(quaternion.copy(this.controller2.quaternion).invert());
42167	                }
42168	            }
42169	            this.controller1.userData.box.position.copy(this.controller1.position);
42170	            pivot.getWorldQuaternion(this.controller1.userData.box.quaternion);
42171	        }
42172	        if (this.controller2) {
42173	            if (this.controller2.userData.turning) {
42174	                pivot.quaternion.copy(this.controller2.quaternion).multiply(this.relativeOrientation);
42175	                if (this.selectedController && this.selectedController === this.controller1) {
42176	                    pivot.quaternion.premultiply(quaternion.copy(this.controller1.quaternion).invert());
42177	                }
42178	            }
42179	            this.controller2.userData.box.position.copy(this.controller2.position);
42180	            pivot.getWorldQuaternion(this.controller2.userData.box.quaternion);
42181	        }
42182	        if (this.controller1 && this.controller2 && this.isTwoFingering) {
42183	            const dist = this.controllerSeparation();
42184	            this.setScale(dist);
42185	            this.scaleLine.scale.z = -dist;
42186	            this.scaleLine.lookAt(this.controller2.position);
42187	        }
42188	        const oldScale = scene.pivot.scale.x;
42189	        if (this.goalScale !== oldScale) {
42190	            const newScale = this.scaleDamper.update(oldScale, this.goalScale, delta, 1);
42191	            scene.pivot.scale.set(newScale, newScale, newScale);
42192	        }
42193	        if (pivot.parent !== scene) {
42194	            return;
42195	        }
42196	        const { position } = pivot;
42197	        const boundingRadius = scene.boundingSphere.radius;
42198	        const goal = this.goalPosition;
42199	        let source = ChangeSource.NONE;
42200	        if (!goal.equals(position)) {
42201	            source = ChangeSource.USER_INTERACTION;
42202	            let { x, y, z } = position;
42203	            x = this.xDamper.update(x, goal.x, delta, boundingRadius);
42204	            y = this.yDamper.update(y, goal.y, delta, boundingRadius);
42205	            z = this.zDamper.update(z, goal.z, delta, boundingRadius);
42206	            position.set(x, y, z);
42207	            if (this.xrMode === 'screen-space' && !this.isTranslating) {
42208	                const offset = goal.y - y;
42209	                if (this.placementComplete && this.placeOnWall === false) {
42210	                    box.offsetHeight = offset / scene.pivot.scale.x;
42211	                    scene.setShadowOffset(offset);
42212	                } else if (offset === 0) {
42213	                    this.placementComplete = true;
42214	                    box.show = false;
42215	                    scene.setShadowIntensity(AR_SHADOW_INTENSITY);
42216	                }
42217	            }
42218	            if (this.xrMode !== 'screen-space' && goal.equals(position)) {
42219	                scene.setShadowIntensity(AR_SHADOW_INTENSITY);
42220	            }
42221	        }
42222	        scene.updateTarget(delta);
42223	        quaternion.setFromAxisAngle(vector3$1.set(0, 1, 0), this.goalYaw);
42224	        const angle = scene.pivot.quaternion.angleTo(quaternion);
42225	        const angleStep = angle - this.yawDamper.update(angle, 0, delta, Math.PI);
42226	        scene.pivot.quaternion.rotateTowards(quaternion, angleStep);
42227	        scene.element.dispatchEvent(new CustomEvent('camera-change', {
42228	            detail: {
42229	                source
42230	            }
42231	        }));
42232	    }
42233	 onWebXRFrame(time, frame) {
42234	        if (this.xrMode !== 'screen-space') {
42235	            const over1 = this.hover(this.controller1);
42236	            const over2 = this.hover(this.controller2);
42237	            this.placementBox.show = (over1 || over2) && !this.isTwoFingering;
42238	        }
42239	        this.frame = frame;
42240	        ++this.frames;
42241	        const refSpace = this.threeRenderer.xr.getReferenceSpace();
42242	        const pose = frame.getViewerPose(refSpace);
42243	        if (pose == null && this.tracking === true && this.frames > INIT_FRAMES) {
42244	            this.tracking = false;
42245	            this.dispatchEvent({
42246	                type: 'tracking',
42247	                status: ARTracking.NOT_TRACKING
42248	            });
42249	        }
42250	        const scene = this.presentedScene;
42251	        if (pose == null || scene == null || !scene.element.loaded) {
42252	            this.threeRenderer.clear();
42253	            return;
42254	        }
42255	        if (this.tracking === false) {
42256	            this.tracking = true;
42257	            this.dispatchEvent({
42258	                type: 'tracking',
42259	                status: ARTracking.TRACKING
42260	            });
42261	        }
42262	        let isFirstView = true;
42263	        for (const view of pose.views){
42264	            this.updateView(view);
42265	            if (isFirstView) {
42266	                this.moveToFloor(frame);
42267	                this.processInput(frame);
42268	                const delta = time - this.lastTick;
42269	                this.moveScene(delta);
42270	                this.renderer.preRender(scene, time, delta);
42271	                this.lastTick = time;
42272	                scene.renderShadow(this.threeRenderer);
42273	            }
42274	            this.threeRenderer.render(scene, scene.getCamera());
42275	            isFirstView = false;
42276	        }
42277	    }
42278	    constructor(renderer){
42279	        super();
42280	        this.renderer = renderer;
42281	        this.currentSession = null;
42282	        this.placeOnWall = false;
42283	        this.placementBox = null;
42284	        this.lastTick = null;
42285	        this.turntableRotation = null;
42286	        this.oldShadowIntensity = null;
42287	        this.frame = null;
42288	        this.initialHitSource = null;
42289	        this.transientHitTestSource = null;
42290	        this.inputSource = null;
42291	        this._presentedScene = null;
42292	        this.resolveCleanup = null;
42293	        this.exitWebXRButtonContainer = null;
42294	        this.overlay = null;
42295	        this.xrLight = null;
42296	        this.xrMode = null;
42297	        this.controller1 = null;
42298	        this.controller2 = null;
42299	        this.selectedController = null;
42300	        this.tracking = true;
42301	        this.frames = 0;
42302	        this.initialized = false;
42303	        this.oldTarget = new Vector3();
42304	        this.placementComplete = false;
42305	        this.isTranslating = false;
42306	        this.isRotating = false;
42307	        this.isTwoFingering = false;
42308	        this.lastDragPosition = new Vector3();
42309	        this.relativeOrientation = new Quaternion();
42310	        this.scaleLine = new Line(lineGeometry);
42311	        this.firstRatio = 0;
42312	        this.lastAngle = 0;
42313	        this.goalPosition = new Vector3();
42314	        this.goalYaw = 0;
42315	        this.goalScale = 1;
42316	        this.xDamper = new Damper();
42317	        this.yDamper = new Damper();
42318	        this.zDamper = new Damper();
42319	        this.yawDamper = new Damper();
42320	        this.pitchDamper = new Damper();
42321	        this.rollDamper = new Damper();
42322	        this.scaleDamper = new Damper();
42323	        this.onExitWebXRButtonContainerClick = ()=>this.stopPresenting();
42324	        this.onControllerSelectStart = (event)=>{
42325	            const scene = this.presentedScene;
42326	            const controller = event.target;
42327	            if (this.placementBox.controllerIntersection(scene, controller) != null) {
42328	                if (this.selectedController != null) {
42329	                    this.selectedController.userData.line.visible = false;
42330	                    if (scene.canScale) {
42331	                        this.isTwoFingering = true;
42332	                        this.firstRatio = this.controllerSeparation() / scene.pivot.scale.x;
42333	                        this.scaleLine.visible = true;
42334	                    }
42335	                }
42336	                controller.attach(scene.pivot);
42337	                this.selectedController = controller;
42338	                scene.setShadowIntensity(0.01);
42339	            } else {
42340	                const otherController = controller === this.controller1 ? this.controller2 : this.controller1;
42341	                this.relativeOrientation.copy(controller.quaternion).invert().multiply(scene.pivot.getWorldQuaternion(quaternion));
42342	                otherController.userData.turning = false;
42343	                controller.userData.turning = true;
42344	                controller.userData.line.visible = false;
42345	            }
42346	        };
42347	        this.onControllerSelectEnd = (event)=>{
42348	            const controller = event.target;
42349	            controller.userData.turning = false;
42350	            controller.userData.line.visible = true;
42351	            this.isTwoFingering = false;
42352	            this.scaleLine.visible = false;
42353	            if (this.selectedController != null && this.selectedController != controller) {
42354	                return;
42355	            }
42356	            const scene = this.presentedScene;
42357	            scene.attach(scene.pivot);
42358	            this.selectedController = null;
42359	            this.goalYaw = Math.atan2(scene.pivot.matrix.elements[8], scene.pivot.matrix.elements[10]);
42360	            this.goalPosition.x = scene.pivot.position.x;
42361	            this.goalPosition.z = scene.pivot.position.z;
42362	        };
42363	        this.onUpdateScene = ()=>{
42364	            if (this.placementBox != null && this.isPresenting) {
42365	                this.placementBox.dispose();
42366	                this.placementBox = new PlacementBox(this.presentedScene, this.placeOnWall ? 'back' : 'bottom');
42367	            }
42368	        };
42369	        this.onSelectStart = (event)=>{
42370	            const hitSource = this.transientHitTestSource;
42371	            if (hitSource == null) {
42372	                return;
42373	            }
42374	            const fingers = this.frame.getHitTestResultsForTransientInput(hitSource);
42375	            const scene = this.presentedScene;
42376	            const box = this.placementBox;
42377	            if (fingers.length === 1) {
42378	                this.inputSource = event.inputSource;
42379	                const { axes } = this.inputSource.gamepad;
42380	                const hitPosition = box.getHit(this.presentedScene, axes[0], axes[1]);
42381	                box.show = true;
42382	                if (hitPosition != null) {
42383	                    this.isTranslating = true;
42384	                    this.lastDragPosition.copy(hitPosition);
42385	                } else if (this.placeOnWall === false) {
42386	                    this.isRotating = true;
42387	                    this.lastAngle = axes[0] * ROTATION_RATE;
42388	                }
42389	            } else if (fingers.length === 2) {
42390	                box.show = true;
42391	                this.isTwoFingering = true;
42392	                const { separation } = this.fingerPolar(fingers);
42393	                this.firstRatio = separation / scene.pivot.scale.x;
42394	            }
42395	        };
42396	        this.onSelectEnd = ()=>{
42397	            this.isTranslating = false;
vendor: 5,060 bytes, lines 42398-42549
42398	            this.isRotating = false;
42399	            this.isTwoFingering = false;
42400	            this.inputSource = null;
42401	            this.goalPosition.y += this.placementBox.offsetHeight * this.presentedScene.scale.x;
42402	            this.placementBox.show = false;
42403	        };
42404	        this.threeRenderer = renderer.threeRenderer;
42405	        this.threeRenderer.xr.enabled = true;
42406	    }
42407	}
42408
42409	function clone(source) {
42410	    const sourceLookup = new Map();
42411	    const cloneLookup = new Map();
42412	    const clone = source.clone();
42413	    parallelTraverse(source, clone, function(sourceNode, clonedNode) {
42414	        sourceLookup.set(clonedNode, sourceNode);
42415	        cloneLookup.set(sourceNode, clonedNode);
42416	    });
42417	    clone.traverse(function(node) {
42418	        if (!node.isSkinnedMesh) return;
42419	        const clonedMesh = node;
42420	        const sourceMesh = sourceLookup.get(node);
42421	        const sourceBones = sourceMesh.skeleton.bones;
42422	        clonedMesh.skeleton = sourceMesh.skeleton.clone();
42423	        clonedMesh.bindMatrix.copy(sourceMesh.bindMatrix);
42424	        clonedMesh.skeleton.bones = sourceBones.map(function(bone) {
42425	            return cloneLookup.get(bone);
42426	        });
42427	        clonedMesh.bind(clonedMesh.skeleton, clonedMesh.bindMatrix);
42428	    });
42429	    return clone;
42430	}
42431	function parallelTraverse(a, b, callback) {
42432	    callback(a, b);
42433	    for(let i = 0; i < a.children.length; i++){
42434	        parallelTraverse(a.children[i], b.children[i], callback);
42435	    }
42436	}
42437
42438	const $prepared = Symbol('prepared');
42439	const $prepare = Symbol('prepare');
42440	const $preparedGLTF = Symbol('preparedGLTF');
42441	const $clone = Symbol('clone');
42442	 class GLTFInstance {
42443	 static prepare(source) {
42444	        if (source.scene == null) {
42445	            throw new Error('Model does not have a scene');
42446	        }
42447	        if (source[$prepared]) {
42448	            return source;
42449	        }
42450	        const prepared = this[$prepare](source);
42451	        prepared[$prepared] = true;
42452	        return prepared;
42453	    }
42454	 static [$prepare](source) {
42455	        const { scene } = source;
42456	        const scenes = [
42457	            scene
42458	        ];
42459	        return Object.assign(Object.assign({}, source), {
42460	            scene,
42461	            scenes
42462	        });
42463	    }
42464	    get parser() {
42465	        return this[$preparedGLTF].parser;
42466	    }
42467	    get animations() {
42468	        return this[$preparedGLTF].animations;
42469	    }
42470	    get scene() {
42471	        return this[$preparedGLTF].scene;
42472	    }
42473	    get scenes() {
42474	        return this[$preparedGLTF].scenes;
42475	    }
42476	    get cameras() {
42477	        return this[$preparedGLTF].cameras;
42478	    }
42479	    get asset() {
42480	        return this[$preparedGLTF].asset;
42481	    }
42482	    get userData() {
42483	        return this[$preparedGLTF].userData;
42484	    }
42485	 clone() {
42486	        const GLTFInstanceConstructor = this.constructor;
42487	        const clonedGLTF = this[$clone]();
42488	        return new GLTFInstanceConstructor(clonedGLTF);
42489	    }
42490	 dispose() {
42491	        this.scenes.forEach((scene)=>{
42492	            scene.traverse((object)=>{
42493	                const mesh = object;
42494	                if (!mesh.material) {
42495	                    return;
42496	                }
42497	                const materials = Array.isArray(mesh.material) ? mesh.material : [
42498	                    mesh.material
42499	                ];
42500	                materials.forEach((material)=>{
42501	                    for(const propertyName in material){
42502	                        const texture = material[propertyName];
42503	                        if (texture instanceof Texture$1) {
42504	                            const image = texture.source.data;
42505	                            if (image.close != null) {
42506	                                image.close();
42507	                            }
42508	                            texture.dispose();
42509	                        }
42510	                    }
42511	                    material.dispose();
42512	                });
42513	                mesh.geometry.dispose();
42514	            });
42515	        });
42516	    }
42517	 [$clone]() {
42518	        const source = this[$preparedGLTF];
42519	        const scene = clone(this.scene);
42520	        cloneVariantMaterials(scene, this.scene);
42521	        const scenes = [
42522	            scene
42523	        ];
42524	        const userData = source.userData ? Object.assign({}, source.userData) : {};
42525	        return Object.assign(Object.assign({}, source), {
42526	            scene,
42527	            scenes,
42528	            userData
42529	        });
42530	    }
42531	    constructor(preparedGLTF){
42532	        this[$preparedGLTF] = preparedGLTF;
42533	    }
42534	}
42535	const cloneVariantMaterials = (dst, src)=>{
42536	    traversePair(dst, src, (dst, src)=>{
42537	        if (src.userData.variantMaterials !== undefined) {
42538	            dst.userData.variantMaterials = new Map(src.userData.variantMaterials);
42539	        }
42540	        if (src.userData.variantData !== undefined) {
42541	            dst.userData.variantData = src.userData.variantData;
42542	        }
42543	        if (src.userData.originalMaterial !== undefined) {
42544	            dst.userData.originalMaterial = src.userData.originalMaterial;
42545	        }
42546	    });
42547	};
42548	const traversePair = (obj1, obj2, callback)=>{
42549	    callback(obj1, obj2);
vendor: 5,410 bytes, lines 42550-42663
42550	    for(let i = 0; i < obj1.children.length; i++){
42551	        traversePair(obj1.children[i], obj2.children[i], callback);
42552	    }
42553	};
42554
42555	const $threeGLTF = Symbol('threeGLTF');
42556	const $gltf = Symbol('gltf');
42557	const $gltfElementMap = Symbol('gltfElementMap');
42558	const $threeObjectMap = Symbol('threeObjectMap');
42559	const $parallelTraverseThreeScene = Symbol('parallelTraverseThreeScene');
42560	const $correlateOriginalThreeGLTF = Symbol('correlateOriginalThreeGLTF');
42561	const $correlateCloneThreeGLTF = Symbol('correlateCloneThreeGLTF');
42562	 class CorrelatedSceneGraph {
42563	 static from(threeGLTF, upstreamCorrelatedSceneGraph) {
42564	        if (upstreamCorrelatedSceneGraph != null) {
42565	            return this[$correlateCloneThreeGLTF](threeGLTF, upstreamCorrelatedSceneGraph);
42566	        } else {
42567	            return this[$correlateOriginalThreeGLTF](threeGLTF);
42568	        }
42569	    }
42570	    static [$correlateOriginalThreeGLTF](threeGLTF) {
42571	        const gltf = threeGLTF.parser.json;
42572	        const associations = threeGLTF.parser.associations;
42573	        const gltfElementMap = new Map();
42574	        const defaultMaterial = {
42575	            name: 'Default'
42576	        };
42577	        const defaultReference = {
42578	            index: -1
42579	        };
42580	        for (const threeMaterial of associations.keys()){
42581	            if (threeMaterial instanceof Material$1 && associations.get(threeMaterial) == null) {
42582	                if (defaultReference.index < 0) {
42583	                    if (gltf.materials == null) {
42584	                        gltf.materials = [];
42585	                    }
42586	                    defaultReference.index = gltf.materials.length;
42587	                    gltf.materials.push(defaultMaterial);
42588	                }
42589	                threeMaterial.name = defaultMaterial.name;
42590	                associations.set(threeMaterial, {
42591	                    materials: defaultReference.index
42592	                });
42593	            }
42594	        }
42595	        for (const [threeObject, gltfMappings] of associations){
42596	            if (gltfMappings) {
42597	                threeObject.userData = threeObject.userData || {};
42598	                threeObject.userData.associations = gltfMappings;
42599	            }
42600	            for(const mapping in gltfMappings){
42601	                if (mapping != null && mapping !== 'primitives') {
42602	                    const type = mapping;
42603	                    const elementArray = gltf[type] || [];
42604	                    const gltfElement = elementArray[gltfMappings[type]];
42605	                    if (gltfElement == null) {
42606	                        continue;
42607	                    }
42608	                    let threeObjects = gltfElementMap.get(gltfElement);
42609	                    if (threeObjects == null) {
42610	                        threeObjects = new Set();
42611	                        gltfElementMap.set(gltfElement, threeObjects);
42612	                    }
42613	                    threeObjects.add(threeObject);
42614	                }
42615	            }
42616	        }
42617	        return new CorrelatedSceneGraph(threeGLTF, gltf, associations, gltfElementMap);
42618	    }
42619	 static [$correlateCloneThreeGLTF](cloneThreeGLTF, upstreamCorrelatedSceneGraph) {
42620	        const originalThreeGLTF = upstreamCorrelatedSceneGraph.threeGLTF;
42621	        const originalGLTF = upstreamCorrelatedSceneGraph.gltf;
42622	        const cloneGLTF = JSON.parse(JSON.stringify(originalGLTF));
42623	        const cloneThreeObjectMap = new Map();
42624	        const cloneGLTFElementMap = new Map();
42625	        for(let i = 0; i < originalThreeGLTF.scenes.length; i++){
42626	            this[$parallelTraverseThreeScene](originalThreeGLTF.scenes[i], cloneThreeGLTF.scenes[i], (object, cloneObject)=>{
42627	                const elementReference = upstreamCorrelatedSceneGraph.threeObjectMap.get(object);
42628	                if (elementReference == null) {
42629	                    return;
42630	                }
42631	                for(const mapping in elementReference){
42632	                    if (mapping != null && mapping !== 'primitives') {
42633	                        const type = mapping;
42634	                        const index = elementReference[type];
42635	                        const cloneElement = cloneGLTF[type][index];
42636	                        const mappings = cloneThreeObjectMap.get(cloneObject) || {};
42637	                        mappings[type] = index;
42638	                        cloneThreeObjectMap.set(cloneObject, mappings);
42639	                        const cloneObjects = cloneGLTFElementMap.get(cloneElement) || new Set();
42640	                        cloneObjects.add(cloneObject);
42641	                        cloneGLTFElementMap.set(cloneElement, cloneObjects);
42642	                    }
42643	                }
42644	            });
42645	        }
42646	        return new CorrelatedSceneGraph(cloneThreeGLTF, cloneGLTF, cloneThreeObjectMap, cloneGLTFElementMap);
42647	    }
42648	 static [$parallelTraverseThreeScene](sceneOne, sceneTwo, callback) {
42649	        const traverse = (a, b)=>{
42650	            callback(a, b);
42651	            if (a.isObject3D) {
42652	                const meshA = a;
42653	                const meshB = b;
42654	                if (meshA.material) {
42655	                    if (Array.isArray(meshA.material)) {
42656	                        for(let i = 0; i < meshA.material.length; ++i){
42657	                            callback(meshA.material[i], meshB.material[i]);
42658	                        }
42659	                    } else {
42660	                        callback(meshA.material, meshB.material);
42661	                    }
42662	                }
42663	                for(let i = 0;
vendor: 6,066 bytes, lines 42663-42833
42663 i < a.children.length; ++i){
42664	                    traverse(a.children[i], b.children[i]);
42665	                }
42666	            }
42667	        };
42668	        traverse(sceneOne, sceneTwo);
42669	    }
42670	 get threeGLTF() {
42671	        return this[$threeGLTF];
42672	    }
42673	 get gltf() {
42674	        return this[$gltf];
42675	    }
42676	 get gltfElementMap() {
42677	        return this[$gltfElementMap];
42678	    }
42679	 get threeObjectMap() {
42680	        return this[$threeObjectMap];
42681	    }
42682	    constructor(threeGLTF, gltf, threeObjectMap, gltfElementMap){
42683	        this[$threeGLTF] = threeGLTF;
42684	        this[$gltf] = gltf;
42685	        this[$gltfElementMap] = gltfElementMap;
42686	        this[$threeObjectMap] = threeObjectMap;
42687	    }
42688	}
42689
42690	const $correlatedSceneGraph = Symbol('correlatedSceneGraph');
42691	 class ModelViewerGLTFInstance extends GLTFInstance {
42692	 static [$prepare](source) {
42693	        const prepared = super[$prepare](source);
42694	        if (prepared[$correlatedSceneGraph] == null) {
42695	            prepared[$correlatedSceneGraph] = CorrelatedSceneGraph.from(prepared);
42696	        }
42697	        const { scene } = prepared;
42698	        const nullSphere = new Sphere(undefined, Infinity);
42699	        scene.traverse((node)=>{
42700	            node.renderOrder = 1000;
42701	            node.frustumCulled = false;
42702	            if (!node.name) {
42703	                node.name = node.uuid;
42704	            }
42705	            const mesh = node;
42706	            if (mesh.material) {
42707	                const { geometry } = mesh;
42708	                mesh.castShadow = true;
42709	                if (mesh.isSkinnedMesh) {
42710	                    geometry.boundingSphere = nullSphere;
42711	                    geometry.boundingBox = null;
42712	                }
42713	                const material = mesh.material;
42714	                if (material.isMeshBasicMaterial === true) {
42715	                    material.toneMapped = false;
42716	                }
42717	                material.shadowSide = FrontSide;
42718	                if (material.aoMap) {
42719	                    const { gltf, threeObjectMap } = prepared[$correlatedSceneGraph];
42720	                    const gltfRef = threeObjectMap.get(material);
42721	                    if (gltf.materials != null && gltfRef != null && gltfRef.materials != null) {
42722	                        const gltfMaterial = gltf.materials[gltfRef.materials];
42723	                        if (gltfMaterial.occlusionTexture && gltfMaterial.occlusionTexture.texCoord === 0 && geometry.attributes.uv != null) {
42724	                            geometry.setAttribute('uv2', geometry.attributes.uv);
42725	                        }
42726	                    }
42727	                }
42728	            }
42729	        });
42730	        return prepared;
42731	    }
42732	    get correlatedSceneGraph() {
42733	        return this[$preparedGLTF][$correlatedSceneGraph];
42734	    }
42735	 [$clone]() {
42736	        const clone = super[$clone]();
42737	        const sourceUUIDToClonedMaterial = new Map();
42738	        clone.scene.traverse((node)=>{
42739	            const mesh = node;
42740	            if (mesh.material) {
42741	                const material = mesh.material;
42742	                if (material != null) {
42743	                    if (sourceUUIDToClonedMaterial.has(material.uuid)) {
42744	                        mesh.material = sourceUUIDToClonedMaterial.get(material.uuid);
42745	                        return;
42746	                    }
42747	                    mesh.material = material.clone();
42748	                    sourceUUIDToClonedMaterial.set(material.uuid, mesh.material);
42749	                }
42750	            }
42751	            const light = node;
42752	            if (light.target !== undefined) {
42753	                light.add(light.target);
42754	            }
42755	        });
42756	        clone[$correlatedSceneGraph] = CorrelatedSceneGraph.from(clone, this.correlatedSceneGraph);
42757	        return clone;
42758	    }
42759	}
42760
42761	const getBufferForType = (type, width, height)=>{
42762	    let out;
42763	    switch(type){
42764	        case UnsignedByteType:
42765	            out = new Uint8ClampedArray(width * height * 4);
42766	            break;
42767	        case HalfFloatType:
42768	            out = new Uint16Array(width * height * 4);
42769	            break;
42770	        case UnsignedIntType:
42771	            out = new Uint32Array(width * height * 4);
42772	            break;
42773	        case ByteType:
42774	            out = new Int8Array(width * height * 4);
42775	            break;
42776	        case ShortType:
42777	            out = new Int16Array(width * height * 4);
42778	            break;
42779	        case IntType:
42780	            out = new Int32Array(width * height * 4);
42781	            break;
42782	        case FloatType:
42783	            out = new Float32Array(width * height * 4);
42784	            break;
42785	        default:
42786	            throw new Error('Unsupported data type');
42787	    }
42788	    return out;
42789	};
42790	let _canReadPixelsResult;
42791	/**
42792	 * Test if this browser implementation can correctly read pixels from the specified
42793	 * Render target type.
42794	 *
42795	 * Runs only once
42796	 *
42797	 * @param type
42798	 * @param renderer
42799	 * @param camera
42800	 * @param renderTargetOptions
42801	 * @returns
42802	 */ const canReadPixels = (type, renderer, camera, renderTargetOptions)=>{
42803	    if (_canReadPixelsResult !== undefined) return _canReadPixelsResult;
42804	    const testRT = new WebGLRenderTarget(1, 1, renderTargetOptions);
42805	    renderer.setRenderTarget(testRT);
42806	    const mesh = new Mesh(new PlaneGeometry(), new MeshBasicMaterial({
42807	        color: 0xffffff
42808	    }));
42809	    renderer.render(mesh, camera);
42810	    renderer.setRenderTarget(null);
42811	    const out = getBufferForType(type, testRT.width, testRT.height);
42812	    renderer.readRenderTargetPixels(testRT, 0, 0, testRT.width, testRT.height, out);
42813	    testRT.dispose();
42814	    mesh.geometry.dispose();
42815	    mesh.material.dispose();
42816	    _canReadPixelsResult = out[0] !== 0;
42817	    return _canReadPixelsResult;
42818	};
42819	/**
42820	 * Utility class used for rendering a texture with a material
42821	 *
42822	 * @category Core
42823	 * @group Core
42824	 */ class QuadRenderer {
42825	    /**
42826	     * Instantiates a temporary renderer
42827	     *
42828	     * @returns
42829	     */ static instantiateRenderer() {
42830	        const renderer = new WebGLRenderer();
42831	        renderer.setSize(128, 128);
42832	        // renderer.outputColorSpace = SRGBColorSpace
42833	        // renderer.toneMapping = LinearToneMapping
42834	        // renderer.debug.checkShaderErrors = false
42835	        // this._rendererIsDisposable = true
42836	        return renderer;
42837	    }
42838	    /**
42839	     * Obtains a Buffer containing the rendered texture.
42840	     *
42841	     * @throws Error if the browser cannot read pixels from this RenderTarget type.
42842	     * @returns a TypedArray containing RGBA values from this renderer
42843	     */ toArray() {
42844	        if (!this._supportsReadPixels) throw new Error('Can\'t read pixels in this browser');
42845	        const out = getBufferForType(this._type, this._width, this._height);
42846	        this._renderer.readRenderTargetPixels(this._renderTarget, 0, 0, this._width, this._height, out);
42847	        return out;
42848	    }
42849	    /**
42850	     * Performs a readPixel operation in the renderTarget
42851	     * and returns a DataTexture containing the read data
42852	     *
42853	     * @param options options
42854	     * @returns
42855	     */ toDataTexture(options) {
42856	        const returnValue = new DataTexture(// fixed values
42857	        this.toArray(), this.width, this.height, RGBAFormat, this._type, // user values
42858	        (options === null || options === void 0 ? void 0 : options.mapping) || UVMapping, (options === null || options === void 0 ? void 0 : options.wrapS) || ClampToEdgeWrapping, (options === null || options === void 0 ? void 0 : options.wrapT) || ClampToEdgeWrapping, (options === null || options === void 0 ? void 0 : options.magFilter) || LinearFilter, (options === null || options === void 0 ? void 0 : options.minFilter) || LinearFilter, (options === null || options === void 0 ? void 0 : options.anisotropy) || 1, // fixed value
42859	        LinearSRGBColorSpace);
42860	        // set this afterwards, we can't set it in constructor
42861	        returnValue.generateMipmaps = (options === null || options === void 0 ? void 0 : options.generateMipmaps) !== undefined ? options === null || options === void 0 ? void 0 : options.generateMipmaps : false;
42862	        return returnValue;
42863	    }
42864	    /**
42865	     * If using a disposable renderer, it will dispose it.
42866	     */ disposeOnDemandRenderer() {
42867	        this._renderer.setRenderTarget(null);
42868	        if (this._rendererIsDisposable) {
42869	            this._renderer.dispose();
42870	            this._renderer.forceContextLoss();
42871	        }
42872	    }
42873	    /**
42874	     * Will dispose of **all** assets used by this renderer.
42875	     *
42876	     *
42877	     * @param disposeRenderTarget will dispose of the renderTarget which will not be usable later
42878	     * set this to true if you passed the `renderTarget.texture` to a `PMREMGenerator`
42879	     * or are otherwise done with it.
42880	     *
42881	     * @example
42882	     * ```js
42883	     * const loader = new HDRJPGLoader(renderer)
42884	     * const result = await loader.loadAsync('gainmap.jpeg')
42885	     * const mesh = new Mesh(geometry, new MeshBasicMaterial({ map: result.renderTarget.texture }) )
42886	     * // DO NOT dispose the renderTarget here,
42887	     * // it is used directly in the material
42888	     * result.dispose()
42889	     * ```
42890	     *
42891	     * @example
42892	     * ```js
42893	     * const loader = new HDRJPGLoader(renderer)
42894	     * const pmremGenerator = new PMREMGenerator( renderer );
42895	     * const result = await loader.loadAsync('gainmap.jpeg')
42896	     * const envMap = pmremGenerator.fromEquirectangular(result.renderTarget.texture)
42897	     * const mesh = new Mesh(geometry, new MeshStandardMaterial({ envMap }) )
42898	     * // renderTarget can be disposed here
42899	     * // because it was used to generate a PMREM texture
42900	     * result.dispose(true)
42901	     * ```
42902	     */ dispose(disposeRenderTarget) {
42903	        this.disposeOnDemandRenderer();
42904	        if (disposeRenderTarget) {
42905	            this.renderTarget.dispose();
42906	        }
42907	        // dispose shader material texture uniforms
42908	        if (this.material instanceof ShaderMaterial) {
42909	            Object.values(this.material.uniforms).forEach((v)=>{
42910	                if (v.value instanceof Texture$1) v.value.dispose();
42911	            });
42912	        }
42913	        // dispose other material properties
42914	        Object.values(this.material).forEach((value)=>{
42915	            if (value instanceof Texture$1) value.dispose();
42916	        });
42917	        this.material.dispose();
42918	        this._quad.geometry.dispose();
42919	    }
42920	    /**
42921	     * Width of the texture
42922	     */ get width() {
42923	        return this._width;
42924	    }
42925	    set width(value) {
42926	        this._width = value;
42927	        this._renderTarget.setSize(this._width, this._height);
42928	    }
42929	    /**
42930	     * Height of the texture
42931	     */ get height() {
42932	        return this._height;
42933	    }
42934	    set height(value) {
42935	        this._height = value;
42936	        this._renderTarget.setSize(this._width, this._height);
42937	    }
42938	    /**
42939	     * The renderer used
42940	     */ get renderer() {
42941	        return this._renderer;
42942	    }
42943	    /**
42944	     * The `WebGLRenderTarget` used.
42945	     */ get renderTarget() {
42946	        return this._renderTarget;
42947	    }
42948	    set renderTarget(value) {
42949	        this._renderTarget = value;
42950	        this._width = value.width;
42951	        this._height = value.height;
42952	    // this._type = value.texture.type
42953	    }
42954	    /**
42955	     * The `Material` used.
42956	     */ get material() {
42957	        return this._material;
42958	    }
42959	    /**
42960	     *
42961	     */ get type() {
42962	        return this._type;
42963	    }
42964	    get colorSpace() {
42965	        return this._colorSpace;
42966	    }
42967	    /**
42968	     * Constructs a new QuadRenderer
42969	     *
42970	     * @param options Parameters for this QuadRenderer
42971	     */ constructor(options){
42972	        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
42973	        this._rendererIsDisposable = false;
42974	        this._supportsReadPixels = true;
42975	        /**
42976	         * Renders the input texture using the specified material
42977	         */ this.render = ()=>{
42978	            this._renderer.setRenderTarget(this._renderTarget);
42979	            try {
42980	                this._renderer.render(this._scene, this._camera);
42981	            } catch (e) {
42982	                this._renderer.setRenderTarget(null);
42983	                throw e;
42984	            }
42985	            this._renderer.setRenderTarget(null);
42986	        };
42987	        this._width = options.width;
42988	        this._height = options.height;
42989	        this._type = options.type;
42990	        this._colorSpace = options.colorSpace;
42991	        const rtOptions = {
42992	            // fixed options
42993	            format: RGBAFormat,
42994	            depthBuffer: false,
42995	            stencilBuffer: false,
42996	            // user options
42997	            type: this._type,
42998	            colorSpace: this._colorSpace,
42999	            anisotropy: ((_a = options.renderTargetOptions) === null || _a === void 0 ? void 0 : _a.anisotropy) !== undefined ? (_b = options.renderTargetOptions) === null || _b === void 0 ? void 0 : _b.anisotropy : 1,
43000	            generateMipmaps: ((_c = options.renderTargetOptions) === null || _c === void 0 ? void 0 : _c.generateMipmaps) !== undefined ? (_d = options.renderTargetOptions) === null || _d === void 0 ? void 0 : _d.generateMipmaps : false,
43001	            magFilter: ((_e = options.renderTargetOptions) === null || _e === void 0 ? void 0 : _e.magFilter) !== undefined ? (_f = options.renderTargetOptions) === null || _f === void 0 ? void 0 : _f.magFilter : LinearFilter,
43002	            minFilter: ((_g = options.renderTargetOptions) === null || _g === void 0 ? void 0 : _g.minFilter) !== undefined ? (_h = options.renderTargetOptions) === null || _h === void 0 ? void 0 : _h.minFilter : LinearFilter,
43003	            samples: ((_j = options.renderTargetOptions) === null || _j === void 0 ? void 0 : _j.samples) !== undefined ? (_k = options.renderTargetOptions) === null || _k === void 0 ? void 0 : _k.samples : undefined,
43004	            wrapS: ((_l = options.renderTargetOptions) === null || _l === void 0 ? void 0 : _l.wrapS) !== undefined ? (_m = options.renderTargetOptions) === null || _m === void 0 ? void 0 : _m.wrapS : ClampToEdgeWrapping,
vendor: 15,142 bytes, lines 43005-43364
43005	            wrapT: ((_o = options.renderTargetOptions) === null || _o === void 0 ? void 0 : _o.wrapT) !== undefined ? (_p = options.renderTargetOptions) === null || _p === void 0 ? void 0 : _p.wrapT : ClampToEdgeWrapping
43006	        };
43007	        this._material = options.material;
43008	        if (options.renderer) {
43009	            this._renderer = options.renderer;
43010	        } else {
43011	            this._renderer = QuadRenderer.instantiateRenderer();
43012	            this._rendererIsDisposable = true;
43013	        }
43014	        this._scene = new Scene();
43015	        this._camera = new OrthographicCamera();
43016	        this._camera.position.set(0, 0, 10);
43017	        this._camera.left = -0.5;
43018	        this._camera.right = 0.5;
43019	        this._camera.top = 0.5;
43020	        this._camera.bottom = -0.5;
43021	        this._camera.updateProjectionMatrix();
43022	        if (!canReadPixels(this._type, this._renderer, this._camera, rtOptions)) {
43023	            let alternativeType;
43024	            switch(this._type){
43025	                case HalfFloatType:
43026	                    alternativeType = this._renderer.extensions.has('EXT_color_buffer_float') ? FloatType : undefined;
43027	                    break;
43028	            }
43029	            if (alternativeType !== undefined) {
43030	                console.warn(`This browser does not support reading pixels from ${this._type} RenderTargets, switching to ${FloatType}`);
43031	                this._type = alternativeType;
43032	            } else {
43033	                this._supportsReadPixels = false;
43034	                console.warn('This browser dos not support toArray or toDataTexture, calls to those methods will result in an error thrown');
43035	            }
43036	        }
43037	        this._quad = new Mesh(new PlaneGeometry(), this._material);
43038	        this._quad.geometry.computeBoundingBox();
43039	        this._scene.add(this._quad);
43040	        this._renderTarget = new WebGLRenderTarget(this.width, this.height, rtOptions);
43041	        this._renderTarget.texture.mapping = ((_q = options.renderTargetOptions) === null || _q === void 0 ? void 0 : _q.mapping) !== undefined ? (_r = options.renderTargetOptions) === null || _r === void 0 ? void 0 : _r.mapping : UVMapping;
43042	    }
43043	}
43044
43045	const vertexShader = /* glsl */ `
43046varying vec2 vUv;
43047
43048void main() {
43049  vUv = uv;
43050  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
43051}
43052`;
43053	const fragmentShader = /* glsl */ `
43054// min half float value
43055#define HALF_FLOAT_MIN vec3( -65504, -65504, -65504 )
43056// max half float value
43057#define HALF_FLOAT_MAX vec3( 65504, 65504, 65504 )
43058
43059uniform sampler2D sdr;
43060uniform sampler2D gainMap;
43061uniform vec3 gamma;
43062uniform vec3 offsetHdr;
43063uniform vec3 offsetSdr;
43064uniform vec3 gainMapMin;
43065uniform vec3 gainMapMax;
43066uniform float weightFactor;
43067
43068varying vec2 vUv;
43069
43070void main() {
43071  vec3 rgb = texture2D( sdr, vUv ).rgb;
43072  vec3 recovery = texture2D( gainMap, vUv ).rgb;
43073  vec3 logRecovery = pow( recovery, gamma );
43074  vec3 logBoost = gainMapMin * ( 1.0 - logRecovery ) + gainMapMax * logRecovery;
43075  vec3 hdrColor = (rgb + offsetSdr) * exp2( logBoost * weightFactor ) - offsetHdr;
43076  vec3 clampedHdrColor = max( HALF_FLOAT_MIN, min( HALF_FLOAT_MAX, hdrColor ));
43077  gl_FragColor = vec4( clampedHdrColor , 1.0 );
43078}
43079`;
43080	/**
43081	 * A Material which is able to decode the Gainmap into a full HDR Representation
43082	 *
43083	 * @category Materials
43084	 * @group Materials
43085	 */ class GainMapDecoderMaterial extends ShaderMaterial {
43086	    get sdr() {
43087	        return this.uniforms.sdr.value;
43088	    }
43089	    set sdr(value) {
43090	        this.uniforms.sdr.value = value;
43091	    }
43092	    get gainMap() {
43093	        return this.uniforms.gainMap.value;
43094	    }
43095	    set gainMap(value) {
43096	        this.uniforms.gainMap.value = value;
43097	    }
43098	    /**
43099	     * @see {@link GainMapMetadata.offsetHdr}
43100	     */ get offsetHdr() {
43101	        return this.uniforms.offsetHdr.value.toArray();
43102	    }
43103	    set offsetHdr(value) {
43104	        this.uniforms.offsetHdr.value.fromArray(value);
43105	    }
43106	    /**
43107	     * @see {@link GainMapMetadata.offsetSdr}
43108	     */ get offsetSdr() {
43109	        return this.uniforms.offsetSdr.value.toArray();
43110	    }
43111	    set offsetSdr(value) {
43112	        this.uniforms.offsetSdr.value.fromArray(value);
43113	    }
43114	    /**
43115	     * @see {@link GainMapMetadata.gainMapMin}
43116	     */ get gainMapMin() {
43117	        return this.uniforms.gainMapMin.value.toArray();
43118	    }
43119	    set gainMapMin(value) {
43120	        this.uniforms.gainMapMin.value.fromArray(value);
43121	    }
43122	    /**
43123	     * @see {@link GainMapMetadata.gainMapMax}
43124	     */ get gainMapMax() {
43125	        return this.uniforms.gainMapMax.value.toArray();
43126	    }
43127	    set gainMapMax(value) {
43128	        this.uniforms.gainMapMax.value.fromArray(value);
43129	    }
43130	    /**
43131	     * @see {@link GainMapMetadata.gamma}
43132	     */ get gamma() {
43133	        const g = this.uniforms.gamma.value;
43134	        return [
43135	            1 / g.x,
43136	            1 / g.y,
43137	            1 / g.z
43138	        ];
43139	    }
43140	    set gamma(value) {
43141	        const g = this.uniforms.gamma.value;
43142	        g.x = 1.0 / value[0];
43143	        g.y = 1.0 / value[1];
43144	        g.z = 1.0 / value[2];
43145	    }
43146	    /**
43147	     * @see {@link GainMapMetadata.hdrCapacityMin}
43148	     * @remarks Logarithmic space
43149	     */ get hdrCapacityMin() {
43150	        return this._hdrCapacityMin;
43151	    }
43152	    set hdrCapacityMin(value) {
43153	        this._hdrCapacityMin = value;
43154	        this.calculateWeight();
43155	    }
43156	    /**
43157	     * @see {@link GainMapMetadata.hdrCapacityMin}
43158	     * @remarks Logarithmic space
43159	     */ get hdrCapacityMax() {
43160	        return this._hdrCapacityMax;
43161	    }
43162	    set hdrCapacityMax(value) {
43163	        this._hdrCapacityMax = value;
43164	        this.calculateWeight();
43165	    }
43166	    /**
43167	     * @see {@link GainmapDecodingParameters.maxDisplayBoost}
43168	     * @remarks Non Logarithmic space
43169	     */ get maxDisplayBoost() {
43170	        return this._maxDisplayBoost;
43171	    }
43172	    set maxDisplayBoost(value) {
43173	        this._maxDisplayBoost = Math.max(1, Math.min(65504, value));
43174	        this.calculateWeight();
43175	    }
43176	    calculateWeight() {
43177	        const val = (Math.log2(this._maxDisplayBoost) - this._hdrCapacityMin) / (this._hdrCapacityMax - this._hdrCapacityMin);
43178	        this.uniforms.weightFactor.value = Math.max(0, Math.min(1, val));
43179	    }
43180	    /**
43181	     *
43182	     * @param params
43183	     */ constructor({ gamma, offsetHdr, offsetSdr, gainMapMin, gainMapMax, maxDisplayBoost, hdrCapacityMin, hdrCapacityMax, sdr, gainMap }){
43184	        super({
43185	            name: 'GainMapDecoderMaterial',
43186	            vertexShader,
43187	            fragmentShader,
43188	            uniforms: {
43189	                sdr: {
43190	                    value: sdr
43191	                },
43192	                gainMap: {
43193	                    value: gainMap
43194	                },
43195	                gamma: {
43196	                    value: new Vector3(1.0 / gamma[0], 1.0 / gamma[1], 1.0 / gamma[2])
43197	                },
43198	                offsetHdr: {
43199	                    value: new Vector3().fromArray(offsetHdr)
43200	                },
43201	                offsetSdr: {
43202	                    value: new Vector3().fromArray(offsetSdr)
43203	                },
43204	                gainMapMin: {
43205	                    value: new Vector3().fromArray(gainMapMin)
43206	                },
43207	                gainMapMax: {
43208	                    value: new Vector3().fromArray(gainMapMax)
43209	                },
43210	                weightFactor: {
43211	                    value: (Math.log2(maxDisplayBoost) - hdrCapacityMin) / (hdrCapacityMax - hdrCapacityMin)
43212	                }
43213	            },
43214	            blending: NoBlending,
43215	            depthTest: false,
43216	            depthWrite: false
43217	        });
43218	        this._maxDisplayBoost = maxDisplayBoost;
43219	        this._hdrCapacityMin = hdrCapacityMin;
43220	        this._hdrCapacityMax = hdrCapacityMax;
43221	        this.needsUpdate = true;
43222	        this.uniformsNeedUpdate = true;
43223	    }
43224	}
43225	class GainMapNotFoundError extends Error {
43226	}
43227	class XMPMetadataNotFoundError extends Error {
43228	}
43229	const getXMLValue = (xml, tag, defaultValue)=>{
43230	    // Check for attribute format first: tag="value"
43231	    const attributeMatch = new RegExp(`${tag}="([^"]*)"`, 'i').exec(xml);
43232	    if (attributeMatch) return attributeMatch[1];
43233	    // Check for tag format: <tag>value</tag> or <tag><rdf:li>value</rdf:li>...</tag>
43234	    const tagMatch = new RegExp(`<${tag}[^>]*>([\\s\\S]*?)</${tag}>`, 'i').exec(xml);
43235	    if (tagMatch) {
43236	        // Check if it contains rdf:li elements
43237	        const liValues = tagMatch[1].match(/<rdf:li>([^<]*)<\/rdf:li>/g);
43238	        if (liValues && liValues.length === 3) {
43239	            return liValues.map((v)=>v.replace(/<\/?rdf:li>/g, ''));
43240	        }
43241	        return tagMatch[1].trim();
43242	    }
43243	    if (defaultValue !== undefined) return defaultValue;
43244	    throw new Error(`Can't find ${tag} in gainmap metadata`);
43245	};
43246	const extractXMP = (input)=>{
43247	    let str;
43248	    // support node test environment
43249	    if (typeof TextDecoder !== 'undefined') str = new TextDecoder().decode(input);
43250	    else str = input.toString();
43251	    let start = str.indexOf('<x:xmpmeta');
43252	    while(start !== -1){
43253	        const end = str.indexOf('x:xmpmeta>', start);
43254	        const xmpBlock = str.slice(start, end + 10);
43255	        try {
43256	            const gainMapMin = getXMLValue(xmpBlock, 'hdrgm:GainMapMin', '0');
43257	            const gainMapMax = getXMLValue(xmpBlock, 'hdrgm:GainMapMax');
43258	            const gamma = getXMLValue(xmpBlock, 'hdrgm:Gamma', '1');
43259	            const offsetSDR = getXMLValue(xmpBlock, 'hdrgm:OffsetSDR', '0.015625');
43260	            const offsetHDR = getXMLValue(xmpBlock, 'hdrgm:OffsetHDR', '0.015625');
43261	            // These are always attributes, so we can use a simpler regex
43262	            const hdrCapacityMinMatch = /hdrgm:HDRCapacityMin="([^"]*)"/.exec(xmpBlock);
43263	            const hdrCapacityMin = hdrCapacityMinMatch ? hdrCapacityMinMatch[1] : '0';
43264	            const hdrCapacityMaxMatch = /hdrgm:HDRCapacityMax="([^"]*)"/.exec(xmpBlock);
43265	            if (!hdrCapacityMaxMatch) throw new Error('Incomplete gainmap metadata');
43266	            const hdrCapacityMax = hdrCapacityMaxMatch[1];
43267	            return {
43268	                gainMapMin: Array.isArray(gainMapMin) ? gainMapMin.map((v)=>parseFloat(v)) : [
43269	                    parseFloat(gainMapMin),
43270	                    parseFloat(gainMapMin),
43271	                    parseFloat(gainMapMin)
43272	                ],
43273	                gainMapMax: Array.isArray(gainMapMax) ? gainMapMax.map((v)=>parseFloat(v)) : [
43274	                    parseFloat(gainMapMax),
43275	                    parseFloat(gainMapMax),
43276	                    parseFloat(gainMapMax)
43277	                ],
43278	                gamma: Array.isArray(gamma) ? gamma.map((v)=>parseFloat(v)) : [
43279	                    parseFloat(gamma),
43280	                    parseFloat(gamma),
43281	                    parseFloat(gamma)
43282	                ],
43283	                offsetSdr: Array.isArray(offsetSDR) ? offsetSDR.map((v)=>parseFloat(v)) : [
43284	                    parseFloat(offsetSDR),
43285	                    parseFloat(offsetSDR),
43286	                    parseFloat(offsetSDR)
43287	                ],
43288	                offsetHdr: Array.isArray(offsetHDR) ? offsetHDR.map((v)=>parseFloat(v)) : [
43289	                    parseFloat(offsetHDR),
43290	                    parseFloat(offsetHDR),
43291	                    parseFloat(offsetHDR)
43292	                ],
43293	                hdrCapacityMin: parseFloat(hdrCapacityMin),
43294	                hdrCapacityMax: parseFloat(hdrCapacityMax)
43295	            };
43296	        } catch (e) {
43297	        // Continue searching for another xmpmeta block if this one fails
43298	        }
43299	        start = str.indexOf('<x:xmpmeta', end);
43300	    }
43301	};
43302	/**
43303	 * MPF Extractor (Multi Picture Format Extractor)
43304	 * By Henrik S Nilsson 2019
43305	 *
43306	 * Extracts images stored in images based on the MPF format (found here: https://www.cipa.jp/e/std/std-sec.html
43307	 * under "CIPA DC-007-Translation-2021 Multi-Picture Format"
43308	 *
43309	 * Overly commented, and without intention of being complete or production ready.
43310	 * Created to extract depth maps from iPhone images, and to learn about image metadata.
43311	 * Kudos to: Phil Harvey (exiftool), Jaume Sanchez (android-lens-blur-depth-extractor)
43312	 */ class MPFExtractor {
43313	    extract(imageArrayBuffer) {
43314	        return new Promise((resolve, reject)=>{
43315	            const debug = this.options.debug;
43316	            const dataView = new DataView(imageArrayBuffer.buffer);
43317	            // If you're executing this line on a big endian machine, it'll be reversed.
43318	            // bigEnd further down though, refers to the endianness of the image itself.
43319	            if (dataView.getUint16(0) !== 0xffd8) {
43320	                reject(new Error('Not a valid jpeg'));
43321	                return;
43322	            }
43323	            const length = dataView.byteLength;
43324	            let offset = 2;
43325	            let loops = 0;
43326	            let marker; // APP# marker
43327	            while(offset < length){
43328	                if (++loops > 250) {
43329	                    reject(new Error(`Found no marker after ${loops} loops 😵`));
43330	                    return;
43331	                }
43332	                if (dataView.getUint8(offset) !== 0xff) {
43333	                    reject(new Error(`Not a valid marker at offset 0x${offset.toString(16)}, found: 0x${dataView.getUint8(offset).toString(16)}`));
43334	                    return;
43335	                }
43336	                marker = dataView.getUint8(offset + 1);
43337	                if (debug) console.log(`Marker: ${marker.toString(16)}`);
43338	                if (marker === 0xe2) {
43339	                    if (debug) console.log('Found APP2 marker (0xffe2)');
43340	                    // Works for iPhone 8 Plus, X, and XSMax. Or any photos of MPF format.
43341	                    // Great way to visualize image information in html is using Exiftool. E.g.:
43342	                    // ./exiftool.exe -htmldump -wantTrailer photo.jpg > photo.html
43343	                    const formatPt = offset + 4;
43344	                    /*
43345	                     *  Structure of the MP Format Identifier
43346	                     *
43347	                     *  Offset Addr.  | Code (Hex)  | Description
43348	                     *  +00             ff            Marker Prefix      <-- offset
43349	                     *  +01             e2            APP2
43350	                     *  +02             #n            APP2 Field Length
43351	                     *  +03             #n            APP2 Field Length
43352	                     *  +04             4d            'M'                <-- formatPt
43353	                     *  +05             50            'P'
43354	                     *  +06             46            'F'
43355	                     *  +07             00            NULL
43356	                     *                                                   <-- tiffOffset
43357	                     */ if (dataView.getUint32(formatPt) === 0x4d504600) {
43358	                        // Found MPF tag, so we start dig out sub images
43359	                        const tiffOffset = formatPt + 4;
43360	                        let bigEnd; // Endianness from TIFF header
43361	                        // Test for TIFF validity and endianness
43362	                        // 0x4949 and 0x4D4D ('II' and 'MM') marks Little Endian and Big Endian
43363	                        if (dataView.getUint16(tiffOffset) === 0x4949) {
43364	                            bigEnd = false;
vendor: 4,099 bytes, lines 43365-43422
43365	                        } else if (dataView.getUint16(tiffOffset) === 0x4d4d) {
43366	                            bigEnd = true;
43367	                        } else {
43368	                            reject(new Error('No valid endianness marker found in TIFF header'));
43369	                            return;
43370	                        }
43371	                        if (dataView.getUint16(tiffOffset + 2, !bigEnd) !== 0x002a) {
43372	                            reject(new Error('Not valid TIFF data! (no 0x002A marker)'));
43373	                            return;
43374	                        }
43375	                        // 32 bit number stating the offset from the start of the 8 Byte MP Header
43376	                        // to MP Index IFD Least possible value is thus 8 (means 0 offset)
43377	                        const firstIFDOffset = dataView.getUint32(tiffOffset + 4, !bigEnd);
43378	                        if (firstIFDOffset < 0x00000008) {
43379	                            reject(new Error('Not valid TIFF data! (First offset less than 8)'));
43380	                            return;
43381	                        }
43382	                        // Move ahead to MP Index IFD
43383	                        // Assume we're at the first IFD, so firstIFDOffset points to
43384	                        // MP Index IFD and not MP Attributes IFD. (If we try extract from a sub image,
43385	                        // we fail silently here due to this assumption)
43386	                        // Count (2 Byte) | MP Index Fields a.k.a. MP Entries (count * 12 Byte) | Offset of Next IFD (4 Byte)
43387	                        const dirStart = tiffOffset + firstIFDOffset; // Start of IFD (Image File Directory)
43388	                        const count = dataView.getUint16(dirStart, !bigEnd); // Count of MPEntries (2 Byte)
43389	                        // Extract info from MPEntries (starting after Count)
43390	                        const entriesStart = dirStart + 2;
43391	                        let numberOfImages = 0;
43392	                        for(let i = entriesStart; i < entriesStart + 12 * count; i += 12){
43393	                            // Each entry is 12 Bytes long
43394	                            // Check MP Index IFD tags, here we only take tag 0xb001 = Number of images
43395	                            if (dataView.getUint16(i, !bigEnd) === 0xb001) {
43396	                                // stored in Last 4 bytes of its 12 Byte entry.
43397	                                numberOfImages = dataView.getUint32(i + 8, !bigEnd);
43398	                            }
43399	                        }
43400	                        const nextIFDOffsetLen = 4; // 4 Byte offset field that appears after MP Index IFD tags
43401	                        const MPImageListValPt = dirStart + 2 + count * 12 + nextIFDOffsetLen;
43402	                        const images = [];
43403	                        for(let i = MPImageListValPt; i < MPImageListValPt + numberOfImages * 16; i += 16){
43404	                            const image = {
43405	                                MPType: dataView.getUint32(i, !bigEnd),
43406	                                size: dataView.getUint32(i + 4, !bigEnd),
43407	                                // This offset is specified relative to the address of the MP Endian
43408	                                // field in the MP Header, unless the image is a First Individual Image,
43409	                                // in which case the value of the offset shall be NULL (0x00000000).
43410	                                dataOffset: dataView.getUint32(i + 8, !bigEnd),
43411	                                dependantImages: dataView.getUint32(i + 12, !bigEnd),
43412	                                start: -1,
43413	                                end: -1,
43414	                                isFII: false
43415	                            };
43416	                            if (!image.dataOffset) {
43417	                                // dataOffset is 0x00000000 for First Individual Image
43418	                                image.start = 0;
43419	                                image.isFII = true;
43420	                            } else {
43421	                                image.start = tiffOffset + image.dataOffset;
43422	                                image.isFII = false;
vendor: 4,205 bytes, lines 43423-43533
43423	                            }
43424	                            image.end = image.start + image.size;
43425	                            images.push(image);
43426	                        }
43427	                        if (this.options.extractNonFII && images.length) {
43428	                            const bufferBlob = new Blob([
43429	                                dataView
43430	                            ]);
43431	                            const imgs = [];
43432	                            for (const image of images){
43433	                                if (image.isFII && !this.options.extractFII) {
43434	                                    continue; // Skip FII
43435	                                }
43436	                                const imageBlob = bufferBlob.slice(image.start, image.end + 1, 'image/jpeg');
43437	                                // we don't need this
43438	                                // const imageUrl = URL.createObjectURL(imageBlob)
43439	                                // image.img = document.createElement('img')
43440	                                // image.img.src = imageUrl
43441	                                imgs.push(imageBlob);
43442	                            }
43443	                            resolve(imgs);
43444	                        }
43445	                    }
43446	                }
43447	                offset += 2 + dataView.getUint16(offset + 2);
43448	            }
43449	        });
43450	    }
43451	    constructor(options){
43452	        this.options = {
43453	            debug: options && options.debug !== undefined ? options.debug : false,
43454	            extractFII: options && options.extractFII !== undefined ? options.extractFII : true,
43455	            extractNonFII: options && options.extractNonFII !== undefined ? options.extractNonFII : true
43456	        };
43457	    }
43458	}
43459	/**
43460	 * Extracts XMP Metadata and the gain map recovery image
43461	 * from a single JPEG file.
43462	 *
43463	 * @category Decoding Functions
43464	 * @group Decoding Functions
43465	 * @param jpegFile an `Uint8Array` containing and encoded JPEG file
43466	 * @returns an sdr `Uint8Array` compressed in JPEG, a gainMap `Uint8Array` compressed in JPEG and the XMP parsed XMP metadata
43467	 * @throws Error if XMP Metadata is not found
43468	 * @throws Error if Gain map image is not found
43469	 * @example
43470	 * import { FileLoader } from 'three'
43471	 * import { extractGainmapFromJPEG } from '@monogrid/gainmap-js'
43472	 *
43473	 * const jpegFile = await new FileLoader()
43474	 *  .setResponseType('arraybuffer')
43475	 *  .loadAsync('image.jpg')
43476	 *
43477	 * const { sdr, gainMap, metadata } = extractGainmapFromJPEG(jpegFile)
43478	 */ const extractGainmapFromJPEG = async (jpegFile)=>{
43479	    const metadata = extractXMP(jpegFile);
43480	    if (!metadata) throw new XMPMetadataNotFoundError('Gain map XMP metadata not found');
43481	    const mpfExtractor = new MPFExtractor({
43482	        extractFII: true,
43483	        extractNonFII: true
43484	    });
43485	    const images = await mpfExtractor.extract(jpegFile);
43486	    if (images.length !== 2) throw new GainMapNotFoundError('Gain map recovery image not found');
43487	    return {
43488	        sdr: new Uint8Array(await images[0].arrayBuffer()),
43489	        gainMap: new Uint8Array(await images[1].arrayBuffer()),
43490	        metadata
43491	    };
43492	};
43493	/**
43494	 * private function, async get image from blob
43495	 *
43496	 * @param blob
43497	 * @returns
43498	 */ const getHTMLImageFromBlob = (blob)=>{
43499	    return new Promise((resolve, reject)=>{
43500	        const img = document.createElement('img');
43501	        img.onload = ()=>{
43502	            resolve(img);
43503	        };
43504	        img.onerror = (e)=>{
43505	            reject(e);
43506	        };
43507	        img.src = URL.createObjectURL(blob);
43508	    });
43509	};
43510	class LoaderBase extends Loader {
43511	    /**
43512	     * Specify the renderer to use when rendering the gain map
43513	     *
43514	     * @param renderer
43515	     * @returns
43516	     */ setRenderer(renderer) {
43517	        this._renderer = renderer;
43518	        return this;
43519	    }
43520	    /**
43521	     * Specify the renderTarget options to use when rendering the gain map
43522	     *
43523	     * @param options
43524	     * @returns
43525	     */ setRenderTargetOptions(options) {
43526	        this._renderTargetOptions = options;
43527	        return this;
43528	    }
43529	    /**
43530	     * @private
43531	     * @returns
43532	     */ prepareQuadRenderer() {
43533	        if (!this._renderer) console.warn('WARNING: An existing WebGL Renderer was not passed to this Loa
43533der constructor or in setRenderer, the result of this Loader will need to be converted to a Data Texture with toDataTexture() before you can use it in your renderer.');
43534	        // temporary values
43535	        const material = new GainMapDecoderMaterial({
43536	            gainMapMax: [
43537	                1,
43538	                1,
43539	                1
43540	            ],
43541	            gainMapMin: [
43542	                0,
43543	                0,
43544	                0
43545	            ],
43546	            gamma: [
43547	                1,
43548	                1,
43549	                1
43550	            ],
43551	            offsetHdr: [
43552	                1,
43553	                1,
43554	                1
43555	            ],
43556	            offsetSdr: [
43557	                1,
43558	                1,
43559	                1
43560	            ],
43561	            hdrCapacityMax: 1,
43562	            hdrCapacityMin: 0,
43563	            maxDisplayBoost: 1,
43564	            gainMap: new Texture$1(),
43565	            sdr: new Texture$1()
43566	        });
43567	        return new QuadRenderer({
43568	            width: 16,
43569	            height: 16,
43570	            type: HalfFloatType,
43571	            colorSpace: LinearSRGBColorSpace,
43572	            material,
43573	            renderer: this._renderer,
43574	            renderTargetOptions: this._renderTargetOptions
43575	        });
43576	    }
43577	    /**
43578	   * @private
43579	   * @param quadRenderer
43580	   * @param metadata
43581	   * @param sdrBuffer
43582	   * @param gainMapBuffer
43583	   */ async render(quadRenderer, metadata, sdrBuffer, gainMapBuffer) {
43584	        // this is optional, will render a black gain-map if not present
43585	        const gainMapBlob = gainMapBuffer ? new Blob([
43586	            gainMapBuffer
43587	        ], {
43588	            type: 'image/jpeg'
43589	        }) : undefined;
43590	        const sdrBlob = new Blob([
43591	            sdrBuffer
43592	        ], {
43593	            type: 'image/jpeg'
43594	        });
43595	        let sdrImage;
43596	        let gainMapImage;
43597	        let needsFlip = false;
43598	        if (typeof createImageBitmap === 'undefined') {
43599	            const res = await Promise.all([
43600	                gainMapBlob ? getHTMLImageFromBlob(gainMapBlob) : Promise.resolve(undefined),
43601	                getHTMLImageFromBlob(sdrBlob)
43602	            ]);
43603	            gainMapImage = res[0];
43604	            sdrImage = res[1];
43605	            needsFlip = true;
43606	        } else {
43607	            const res = await Promise.all([
43608	                gainMapBlob ? createImageBitmap(gainMapBlob, {
43609	                    imageOrientation: 'flipY'
43610	                }) : Promise.resolve(undefined),
43611	                createImageBitmap(sdrBlob, {
43612	                    imageOrientation: 'flipY'
43613	                })
43614	            ]);
43615	            gainMapImage = res[0];
43616	            sdrImage = res[1];
43617	        }
43618	        const gainMap = new Texture$1(gainMapImage || new ImageData(2, 2), UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, LinearMipMapLinearFilter, RGBAFormat, UnsignedByteType, 1, LinearSRGBColorSpace);
43619	        gainMap.flipY = needsFlip;
43620	        gainMap.needsUpdate = true;
43621	        const sdr = new Texture$1(sdrImage, UVMapping, ClampToEdgeWrapping, ClampToEdgeWrapping, LinearFilter, LinearMipMapLinearFilter, RGBAFormat, UnsignedByteType, 1, SRGBColorSpace);
43622	        sdr.flipY = needsFlip;
43623	        sdr.needsUpdate = true;
43624	        quadRenderer.width = sdrImage.width;
43625	        quadRenderer.height = sdrImage.height;
43626	        quadRenderer.material.gainMap = gainMap;
43627	        quadRenderer.material.sdr = sdr;
43628	        quadRenderer.material.gainMapMin = metadata.gainMapMin;
43629	        quadRenderer.material.gainMapMax = metadata.gainMapMax;
43630	        quadRenderer.material.offsetHdr = metadata.offsetHdr;
43631	        quadRenderer.material.offsetSdr = metadata.offsetSdr;
43632	        quadRenderer.material.gamma = metadata.gamma;
43633	        quadRenderer.material.hdrCapacityMin = metadata.hdrCapacityMin;
43634	        quadRenderer.material.hdrCapacityMax = metadata.hdrCapacityMax;
43635	        quadRenderer.material.maxDisplayBoost = Math.pow(2, metadata.hdrCapacityMax);
43636	        quadRenderer.material.needsUpdate = true;
43637	        quadRenderer.render();
43638	    }
43639	    /**
43640	     *
43641	     * @param renderer
43642	     * @param manager
43643	     */ constructor(renderer, manager){
43644	        super(manager);
43645	        if (renderer) this._renderer = renderer;
43646	        this._internalLoadingManager = new LoadingManager();
43647	    }
43648	}
43649	/**
43650	 * A Three.js Loader for a JPEG with embedded gainmap metadata.
43651	 *
43652	 * @category Loaders
43653	 * @group Loaders
43654	 *
43655	 * @example
43656	 * import { HDRJPGLoader } from '@monogrid/gainmap-js'
43657	 * import {
43658	 *   EquirectangularReflectionMapping,
43659	 *   LinearFilter,
43660	 *   Mesh,
43661	 *   MeshBasicMaterial,
43662	 *   PerspectiveCamera,
43663	 *   PlaneGeometry,
43664	 *   Scene,
43665	 *   WebGLRenderer
43666	 * } from 'three'
43667	 *
43668	 * const renderer = new WebGLRenderer()
43669	 *
43670	 * const loader = new HDRJPGLoader(renderer)
43671	 *
43672	 * const result = await loader.loadAsync('gainmap.jpeg')
43673	 * // `result` can be used to populate a Texture
43674	 *
43675	 * const scene = new Scene()
43676	 * const mesh = new Mesh(
43677	 *   new PlaneGeometry(),
43678	 *   new MeshBasicMaterial({ map: result.renderTarget.texture })
43679	 * )
43680	 * scene.add(mesh)
43681	 * renderer.render(scene, new PerspectiveCamera())
43682	 *
43683	 * // Starting from three.js r159
43684	 * // `result.renderTarget.texture` can
43685	 * // also be used as Equirectangular scene background
43686	 * //
43687	 * // it was previously needed to convert it
43688	 * // to a DataTexture with `result.toDataTexture()`
43689	 * scene.background = result.renderTarget.texture
43690	 * scene.background.mapping = EquirectangularReflectionMapping
43691	 *
43692	 * // result must be manually disposed
43693	 * // when you are done using it
43694	 * result.dispose()
43695	 *
43696	 */ class HDRJPGLoader extends LoaderBase {
43697	    /**
43698	     * Loads a JPEG containing gain map metadata
vendor: 6,231 bytes, lines 43699-43826
43699	     * Renders a normal SDR image if gainmap data is not found
43700	     *
43701	     * @param url An array in the form of [sdr.jpg, gainmap.jpg, metadata.json]
43702	     * @param onLoad Load complete callback, will receive the result
43703	     * @param onProgress Progress callback, will receive a {@link ProgressEvent}
43704	     * @param onError Error callback
43705	     * @returns
43706	     */ load(url, onLoad, onProgress, onError) {
43707	        const quadRenderer = this.prepareQuadRenderer();
43708	        const loader = new FileLoader(this._internalLoadingManager);
43709	        loader.setResponseType('arraybuffer');
43710	        loader.setRequestHeader(this.requestHeader);
43711	        loader.setPath(this.path);
43712	        loader.setWithCredentials(this.withCredentials);
43713	        this.manager.itemStart(url);
43714	        loader.load(url, async (jpeg)=>{
43715	            /* istanbul ignore if
43716	             this condition exists only because of three.js types + strict mode
43717	            */ if (typeof jpeg === 'string') throw new Error('Invalid buffer, received [string], was expecting [ArrayBuffer]');
43718	            const jpegBuffer = new Uint8Array(jpeg);
43719	            let sdrJPEG;
43720	            let gainMapJPEG;
43721	            let metadata;
43722	            try {
43723	                const extractionResult = await extractGainmapFromJPEG(jpegBuffer);
43724	                // gain map is successfully reconstructed
43725	                sdrJPEG = extractionResult.sdr;
43726	                gainMapJPEG = extractionResult.gainMap;
43727	                metadata = extractionResult.metadata;
43728	            } catch (e) {
43729	                // render the SDR version if this is not a gainmap
43730	                if (e instanceof XMPMetadataNotFoundError || e instanceof GainMapNotFoundError) {
43731	                    console.warn(`Failure to reconstruct an HDR image from ${url}: Gain map metadata not found in the file, HDRJPGLoader will render the SDR jpeg`);
43732	                    metadata = {
43733	                        gainMapMin: [
43734	                            0,
43735	                            0,
43736	                            0
43737	                        ],
43738	                        gainMapMax: [
43739	                            1,
43740	                            1,
43741	                            1
43742	                        ],
43743	                        gamma: [
43744	                            1,
43745	                            1,
43746	                            1
43747	                        ],
43748	                        hdrCapacityMin: 0,
43749	                        hdrCapacityMax: 1,
43750	                        offsetHdr: [
43751	                            0,
43752	                            0,
43753	                            0
43754	                        ],
43755	                        offsetSdr: [
43756	                            0,
43757	                            0,
43758	                            0
43759	                        ]
43760	                    };
43761	                    sdrJPEG = jpegBuffer;
43762	                } else {
43763	                    throw e;
43764	                }
43765	            }
43766	            // solves #16
43767	            try {
43768	                await this.render(quadRenderer, metadata, sdrJPEG, gainMapJPEG);
43769	            } catch (error) {
43770	                this.manager.itemError(url);
43771	                if (typeof onError === 'function') onError(error);
43772	                quadRenderer.disposeOnDemandRenderer();
43773	                return;
43774	            }
43775	            if (typeof onLoad === 'function') onLoad(quadRenderer);
43776	            this.manager.itemEnd(url);
43777	            quadRenderer.disposeOnDemandRenderer();
43778	        }, onProgress, (error)=>{
43779	            this.manager.itemError(url);
43780	            if (typeof onError === 'function') onError(error);
43781	        });
43782	        return quadRenderer;
43783	    }
43784	}
43785
43786	// https://github.com/mrdoob/three.js/issues/5552
43787	// http://en.wikipedia.org/wiki/RGBE_image_format
43788	class RGBELoader extends DataTextureLoader {
43789	    // adapted from http://www.graphics.cornell.edu/~bjw/rgbe.html
43790	    parse(buffer) {
43791	        const /* default error routine.  change this to change error handling */ rgbe_read_error = 1, rgbe_write_error = 2, rgbe_format_error = 3, rgbe_memory_error = 4, rgbe_error = function(rgbe_error_code, msg) {
43792	            switch(rgbe_error_code){
43793	                case rgbe_read_error:
43794	                    throw new Error('THREE.RGBELoader: Read Error: ' + (msg || ''));
43795	                case rgbe_write_error:
43796	                    throw new Error('THREE.RGBELoader: Write Error: ' + (msg || ''));
43797	                case rgbe_format_error:
43798	                    throw new Error('THREE.RGBELoader: Bad File Format: ' + (msg || ''));
43799	                default:
43800	                case rgbe_memory_error:
43801	                    throw new Error('THREE.RGBELoader: Memory Error: ' + (msg || ''));
43802	            }
43803	        }, /* offsets to red, green, and blue components in a data (float) pixel */ //RGBE_DATA_RED = 0,
43804	        //RGBE_DATA_GREEN = 1,
43805	        //RGBE_DATA_BLUE = 2,
43806	        /* number of floats per pixel, use 4 since stored in rgba image format */ //RGBE_DATA_SIZE = 4,
43807	        /* flags indicating which fields in an rgbe_header_info are valid */ RGBE_VALID_PROGRAMTYPE = 1, RGBE_VALID_FORMAT = 2, RGBE_VALID_DIMENSIONS = 4, NEWLINE = '\n', fgets = function(buffer, lineLimit, consume) {
43808	            const chunkSize = 128;
43809	            lineLimit = !lineLimit ? 1024 : lineLimit;
43810	            let p = buffer.pos, i = -1, len = 0, s = '', chunk = String.fromCharCode.apply(null, new Uint16Array(buffer.subarray(p, p + chunkSize)));
43811	            while(0 > (i = chunk.indexOf(NEWLINE)) && len < lineLimit && p < buffer.byteLength){
43812	                s += chunk;
43813	                len += chunk.length;
43814	                p += chunkSize;
43815	                chunk += String.fromCharCode.apply(null, new Uint16Array(buffer.subarray(p, p + chunkSize)));
43816	            }
43817	            if (-1 < i) {
43818	                /*for (i=l-1; i>=0; i--) {
43819							byteCode = m.charCodeAt(i);
43820							if (byteCode > 0x7f && byteCode <= 0x7ff) byteLen++;
43821							else if (byteCode > 0x7ff && byteCode <= 0xffff) byteLen += 2;
43822							if (byteCode >= 0xDC00 && byteCode <= 0xDFFF) i--; //trail surrogate
43823						}*/ buffer.pos += len + i + 1;
43824	                return s + chunk.slice(0, i);
43825	            }
43826	            return false;
vendor: 6,994 bytes, lines 43827-43956
43827	        }, /* minimal header reading.  modify if you want to parse more information */ RGBE_ReadHeader = function(buffer) {
43828	            // regexes to parse header info fields
43829	            const magic_token_re = /^#\?(\S+)/, gamma_re = /^\s*GAMMA\s*=\s*(\d+(\.\d+)?)\s*$/, exposure_re = /^\s*EXPOSURE\s*=\s*(\d+(\.\d+)?)\s*$/, format_re = /^\s*FORMAT=(\S+)\s*$/, dimensions_re = /^\s*\-Y\s+(\d+)\s+\+X\s+(\d+)\s*$/, // RGBE format header struct
43830	            header = {
43831	                valid: 0,
43832	                /* indicate which fields are valid */ string: '',
43833	                /* the actual header string */ comments: '',
43834	                /* comments found in header */ programtype: 'RGBE',
43835	                /* listed at beginning of file to identify it after "#?". defaults to "RGBE" */ format: '',
43836	                /* RGBE format, default 32-bit_rle_rgbe */ gamma: 1.0,
43837	                /* image has already been gamma corrected with given gamma. defaults to 1.0 (no correction) */ exposure: 1.0,
43838	                /* a value of 1.0 in an image corresponds to <exposure> watts/steradian/m^2. defaults to 1.0 */ width: 0,
43839	                height: 0 /* image dimensions, width/height */ 
43840	            };
43841	            let line, match;
43842	            if (buffer.pos >= buffer.byteLength || !(line = fgets(buffer))) {
43843	                rgbe_error(rgbe_read_error, 'no header found');
43844	            }
43845	            /* if you want to require the magic token then uncomment the next line */ if (!(match = line.match(magic_token_re))) {
43846	                rgbe_error(rgbe_format_error, 'bad initial token');
43847	            }
43848	            header.valid |= RGBE_VALID_PROGRAMTYPE;
43849	            header.programtype = match[1];
43850	            header.string += line + '\n';
43851	            while(true){
43852	                line = fgets(buffer);
43853	                if (false === line) break;
43854	                header.string += line + '\n';
43855	                if ('#' === line.charAt(0)) {
43856	                    header.comments += line + '\n';
43857	                    continue; // comment line
43858	                }
43859	                if (match = line.match(gamma_re)) {
43860	                    header.gamma = parseFloat(match[1]);
43861	                }
43862	                if (match = line.match(exposure_re)) {
43863	                    header.exposure = parseFloat(match[1]);
43864	                }
43865	                if (match = line.match(format_re)) {
43866	                    header.valid |= RGBE_VALID_FORMAT;
43867	                    header.format = match[1]; //'32-bit_rle_rgbe';
43868	                }
43869	                if (match = line.match(dimensions_re)) {
43870	                    header.valid |= RGBE_VALID_DIMENSIONS;
43871	                    header.height = parseInt(match[1], 10);
43872	                    header.width = parseInt(match[2], 10);
43873	                }
43874	                if (header.valid & RGBE_VALID_FORMAT && header.valid & RGBE_VALID_DIMENSIONS) break;
43875	            }
43876	            if (!(header.valid & RGBE_VALID_FORMAT)) {
43877	                rgbe_error(rgbe_format_error, 'missing format specifier');
43878	            }
43879	            if (!(header.valid & RGBE_VALID_DIMENSIONS)) {
43880	                rgbe_error(rgbe_format_error, 'missing image size specifier');
43881	            }
43882	            return header;
43883	        }, RGBE_ReadPixels_RLE = function(buffer, w, h) {
43884	            const scanline_width = w;
43885	            if (scanline_width < 8 || scanline_width > 0x7fff || // this file is not run length encoded
43886	            2 !== buffer[0] || 2 !== buffer[1] || buffer[2] & 0x80) {
43887	                // return the flat buffer
43888	                return new Uint8Array(buffer);
43889	            }
43890	            if (scanline_width !== (buffer[2] << 8 | buffer[3])) {
43891	                rgbe_error(rgbe_format_error, 'wrong scanline width');
43892	            }
43893	            const data_rgba = new Uint8Array(4 * w * h);
43894	            if (!data_rgba.length) {
43895	                rgbe_error(rgbe_memory_error, 'unable to allocate buffer space');
43896	            }
43897	            let offset = 0, pos = 0;
43898	            const ptr_end = 4 * scanline_width;
43899	            const rgbeStart = new Uint8Array(4);
43900	            const scanline_buffer = new Uint8Array(ptr_end);
43901	            let num_scanlines = h;
43902	            // read in each successive scanline
43903	            while(num_scanlines > 0 && pos < buffer.byteLength){
43904	                if (pos + 4 > buffer.byteLength) {
43905	                    rgbe_error(rgbe_read_error);
43906	                }
43907	                rgbeStart[0] = buffer[pos++];
43908	                rgbeStart[1] = buffer[pos++];
43909	                rgbeStart[2] = buffer[pos++];
43910	                rgbeStart[3] = buffer[pos++];
43911	                if (2 != rgbeStart[0] || 2 != rgbeStart[1] || (rgbeStart[2] << 8 | rgbeStart[3]) != scanline_width) {
43912	                    rgbe_error(rgbe_format_error, 'bad rgbe scanline format');
43913	                }
43914	                // read each of the four channels for the scanline into the buffer
43915	                // first red, then green, then blue, then exponent
43916	                let ptr = 0, count;
43917	                while(ptr < ptr_end && pos < buffer.byteLength){
43918	                    count = buffer[pos++];
43919	                    const isEncodedRun = count > 128;
43920	                    if (isEncodedRun) count -= 128;
43921	                    if (0 === count || ptr + count > ptr_end) {
43922	                        rgbe_error(rgbe_format_error, 'bad scanline data');
43923	                    }
43924	                    if (isEncodedRun) {
43925	                        // a (encoded) run of the same value
43926	                        const byteValue = buffer[pos++];
43927	                        for(let i = 0; i < count; i++){
43928	                            scanline_buffer[ptr++] = byteValue;
43929	                        }
43930	                    //ptr += count;
43931	                    } else {
43932	                        // a literal-run
43933	                        scanline_buffer.set(buffer.subarray(pos, pos + count), ptr);
43934	                        ptr += count;
43935	                        pos += count;
43936	                    }
43937	                }
43938	                // now convert data from buffer into rgba
43939	                // first red, then green, then blue, then exponent (alpha)
43940	                const l = scanline_width; //scanline_buffer.byteLength;
43941	                for(let i = 0; i < l; i++){
43942	                    let off = 0;
43943	                    data_rgba[offset] = scanline_buffer[i + off];
43944	                    off += scanline_width; //1;
43945	                    data_rgba[offset + 1] = scanline_buffer[i + off];
43946	                    off += scanline_width; //1;
43947	                    data_rgba[offset + 2] = scanline_buffer[i + off];
43948	                    off += scanline_width; //1;
43949	                    data_rgba[offset + 3] = scanline_buffer[i + off];
43950	                    offset += 4;
43951	                }
43952	                num_scanlines--;
43953	            }
43954	            return data_rgba;
43955	        };
43956	        const RGBEByteToRGBFloat = function(sourceArray, sourceOffset, destArray, destOff
vendor: 14,181 bytes, lines 43956-44493
43956set) {
43957	            const e = sourceArray[sourceOffset + 3];
43958	            const scale = Math.pow(2.0, e - 128.0) / 255.0;
43959	            destArray[destOffset + 0] = sourceArray[sourceOffset + 0] * scale;
43960	            destArray[destOffset + 1] = sourceArray[sourceOffset + 1] * scale;
43961	            destArray[destOffset + 2] = sourceArray[sourceOffset + 2] * scale;
43962	            destArray[destOffset + 3] = 1;
43963	        };
43964	        const RGBEByteToRGBHalf = function(sourceArray, sourceOffset, destArray, destOffset) {
43965	            const e = sourceArray[sourceOffset + 3];
43966	            const scale = Math.pow(2.0, e - 128.0) / 255.0;
43967	            // clamping to 65504, the maximum representable value in float16
43968	            destArray[destOffset + 0] = DataUtils.toHalfFloat(Math.min(sourceArray[sourceOffset + 0] * scale, 65504));
43969	            destArray[destOffset + 1] = DataUtils.toHalfFloat(Math.min(sourceArray[sourceOffset + 1] * scale, 65504));
43970	            destArray[destOffset + 2] = DataUtils.toHalfFloat(Math.min(sourceArray[sourceOffset + 2] * scale, 65504));
43971	            destArray[destOffset + 3] = DataUtils.toHalfFloat(1);
43972	        };
43973	        const byteArray = new Uint8Array(buffer);
43974	        byteArray.pos = 0;
43975	        const rgbe_header_info = RGBE_ReadHeader(byteArray);
43976	        const w = rgbe_header_info.width, h = rgbe_header_info.height, image_rgba_data = RGBE_ReadPixels_RLE(byteArray.subarray(byteArray.pos), w, h);
43977	        let data, type;
43978	        let numElements;
43979	        switch(this.type){
43980	            case FloatType:
43981	                numElements = image_rgba_data.length / 4;
43982	                const floatArray = new Float32Array(numElements * 4);
43983	                for(let j = 0; j < numElements; j++){
43984	                    RGBEByteToRGBFloat(image_rgba_data, j * 4, floatArray, j * 4);
43985	                }
43986	                data = floatArray;
43987	                type = FloatType;
43988	                break;
43989	            case HalfFloatType:
43990	                numElements = image_rgba_data.length / 4;
43991	                const halfArray = new Uint16Array(numElements * 4);
43992	                for(let j = 0; j < numElements; j++){
43993	                    RGBEByteToRGBHalf(image_rgba_data, j * 4, halfArray, j * 4);
43994	                }
43995	                data = halfArray;
43996	                type = HalfFloatType;
43997	                break;
43998	            default:
43999	                throw new Error('THREE.RGBELoader: Unsupported type: ' + this.type);
44000	        }
44001	        return {
44002	            width: w,
44003	            height: h,
44004	            data: data,
44005	            header: rgbe_header_info.string,
44006	            gamma: rgbe_header_info.gamma,
44007	            exposure: rgbe_header_info.exposure,
44008	            type: type
44009	        };
44010	    }
44011	    setDataType(value) {
44012	        this.type = value;
44013	        return this;
44014	    }
44015	    load(url, onLoad, onProgress, onError) {
44016	        function onLoadCallback(texture, texData) {
44017	            switch(texture.type){
44018	                case FloatType:
44019	                case HalfFloatType:
44020	                    texture.colorSpace = LinearSRGBColorSpace;
44021	                    texture.minFilter = LinearFilter;
44022	                    texture.magFilter = LinearFilter;
44023	                    texture.generateMipmaps = false;
44024	                    texture.flipY = true;
44025	                    break;
44026	            }
44027	            if (onLoad) onLoad(texture, texData);
44028	        }
44029	        return super.load(url, onLoadCallback, onProgress, onError);
44030	    }
44031	    constructor(manager){
44032	        super(manager);
44033	        this.type = HalfFloatType;
44034	    }
44035	}
44036
44037	const legacy = {
44038	    topLight: {
44039	        intensity: 500,
44040	        position: [
44041	            0.418,
44042	            16.199,
44043	            0.300
44044	        ]
44045	    },
44046	    room: {
44047	        position: [
44048	            -0.757,
44049	            13.219,
44050	            0.717
44051	        ],
44052	        scale: [
44053	            31.713,
44054	            28.305,
44055	            28.591
44056	        ]
44057	    },
44058	    boxes: [
44059	        {
44060	            position: [
44061	                -10.906,
44062	                2.009,
44063	                1.846
44064	            ],
44065	            rotation: -0.195,
44066	            scale: [
44067	                2.328,
44068	                7.905,
44069	                4.651
44070	            ]
44071	        },
44072	        {
44073	            position: [
44074	                -5.607,
44075	                -0.754,
44076	                -0.758
44077	            ],
44078	            rotation: 0.994,
44079	            scale: [
44080	                1.970,
44081	                1.534,
44082	                3.955
44083	            ]
44084	        },
44085	        {
44086	            position: [
44087	                6.167,
44088	                0.857,
44089	                7.803
44090	            ],
44091	            rotation: 0.561,
44092	            scale: [
44093	                3.927,
44094	                6.285,
44095	                3.687
44096	            ]
44097	        },
44098	        {
44099	            position: [
44100	                -2.017,
44101	                0.018,
44102	                6.124
44103	            ],
44104	            rotation: 0.333,
44105	            scale: [
44106	                2.002,
44107	                4.566,
44108	                2.064
44109	            ]
44110	        },
44111	        {
44112	            position: [
44113	                2.291,
44114	                -0.756,
44115	                -2.621
44116	            ],
44117	            rotation: -0.286,
44118	            scale: [
44119	                1.546,
44120	                1.552,
44121	                1.496
44122	            ]
44123	        },
44124	        {
44125	            position: [
44126	                -2.193,
44127	                -0.369,
44128	                -5.547
44129	            ],
44130	            rotation: 0.516,
44131	            scale: [
44132	                3.875,
44133	                3.487,
44134	                2.986
44135	            ]
44136	        }
44137	    ],
44138	    lights: [
44139	        {
44140	            intensity: 50,
44141	            position: [
44142	                -16.116,
44143	                14.37,
44144	                8.208
44145	            ],
44146	            scale: [
44147	                0.1,
44148	                2.428,
44149	                2.739
44150	            ]
44151	        },
44152	        {
44153	            intensity: 50,
44154	            position: [
44155	                -16.109,
44156	                18.021,
44157	                -8.207
44158	            ],
44159	            scale: [
44160	                0.1,
44161	                2.425,
44162	                2.751
44163	            ]
44164	        },
44165	        {
44166	            intensity: 17,
44167	            position: [
44168	                14.904,
44169	                12.198,
44170	                -1.832
44171	            ],
44172	            scale: [
44173	                0.15,
44174	                4.265,
44175	                6.331
44176	            ]
44177	        },
44178	        {
44179	            intensity: 43,
44180	            position: [
44181	                -0.462,
44182	                8.89,
44183	                14.520
44184	            ],
44185	            scale: [
44186	                4.38,
44187	                5.441,
44188	                0.088
44189	            ]
44190	        },
44191	        {
44192	            intensity: 20,
44193	            position: [
44194	                3.235,
44195	                11.486,
44196	                -12.541
44197	            ],
44198	            scale: [
44199	                2.5,
44200	                2.0,
44201	                0.1
44202	            ]
44203	        },
44204	        {
44205	            intensity: 100,
44206	            position: [
44207	                0.0,
44208	                20.0,
44209	                0.0
44210	            ],
44211	            scale: [
44212	                1.0,
44213	                0.1,
44214	                1.0
44215	            ]
44216	        }
44217	    ]
44218	};
44219	const neutral = {
44220	    topLight: {
44221	        intensity: 400,
44222	        position: [
44223	            0.5,
44224	            14.0,
44225	            0.5
44226	        ]
44227	    },
44228	    room: {
44229	        position: [
44230	            0.0,
44231	            13.2,
44232	            0.0
44233	        ],
44234	        scale: [
44235	            31.5,
44236	            28.5,
44237	            31.5
44238	        ]
44239	    },
44240	    boxes: [
44241	        {
44242	            position: [
44243	                -10.906,
44244	                -1,
44245	                1.846
44246	            ],
44247	            rotation: -0.195,
44248	            scale: [
44249	                2.328,
44250	                7.905,
44251	                4.651
44252	            ]
44253	        },
44254	        {
44255	            position: [
44256	                -5.607,
44257	                -0.754,
44258	                -0.758
44259	            ],
44260	            rotation: 0.994,
44261	            scale: [
44262	                1.970,
44263	                1.534,
44264	                3.955
44265	            ]
44266	        },
44267	        {
44268	            position: [
44269	                6.167,
44270	                -0.16,
44271	                7.803
44272	            ],
44273	            rotation: 0.561,
44274	            scale: [
44275	                3.927,
44276	                6.285,
44277	                3.687
44278	            ]
44279	        },
44280	        {
44281	            position: [
44282	                -2.017,
44283	                0.018,
44284	                6.124
44285	            ],
44286	            rotation: 0.333,
44287	            scale: [
44288	                2.002,
44289	                4.566,
44290	                2.064
44291	            ]
44292	        },
44293	        {
44294	            position: [
44295	                2.291,
44296	                -0.756,
44297	                -2.621
44298	            ],
44299	            rotation: -0.286,
44300	            scale: [
44301	                1.546,
44302	                1.552,
44303	                1.496
44304	            ]
44305	        },
44306	        {
44307	            position: [
44308	                -2.193,
44309	                -0.369,
44310	                -5.547
44311	            ],
44312	            rotation: 0.516,
44313	            scale: [
44314	                3.875,
44315	                3.487,
44316	                2.986
44317	            ]
44318	        }
44319	    ],
44320	    lights: [
44321	        {
44322	            intensity: 80,
44323	            position: [
44324	                -14,
44325	                10.0,
44326	                8.0
44327	            ],
44328	            scale: [
44329	                0.1,
44330	                2.5,
44331	                2.5
44332	            ]
44333	        },
44334	        {
44335	            intensity: 80,
44336	            position: [
44337	                -14,
44338	                14.0,
44339	                -4
44340	            ],
44341	            scale: [
44342	                0.1,
44343	                2.5,
44344	                2.5
44345	            ]
44346	        },
44347	        {
44348	            intensity: 23,
44349	            position: [
44350	                14.0,
44351	                12.0,
44352	                0.0
44353	            ],
44354	            scale: [
44355	                0.1,
44356	                5.0,
44357	                5.0
44358	            ]
44359	        },
44360	        {
44361	            intensity: 16,
44362	            position: [
44363	                0.0,
44364	                9.0,
44365	                14.0
44366	            ],
44367	            scale: [
44368	                5.0,
44369	                5.0,
44370	                0.1
44371	            ]
44372	        },
44373	        {
44374	            intensity: 80,
44375	            position: [
44376	                7.0,
44377	                8.0,
44378	                -14
44379	            ],
44380	            scale: [
44381	                2.5,
44382	                2.5,
44383	                0.1
44384	            ]
44385	        },
44386	        {
44387	            intensity: 80,
44388	            position: [
44389	                -7,
44390	                16.0,
44391	                -14
44392	            ],
44393	            scale: [
44394	                2.5,
44395	                2.5,
44396	                0.1
44397	            ]
44398	        },
44399	        {
44400	            intensity: 1,
44401	            position: [
44402	                0.0,
44403	                20.0,
44404	                0.0
44405	            ],
44406	            scale: [
44407	                0.1,
44408	                0.1,
44409	                0.1
44410	            ]
44411	        }
44412	    ]
44413	};
44414	class EnvironmentScene extends Scene {
44415	    createAreaLightMaterial(intensity) {
44416	        const material = new MeshBasicMaterial();
44417	        material.color.setScalar(intensity);
44418	        return material;
44419	    }
44420	    constructor(name){
44421	        super();
44422	        this.position.y = -3.5;
44423	        const geometry = new BoxGeometry();
44424	        geometry.deleteAttribute('uv');
44425	        const roomMaterial = new MeshStandardMaterial({
44426	            metalness: 0,
44427	            side: BackSide
44428	        });
44429	        const boxMaterial = new MeshStandardMaterial({
44430	            metalness: 0
44431	        });
44432	        const data = name == 'legacy' ? legacy : neutral;
44433	        const mainLight = new PointLight(0xffffff, data.topLight.intensity, 28, 2);
44434	        mainLight.position.set(...data.topLight.position);
44435	        this.add(mainLight);
44436	        const room = new Mesh(geometry, roomMaterial);
44437	        room.position.set(...data.room.position);
44438	        room.scale.set(...data.room.scale);
44439	        this.add(room);
44440	        for (const box of data.boxes){
44441	            const box1 = new Mesh(geometry, boxMaterial);
44442	            box1.position.set(...box.position);
44443	            box1.rotation.set(0, box.rotation, 0);
44444	            box1.scale.set(...box.scale);
44445	            this.add(box1);
44446	        }
44447	        for (const light of data.lights){
44448	            const light1 = new Mesh(geometry, this.createAreaLightMaterial(light.intensity));
44449	            light1.position.set(...light.position);
44450	            light1.scale.set(...light.scale);
44451	            this.add(light1);
44452	        }
44453	    }
44454	}
44455
44456	const GENERATED_SIGMA = 0.04;
44457	const MAX_SAMPLES = 20;
44458	const HDR_FILE_RE = /\.hdr(\.js)?$/;
44459	class TextureUtils {
44460	    ldrLoader(withCredentials) {
44461	        if (this._ldrLoader == null) {
44462	            this._ldrLoader = new TextureLoader();
44463	        }
44464	        this._ldrLoader.setWithCredentials(withCredentials);
44465	        return this._ldrLoader;
44466	    }
44467	    imageLoader(withCredentials) {
44468	        if (this._imageLoader == null) {
44469	            this._imageLoader = new HDRJPGLoader(this.threeRenderer);
44470	        }
44471	        this._imageLoader.setWithCredentials(withCredentials);
44472	        return this._imageLoader;
44473	    }
44474	    hdrLoader(withCredentials) {
44475	        if (this._hdrLoader == null) {
44476	            this._hdrLoader = new RGBELoader();
44477	            this._hdrLoader.setDataType(HalfFloatType);
44478	        }
44479	        this._hdrLoader.setWithCredentials(withCredentials);
44480	        return this._hdrLoader;
44481	    }
44482	    async getLottieLoader(withCredentials) {
44483	        if (this._lottieLoader == null) {
44484	            const { LottieLoader } = await import( this.lottieLoaderUrl);
44485	            this._lottieLoader = new LottieLoader();
44486	        }
44487	        this._lottieLoader.setWithCredentials(withCredentials);
44488	        return this._lottieLoader;
44489	    }
44490	    async loadImage(url, withCredentials) {
44491	        const texture = await new Promise((resolve, reject)=>this.ldrLoader(withCredentials).load(url, resolve, ()=>{}, reject));
44492	        texture.name = url;
44493	        texture.flipY = false;
vendor: 5,594 bytes, lines 44494-44618
44494	        return texture;
44495	    }
44496	    async loadLottie(url, quality, withCredentials) {
44497	        const loader = await this.getLottieLoader(withCredentials);
44498	        loader.setQuality(quality);
44499	        const texture = await new Promise((resolve, reject)=>loader.load(url, resolve, ()=>{}, reject));
44500	        texture.name = url;
44501	        return texture;
44502	    }
44503	    async loadEquirect(url, withCredentials = false, progressCallback = ()=>{}) {
44504	        try {
44505	            const isHDR = HDR_FILE_RE.test(url);
44506	            const loader = isHDR ? this.hdrLoader(withCredentials) : this.imageLoader(withCredentials);
44507	            const texture = await new Promise((resolve, reject)=>loader.load(url, (result)=>{
44508	                    const { renderTarget } = result;
44509	                    if (renderTarget != null) {
44510	                        const { texture } = renderTarget;
44511	                        result.dispose(false);
44512	                        resolve(texture);
44513	                    } else {
44514	                        resolve(result);
44515	                    }
44516	                }, (event)=>{
44517	                    progressCallback(event.loaded / event.total * 0.9);
44518	                }, reject));
44519	            progressCallback(1.0);
44520	            texture.name = url;
44521	            texture.mapping = EquirectangularReflectionMapping;
44522	            if (!isHDR) {
44523	                texture.colorSpace = SRGBColorSpace;
44524	            }
44525	            return texture;
44526	        } finally{
44527	            if (progressCallback) {
44528	                progressCallback(1);
44529	            }
44530	        }
44531	    }
44532	 async generateEnvironmentMapAndSkybox(skyboxUrl = null, environmentMapUrl = null, progressCallback = ()=>{}, withCredentials = false) {
44533	        const useAltEnvironment = environmentMapUrl !== 'legacy';
44534	        if (environmentMapUrl === 'legacy' || environmentMapUrl === 'neutral') {
44535	            environmentMapUrl = null;
44536	        }
44537	        environmentMapUrl = deserializeUrl(environmentMapUrl);
44538	        let skyboxLoads = Promise.resolve(null);
44539	        let environmentMapLoads;
44540	        if (!!skyboxUrl) {
44541	            skyboxLoads = this.loadEquirectFromUrl(skyboxUrl, withCredentials, progressCallback);
44542	        }
44543	        if (!!environmentMapUrl) {
44544	            environmentMapLoads = this.loadEquirectFromUrl(environmentMapUrl, withCredentials, progressCallback);
44545	        } else if (!!skyboxUrl) {
44546	            environmentMapLoads = this.loadEquirectFromUrl(skyboxUrl, withCredentials, progressCallback);
44547	        } else {
44548	            environmentMapLoads = useAltEnvironment ? this.loadGeneratedEnvironmentMapAlt() : this.loadGeneratedEnvironmentMap();
44549	        }
44550	        const [environmentMap, skybox] = await Promise.all([
44551	            environmentMapLoads,
44552	            skyboxLoads
44553	        ]);
44554	        if (environmentMap == null) {
44555	            throw new Error('Failed to load environment map.');
44556	        }
44557	        return {
44558	            environmentMap,
44559	            skybox
44560	        };
44561	    }
44562	 async loadEquirectFromUrl(url, withCredentials, progressCallback) {
44563	        if (!this.skyboxCache.has(url)) {
44564	            const skyboxMapLoads = this.loadEquirect(url, withCredentials, progressCallback);
44565	            this.skyboxCache.set(url, skyboxMapLoads);
44566	        }
44567	        return this.skyboxCache.get(url);
44568	    }
44569	    async GenerateEnvironmentMap(scene, name) {
44570	        await timePasses();
44571	        const renderer = this.threeRenderer;
44572	        const cubeTarget = new WebGLCubeRenderTarget(256, {
44573	            generateMipmaps: false,
44574	            type: HalfFloatType,
44575	            format: RGBAFormat,
44576	            colorSpace: LinearSRGBColorSpace,
44577	            depthBuffer: true
44578	        });
44579	        const cubeCamera = new CubeCamera(0.1, 100, cubeTarget);
44580	        const generatedEnvironmentMap = cubeCamera.renderTarget.texture;
44581	        generatedEnvironmentMap.name = name;
44582	        const outputColorSpace = renderer.outputColorSpace;
44583	        const toneMapping = renderer.toneMapping;
44584	        renderer.toneMapping = NoToneMapping;
44585	        renderer.outputColorSpace = LinearSRGBColorSpace;
44586	        cubeCamera.update(renderer, scene);
44587	        this.blurCubemap(cubeTarget, GENERATED_SIGMA);
44588	        renderer.toneMapping = toneMapping;
44589	        renderer.outputColorSpace = outputColorSpace;
44590	        return generatedEnvironmentMap;
44591	    }
44592	 async loadGeneratedEnvironmentMap() {
44593	        if (this.generatedEnvironmentMap == null) {
44594	            this.generatedEnvironmentMap = this.GenerateEnvironmentMap(new EnvironmentScene('legacy'), 'legacy');
44595	        }
44596	        return this.generatedEnvironmentMap;
44597	    }
44598	 async loadGeneratedEnvironmentMapAlt() {
44599	        if (this.generatedEnvironmentMapAlt == null) {
44600	            this.generatedEnvironmentMapAlt = this.GenerateEnvironmentMap(new EnvironmentScene('neutral'), 'neutral');
44601	        }
44602	        return this.generatedEnvironmentMapAlt;
44603	    }
44604	    blurCubemap(cubeTarget, sigma) {
44605	        if (this.blurMaterial == null) {
44606	            this.blurMaterial = this.getBlurShader(MAX_SAMPLES);
44607	            const box = new BoxGeometry();
44608	            const blurMesh = new Mesh(box, this.blurMaterial);
44609	            this.blurScene = new Scene();
44610	            this.blurScene.add(blurMesh);
44611	        }
44612	        const tempTarget = cubeTarget.clone();
44613	        this.halfblur(cubeTarget, tempTarget, sigma, 'latitudinal');
44614	        this.halfblur(tempTarget, cubeTarget, sigma, 'longitudinal');
44615	     }
44616	    halfblur(targetIn, targetOut, sigmaRadians, direction) {
44617	        const STANDARD_DEVIATIONS = 3;
44618	        const pixels = targetIn.width;
vendor: 53,934 bytes, lines 44619-46114
44619	        const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1);
44620	        const sigmaPixels = sigmaRadians / radiansPerPixel;
44621	        const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES;
44622	        if (samples > MAX_SAMPLES) {
44623	            console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`);
44624	        }
44625	        const weights = [];
44626	        let sum = 0;
44627	        for(let i = 0; i < MAX_SAMPLES; ++i){
44628	            const x = i / sigmaPixels;
44629	            const weight = Math.exp(-x * x / 2);
44630	            weights.push(weight);
44631	            if (i == 0) {
44632	                sum += weight;
44633	            } else if (i < samples) {
44634	                sum += 2 * weight;
44635	            }
44636	        }
44637	        for(let i = 0; i < weights.length; i++){
44638	            weights[i] = weights[i] / sum;
44639	        }
44640	        const blurUniforms = this.blurMaterial.uniforms;
44641	        blurUniforms['envMap'].value = targetIn.texture;
44642	        blurUniforms['samples'].value = samples;
44643	        blurUniforms['weights'].value = weights;
44644	        blurUniforms['latitudinal'].value = direction === 'latitudinal';
44645	        blurUniforms['dTheta'].value = radiansPerPixel;
44646	        const cubeCamera = new CubeCamera(0.1, 100, targetOut);
44647	        cubeCamera.update(this.threeRenderer, this.blurScene);
44648	    }
44649	    getBlurShader(maxSamples) {
44650	        const weights = new Float32Array(maxSamples);
44651	        const poleAxis = new Vector3(0, 1, 0);
44652	        const shaderMaterial = new ShaderMaterial({
44653	            name: 'SphericalGaussianBlur',
44654	            defines: {
44655	                'n': maxSamples
44656	            },
44657	            uniforms: {
44658	                'envMap': {
44659	                    value: null
44660	                },
44661	                'samples': {
44662	                    value: 1
44663	                },
44664	                'weights': {
44665	                    value: weights
44666	                },
44667	                'latitudinal': {
44668	                    value: false
44669	                },
44670	                'dTheta': {
44671	                    value: 0
44672	                },
44673	                'poleAxis': {
44674	                    value: poleAxis
44675	                }
44676	            },
44677	            vertexShader:  `
44678      
44679      varying vec3 vOutputDirection;
44680  
44681      void main() {
44682  
44683        vOutputDirection = vec3( position );
44684        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
44685  
44686      }
44687    `,
44688	            fragmentShader:  `
44689        varying vec3 vOutputDirection;
44690  
44691        uniform samplerCube envMap;
44692        uniform int samples;
44693        uniform float weights[ n ];
44694        uniform bool latitudinal;
44695        uniform float dTheta;
44696        uniform vec3 poleAxis;
44697  
44698        vec3 getSample( float theta, vec3 axis ) {
44699  
44700          float cosTheta = cos( theta );
44701          // Rodrigues' axis-angle rotation
44702          vec3 sampleDirection = vOutputDirection * cosTheta
44703            + cross( axis, vOutputDirection ) * sin( theta )
44704            + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
44705  
44706          return vec3( textureCube( envMap, sampleDirection ) );
44707  
44708        }
44709  
44710        void main() {
44711  
44712          vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
44713  
44714          if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
44715  
44716            axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
44717  
44718          }
44719  
44720          axis = normalize( axis );
44721  
44722          gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
44723          gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
44724  
44725          for ( int i = 1; i < n; i++ ) {
44726  
44727            if ( i >= samples ) {
44728  
44729              break;
44730  
44731            }
44732  
44733            float theta = dTheta * float( i );
44734            gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
44735            gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
44736  
44737          }
44738        }
44739      `,
44740	            blending: NoBlending,
44741	            depthTest: false,
44742	            depthWrite: false,
44743	            side: BackSide
44744	        });
44745	        return shaderMaterial;
44746	    }
44747	    async dispose() {
44748	        for (const [, promise] of this.skyboxCache){
44749	            const skybox = await promise;
44750	            skybox.dispose();
44751	        }
44752	        if (this.generatedEnvironmentMap != null) {
44753	            (await this.generatedEnvironmentMap).dispose();
44754	            this.generatedEnvironmentMap = null;
44755	        }
44756	        if (this.generatedEnvironmentMapAlt != null) {
44757	            (await this.generatedEnvironmentMapAlt).dispose();
44758	            this.generatedEnvironmentMapAlt = null;
44759	        }
44760	        if (this.blurMaterial != null) {
44761	            this.blurMaterial.dispose();
44762	        }
44763	    }
44764	    constructor(threeRenderer){
44765	        this.threeRenderer = threeRenderer;
44766	        this.lottieLoaderUrl = '';
44767	        this._ldrLoader = null;
44768	        this._imageLoader = null;
44769	        this._hdrLoader = null;
44770	        this._lottieLoader = null;
44771	        this.generatedEnvironmentMap = null;
44772	        this.generatedEnvironmentMapAlt = null;
44773	        this.skyboxCache = new Map();
44774	        this.blurMaterial = null;
44775	        this.blurScene = null;
44776	    }
44777	}
44778
44779	const DURATION_DECAY = 0.2;
44780	const LOW_FRAME_DURATION_MS = 40;
44781	const HIGH_FRAME_DURATION_MS = 60;
44782	const MAX_AVG_CHANGE_MS = 5;
44783	const SCALE_STEPS = [
44784	    1,
44785	    0.79,
44786	    0.62,
44787	    0.5,
44788	    0.4,
44789	    0.31,
44790	    0.25
44791	];
44792	const DEFAULT_LAST_STEP = 3;
44793	const DEFAULT_POWER_PREFERENCE = 'high-performance';
44794	const COMMERCE_EXPOSURE = 1.3;
44795	 class Renderer extends EventDispatcher {
44796	    static get singleton() {
44797	        if (!this._singleton) {
44798	            this._singleton = new Renderer({
44799	                powerPreference: (self.ModelViewerElement || {}).powerPreference || DEFAULT_POWER_PREFERENCE,
44800	                debug: isDebugMode()
44801	            });
44802	        }
44803	        return this._singleton;
44804	    }
44805	    static resetSingleton() {
44806	        const elements = this._singleton.dispose();
44807	        for (const element of elements){
44808	            element.disconnectedCallback();
44809	        }
44810	        this._singleton = new Renderer({
44811	            powerPreference: (self.ModelViewerElement || {}).powerPreference || DEFAULT_POWER_PREFERENCE,
44812	            debug: isDebugMode()
44813	        });
44814	        for (const element of elements){
44815	            element.connectedCallback();
44816	        }
44817	    }
44818	    get canRender() {
44819	        return this.threeRenderer != null;
44820	    }
44821	    get scaleFactor() {
44822	        return SCALE_STEPS[this.scaleStep];
44823	    }
44824	    set minScale(scale) {
44825	        let i = 1;
44826	        while(i < SCALE_STEPS.length){
44827	            if (SCALE_STEPS[i] < scale) {
44828	                break;
44829	            }
44830	            ++i;
44831	        }
44832	        this.lastStep = i - 1;
44833	    }
44834	    registerScene(scene) {
44835	        this.scenes.add(scene);
44836	        scene.forceRescale();
44837	        const size = new Vector2();
44838	        this.threeRenderer.getSize(size);
44839	        scene.canvas.width = size.x;
44840	        scene.canvas.height = size.y;
44841	        if (this.canRender && this.scenes.size > 0) {
44842	            this.threeRenderer.setAnimationLoop((time, frame)=>this.render(time, frame));
44843	        }
44844	    }
44845	    unregisterScene(scene) {
44846	        this.scenes.delete(scene);
44847	        if (this.canvas3D.parentElement === scene.canvas.parentElement) {
44848	            scene.canvas.parentElement.removeChild(this.canvas3D);
44849	        }
44850	        if (this.canRender && this.scenes.size === 0) {
44851	            this.threeRenderer.setAnimationLoop(null);
44852	        }
44853	    }
44854	    displayCanvas(scene) {
44855	        return scene.element.modelIsVisible && !this.multipleScenesVisible ? this.canvas3D : scene.element[$canvas];
44856	    }
44857	 countVisibleScenes() {
44858	        const { canvas3D } = this;
44859	        let visibleScenes = 0;
44860	        let canvas3DScene = null;
44861	        for (const scene of this.scenes){
44862	            const { element } = scene;
44863	            if (element.modelIsVisible && scene.externalRenderer == null) {
44864	                ++visibleScenes;
44865	            }
44866	            if (canvas3D.parentElement === scene.canvas.parentElement) {
44867	                canvas3DScene = scene;
44868	            }
44869	        }
44870	        const multipleScenesVisible = visibleScenes > 1;
44871	        if (canvas3DScene != null) {
44872	            const newlyMultiple = multipleScenesVisible && !this.multipleScenesVisible;
44873	            const disappearing = !canvas3DScene.element.modelIsVisible;
44874	            if (newlyMultiple || disappearing) {
44875	                const { width, height } = this.sceneSize(canvas3DScene);
44876	                this.copyPixels(canvas3DScene, width, height);
44877	                canvas3D.parentElement.removeChild(canvas3D);
44878	            }
44879	        }
44880	        this.multipleScenesVisible = multipleScenesVisible;
44881	    }
44882	 updateRendererSize() {
44883	        var _a;
44884	        const dpr = window.devicePixelRatio;
44885	        if (dpr !== this.dpr) {
44886	            for (const scene of this.scenes){
44887	                const { element } = scene;
44888	                element[$updateSize](element.getBoundingClientRect());
44889	            }
44890	        }
44891	        let width = 0;
44892	        let height = 0;
44893	        for (const scene of this.scenes){
44894	            width = Math.max(width, scene.width);
44895	            height = Math.max(height, scene.height);
44896	        }
44897	        if (width === this.width && height === this.height && dpr === this.dpr) {
44898	            return;
44899	        }
44900	        this.width = width;
44901	        this.height = height;
44902	        this.dpr = dpr;
44903	        width = Math.ceil(width * dpr);
44904	        height = Math.ceil(height * dpr);
44905	        if (this.canRender) {
44906	            this.threeRenderer.setSize(width, height, false);
44907	        }
44908	        for (const scene of this.scenes){
44909	            const { canvas } = scene;
44910	            canvas.width = width;
44911	            canvas.height = height;
44912	            scene.forceRescale();
44913	            (_a = scene.effectRenderer) === null || _a === void 0 ? void 0 : _a.setSize(width, height);
44914	        }
44915	    }
44916	    updateRendererScale(delta) {
44917	        const scaleStep = this.scaleStep;
44918	        this.avgFrameDuration += clamp(DURATION_DECAY * (delta - this.avgFrameDuration), -5, MAX_AVG_CHANGE_MS);
44919	        if (this.avgFrameDuration > HIGH_FRAME_DURATION_MS) {
44920	            ++this.scaleStep;
44921	        } else if (this.avgFrameDuration < LOW_FRAME_DURATION_MS && this.scaleStep > 0) {
44922	            --this.scaleStep;
44923	        }
44924	        this.scaleStep = Math.min(this.scaleStep, this.lastStep);
44925	        if (scaleStep !== this.scaleStep) {
44926	            this.avgFrameDuration = (HIGH_FRAME_DURATION_MS + LOW_FRAME_DURATION_MS) / 2;
44927	        }
44928	    }
44929	    shouldRender(scene) {
44930	        if (!scene.shouldRender()) {
44931	            if (scene.scaleStep != 0) {
44932	                scene.scaleStep = 0;
44933	                this.rescaleCanvas(scene);
44934	            } else {
44935	                return false;
44936	            }
44937	        } else if (scene.scaleStep != this.scaleStep) {
44938	            scene.scaleStep = this.scaleStep;
44939	            this.rescaleCanvas(scene);
44940	        }
44941	        return true;
44942	    }
44943	    rescaleCanvas(scene) {
44944	        const scale = SCALE_STEPS[scene.scaleStep];
44945	        const width = Math.ceil(this.width / scale);
44946	        const height = Math.ceil(this.height / scale);
44947	        const { style } = scene.canvas;
44948	        style.width = `${width}px`;
44949	        style.height = `${height}px`;
44950	        this.canvas3D.style.width = `${width}px`;
44951	        this.canvas3D.style.height = `${height}px`;
44952	        const renderedDpr = this.dpr * scale;
44953	        const reason = scale < 1 ? 'GPU throttling' : this.dpr !== window.devicePixelRatio ? 'No meta viewport tag' : '';
44954	        scene.element.dispatchEvent(new CustomEvent('render-scale', {
44955	            detail: {
44956	                reportedDpr: window.devicePixelRatio,
44957	                renderedDpr: renderedDpr,
44958	                minimumDpr: this.dpr * SCALE_STEPS[this.lastStep],
44959	                pixelWidth: Math.ceil(scene.width * renderedDpr),
44960	                pixelHeight: Math.ceil(scene.height * renderedDpr),
44961	                reason: reason
44962	            }
44963	        }));
44964	    }
44965	    sceneSize(scene) {
44966	        const { dpr } = this;
44967	        const scaleFactor = SCALE_STEPS[scene.scaleStep];
44968	        const width = Math.min(Math.ceil(scene.width * scaleFactor * dpr), this.canvas3D.width);
44969	        const height = Math.min(Math.ceil(scene.height * scaleFactor * dpr), this.canvas3D.height);
44970	        return {
44971	            width,
44972	            height
44973	        };
44974	    }
44975	    copyPixels(scene, width, height) {
44976	        const context2D = scene.context;
44977	        if (context2D == null) {
44978	            console.log('could not acquire 2d context');
44979	            return;
44980	        }
44981	        context2D.clearRect(0, 0, width, height);
44982	        context2D.drawImage(this.canvas3D, 0, 0, width, height, 0, 0, width, height);
44983	        scene.canvas.classList.add('show');
44984	    }
44985	 orderedScenes() {
44986	        const scenes = [];
44987	        for (const visible of [
44988	            false,
44989	            true
44990	        ]){
44991	            for (const scene of this.scenes){
44992	                if (scene.element.modelIsVisible === visible) {
44993	                    scenes.push(scene);
44994	                }
44995	            }
44996	        }
44997	        return scenes;
44998	    }
44999	    get isPresenting() {
45000	        return this.arRenderer.isPresenting;
45001	    }
45002	 preRender(scene, t, delta) {
45003	        const { element, exposure, toneMapping } = scene;
45004	        element[$tick](t, delta);
45005	        const exposureIsNumber = typeof exposure === 'number' && !Number.isNaN(exposure);
45006	        const env = element.environmentImage;
45007	        const sky = element.skyboxImage;
45008	        const compensateExposure = toneMapping === NeutralToneMapping && (env === 'neutral' || env === 'legacy' || !env && !sky);
45009	        this.threeRenderer.toneMappingExposure = (exposureIsNumber ? exposure : 1.0) * (compensateExposure ? COMMERCE_EXPOSURE : 1.0);
45010	    }
45011	    render(t, frame) {
45012	        if (frame != null) {
45013	            this.arRenderer.onWebXRFrame(t, frame);
45014	            return;
45015	        }
45016	        const delta = t - this.lastTick;
45017	        this.lastTick = t;
45018	        if (!this.canRender || this.isPresenting) {
45019	            return;
45020	        }
45021	        this.countVisibleScenes();
45022	        this.updateRendererSize();
45023	        if (this.renderedLastFrame) {
45024	            this.updateRendererScale(delta);
45025	            this.renderedLastFrame = false;
45026	        }
45027	        const { canvas3D } = this;
45028	        for (const scene of this.orderedScenes()){
45029	            const { element } = scene;
45030	            if (!element.loaded || !element.modelIsVisible && scene.renderCount > 0) {
45031	                continue;
45032	            }
45033	            this.preRender(scene, t, delta);
45034	            if (!this.shouldRender(scene)) {
45035	                continue;
45036	            }
45037	            if (scene.externalRenderer != null) {
45038	                const camera = scene.getCamera();
45039	                camera.updateMatrix();
45040	                const { matrix, projectionMatrix } = camera;
45041	                const viewMatrix = matrix.elements.slice();
45042	                const target = scene.getTarget();
45043	                viewMatrix[12] += target.x;
45044	                viewMatrix[13] += target.y;
45045	                viewMatrix[14] += target.z;
45046	                scene.externalRenderer.render({
45047	                    viewMatrix: viewMatrix,
45048	                    projectionMatrix: projectionMatrix.elements
45049	                });
45050	                continue;
45051	            }
45052	            if (!element.modelIsVisible && !this.multipleScenesVisible) {
45053	                for (const visibleScene of this.scenes){
45054	                    if (visibleScene.element.modelIsVisible) {
45055	                        visibleScene.queueRender();
45056	                    }
45057	                }
45058	            }
45059	            const { width, height } = this.sceneSize(scene);
45060	            scene.renderShadow(this.threeRenderer);
45061	            this.threeRenderer.setRenderTarget(null);
45062	            this.threeRenderer.setViewport(0, Math.ceil(this.height * this.dpr) - height, width, height);
45063	            if (scene.effectRenderer != null) {
45064	                scene.effectRenderer.render(delta);
45065	            } else {
45066	                this.threeRenderer.autoClear = true;
45067	                this.threeRenderer.toneMapping = scene.toneMapping;
45068	                this.threeRenderer.render(scene, scene.camera);
45069	            }
45070	            if (this.multipleScenesVisible || !scene.element.modelIsVisible && scene.renderCount === 0) {
45071	                this.copyPixels(scene, width, height);
45072	            } else if (canvas3D.parentElement !== scene.canvas.parentElement) {
45073	                scene.canvas.parentElement.appendChild(canvas3D);
45074	                scene.canvas.classList.remove('show');
45075	            }
45076	            scene.hasRendered();
45077	            ++scene.renderCount;
45078	            this.renderedLastFrame = true;
45079	        }
45080	    }
45081	    dispose() {
45082	        if (this.textureUtils != null) {
45083	            this.textureUtils.dispose();
45084	        }
45085	        if (this.threeRenderer != null) {
45086	            this.threeRenderer.dispose();
45087	        }
45088	        this.textureUtils = null;
45089	        this.threeRenderer = null;
45090	        const elements = [];
45091	        for (const scene of this.scenes){
45092	            elements.push(scene.element);
45093	        }
45094	        this.canvas3D.removeEventListener('webglcontextlost', this.onWebGLContextLost);
45095	        this.canvas3D.removeEventListener('webglcontextrestored', this.onWebGLContextRestored);
45096	        return elements;
45097	    }
45098	    constructor(options){
45099	        super();
45100	        this.loader = new CachingGLTFLoader(ModelViewerGLTFInstance);
45101	        this.width = 0;
45102	        this.height = 0;
45103	        this.dpr = 1;
45104	        this.scenes = new Set();
45105	        this.multipleScenesVisible = false;
45106	        this.lastTick = performance.now();
45107	        this.renderedLastFrame = false;
45108	        this.scaleStep = 0;
45109	        this.lastStep = DEFAULT_LAST_STEP;
45110	        this.avgFrameDuration = (HIGH_FRAME_DURATION_MS + LOW_FRAME_DURATION_MS) / 2;
45111	        this.onWebGLContextLost = (event)=>{
45112	            this.dispatchEvent({
45113	                type: 'contextlost',
45114	                sourceEvent: event
45115	            });
45116	        };
45117	        this.onWebGLContextRestored = ()=>{
45118	            var _a;
45119	            (_a = this.textureUtils) === null || _a === void 0 ? void 0 : _a.dispose();
45120	            this.textureUtils = new TextureUtils(this.threeRenderer);
45121	            for (const scene of this.scenes){
45122	                scene.element[$updateEnvironment]();
45123	            }
45124	        };
45125	        this.dpr = window.devicePixelRatio;
45126	        this.canvas3D = document.createElement('canvas');
45127	        this.canvas3D.id = 'webgl-canvas';
45128	        this.canvas3D.classList.add('show');
45129	        try {
45130	            this.threeRenderer = new WebGLRenderer({
45131	                canvas: this.canvas3D,
45132	                alpha: true,
45133	                antialias: true,
45134	                powerPreference: options.powerPreference,
45135	                preserveDrawingBuffer: true
45136	            });
45137	            this.threeRenderer.autoClear = true;
45138	            this.threeRenderer.setPixelRatio(1);
45139	            this.threeRenderer.debug = {
45140	                checkShaderErrors: !!options.debug,
45141	                onShaderError: null
45142	            };
45143	            this.threeRenderer.toneMapping = NeutralToneMapping;
45144	        } catch (error) {
45145	            console.warn(error);
45146	        }
45147	        this.arRenderer = new ARRenderer(this);
45148	        this.textureUtils = this.canRender ? new TextureUtils(this.threeRenderer) : null;
45149	        CachingGLTFLoader.initializeKTX2Loader(this.threeRenderer);
45150	        this.canvas3D.addEventListener('webglcontextlost', this.onWebGLContextLost);
45151	        this.canvas3D.addEventListener('webglcontextrestored', this.onWebGLContextRestored);
45152	        this.updateRendererSize();
45153	    }
45154	}
45155
45156	const $correlatedObjects = Symbol('correlatedObjects');
45157	const $onUpdate$1 = Symbol('onUpdate');
45158	 class ThreeDOMElement {
45159	    constructor(onUpdate, correlatedObjects){
45160	        this[$onUpdate$1] = onUpdate;
45161	        this[$correlatedObjects] = correlatedObjects;
45162	    }
45163	}
45164
45165	const quadMaterial = new MeshBasicMaterial();
45166	const quad = new PlaneGeometry(2, 2);
45167	let adhocNum = 0;
45168	const $threeTexture$2 = Symbol('threeTexture');
45169	const $threeTextures$1 = Symbol('threeTextures');
45170	 let Image$1 = class Image extends ThreeDOMElement {
45171	    get [$threeTexture$2]() {
45172	        var _a;
45173	        return (_a = this[$correlatedObjects]) === null || _a === void 0 ? void 0 : _a.values().next().value;
45174	    }
45175	    get [$threeTextures$1]() {
45176	        return this[$correlatedObjects];
45177	    }
45178	    get name() {
45179	        return this[$threeTexture$2].image.name || '';
45180	    }
45181	    get uri() {
45182	        return this[$threeTexture$2].image.src;
45183	    }
45184	    get bufferView() {
45185	        return this[$threeTexture$2].image.bufferView;
45186	    }
45187	    get element() {
45188	        const texture = this[$threeTexture$2];
45189	        if (texture && (texture.isCanvasTexture || texture.isVideoTexture)) {
45190	            return texture.image;
45191	        }
45192	        return;
45193	    }
45194	    get animation() {
45195	        const texture = this[$threeTexture$2];
45196	        if (texture && texture.isCanvasTexture && texture.animation) {
45197	            return texture.animation;
45198	        }
45199	        return;
45200	    }
45201	    get type() {
45202	        return this.uri != null ? 'external' : 'embedded';
45203	    }
45204	    set name(name) {
45205	        for (const texture of this[$threeTextures$1]){
45206	            texture.image.name = name;
45207	        }
45208	    }
45209	    update() {
45210	        const texture = this[$threeTexture$2];
45211	        if (texture && texture.isCanvasTexture && !texture.animation) {
45212	            this[$threeTexture$2].needsUpdate = true;
45213	            this[$onUpdate$1]();
45214	        }
45215	    }
45216	    async createThumbnail(width, height) {
45217	        const scene = new Scene();
45218	        quadMaterial.map = this[$threeTexture$2];
45219	        const mesh = new Mesh(quad, quadMaterial);
45220	        scene.add(mesh);
45221	        const camera = new OrthographicCamera(-1, 1, 1, -1, 0, 1);
45222	        const { threeRenderer } = Renderer.singleton;
45223	        const renderTarget = new WebGLRenderTarget(width, height);
45224	        threeRenderer.setRenderTarget(renderTarget);
45225	        threeRenderer.render(scene, camera);
45226	        threeRenderer.setRenderTarget(null);
45227	        const buffer = new Uint8Array(width * height * 4);
45228	        threeRenderer.readRenderTargetPixels(renderTarget, 0, 0, width, height, buffer);
45229	        blobCanvas.width = width;
45230	        blobCanvas.height = height;
45231	        const blobContext = blobCanvas.getContext('2d');
45232	        const imageData = blobContext.createImageData(width, height);
45233	        imageData.data.set(buffer);
45234	        blobContext.putImageData(imageData, 0, 0);
45235	        return new Promise(async (resolve, reject)=>{
45236	            blobCanvas.toBlob((blob)=>{
45237	                if (!blob) {
45238	                    return reject('Failed to capture thumbnail.');
45239	                }
45240	                resolve(URL.createObjectURL(blob));
45241	            }, 'image/png');
45242	        });
45243	    }
45244	    constructor(onUpdate, texture){
45245	        super(onUpdate, new Set(texture ? [
45246	            texture
45247	        ] : []));
45248	        if (!this[$threeTexture$2].image.src) {
45249	            this[$threeTexture$2].image.src = texture.name ? texture.name : 'adhoc_image' + adhocNum++;
45250	        }
45251	        if (!this[$threeTexture$2].image.name) {
45252	            this[$threeTexture$2].image.name = texture && texture.image && texture.image.src ? texture.image.src.split('/').pop() : 'adhoc_image';
45253	        }
45254	    }
45255	};
45256
45257	var Filter;
45258	(function(Filter) {
45259	    Filter[Filter["Nearest"] = 9728] = "Nearest";
45260	    Filter[Filter["Linear"] = 9729] = "Linear";
45261	    Filter[Filter["NearestMipmapNearest"] = 9984] = "NearestMipmapNearest";
45262	    Filter[Filter["LinearMipmapNearest"] = 9985] = "LinearMipmapNearest";
45263	    Filter[Filter["NearestMipmapLinear"] = 9986] = "NearestMipmapLinear";
45264	    Filter[Filter["LinearMipmapLinear"] = 9987] = "LinearMipmapLinear";
45265	})(Filter || (Filter = {}));
45266	var Wrap;
45267	(function(Wrap) {
45268	    Wrap[Wrap["ClampToEdge"] = 33071] = "ClampToEdge";
45269	    Wrap[Wrap["MirroredRepeat"] = 33648] = "MirroredRepeat";
45270	    Wrap[Wrap["Repeat"] = 10497] = "Repeat";
45271	})(Wrap || (Wrap = {}));
45272
45273	const wrapModeToWrapping = new Map([
45274	    [
45275	        Wrap.Repeat,
45276	        RepeatWrapping
45277	    ],
45278	    [
45279	        Wrap.ClampToEdge,
45280	        ClampToEdgeWrapping
45281	    ],
45282	    [
45283	        Wrap.MirroredRepeat,
45284	        MirroredRepeatWrapping
45285	    ]
45286	]);
45287	const wrappingToWrapMode = new Map([
45288	    [
45289	        RepeatWrapping,
45290	        Wrap.Repeat
45291	    ],
45292	    [
45293	        ClampToEdgeWrapping,
45294	        Wrap.ClampToEdge
45295	    ],
45296	    [
45297	        MirroredRepeatWrapping,
45298	        Wrap.MirroredRepeat
45299	    ]
45300	]);
45301	const minFilterToMinification = new Map([
45302	    [
45303	        Filter.Nearest,
45304	        NearestFilter
45305	    ],
45306	    [
45307	        Filter.Linear,
45308	        LinearFilter
45309	    ],
45310	    [
45311	        Filter.NearestMipmapNearest,
45312	        NearestMipmapNearestFilter
45313	    ],
45314	    [
45315	        Filter.LinearMipmapNearest,
45316	        LinearMipmapNearestFilter
45317	    ],
45318	    [
45319	        Filter.NearestMipmapLinear,
45320	        NearestMipmapLinearFilter
45321	    ],
45322	    [
45323	        Filter.LinearMipmapLinear,
45324	        LinearMipmapLinearFilter
45325	    ]
45326	]);
45327	const minificationToMinFilter = new Map([
45328	    [
45329	        NearestFilter,
45330	        Filter.Nearest
45331	    ],
45332	    [
45333	        LinearFilter,
45334	        Filter.Linear
45335	    ],
45336	    [
45337	        NearestMipmapNearestFilter,
45338	        Filter.NearestMipmapNearest
45339	    ],
45340	    [
45341	        LinearMipmapNearestFilter,
45342	        Filter.LinearMipmapNearest
45343	    ],
45344	    [
45345	        NearestMipmapLinearFilter,
45346	        Filter.NearestMipmapLinear
45347	    ],
45348	    [
45349	        LinearMipmapLinearFilter,
45350	        Filter.LinearMipmapLinear
45351	    ]
45352	]);
45353	const magFilterToMagnification = new Map([
45354	    [
45355	        Filter.Nearest,
45356	        NearestFilter
45357	    ],
45358	    [
45359	        Filter.Linear,
45360	        LinearFilter
45361	    ]
45362	]);
45363	const magnificationToMagFilter = new Map([
45364	    [
45365	        NearestFilter,
45366	        Filter.Nearest
45367	    ],
45368	    [
45369	        LinearFilter,
45370	        Filter.Linear
45371	    ]
45372	]);
45373	const isMinFilter = (()=>{
45374	    return (value)=>minificationToMinFilter.has(value);
45375	})();
45376	const isMagFilter = (()=>{
45377	    return (value)=>magnificationToMagFilter.has(value);
45378	})();
45379	const isWrapping = (()=>{
45380	    return (value)=>wrappingToWrapMode.has(value);
45381	})();
45382	const isValidSamplerValue = (property, value)=>{
45383	    switch(property){
45384	        case 'minFilter':
45385	            return isMinFilter(value);
45386	        case 'magFilter':
45387	            return isMagFilter(value);
45388	        case 'wrapS':
45389	        case 'wrapT':
45390	            return isWrapping(value);
45391	        case 'rotation':
45392	        case 'repeat':
45393	        case 'offset':
45394	            return true;
45395	        default:
45396	            throw new Error(`Cannot configure property "${property}" on Sampler`);
45397	    }
45398	};
45399	const $threeTexture$1 = Symbol('threeTexture');
45400	const $threeTextures = Symbol('threeTextures');
45401	const $setProperty = Symbol('setProperty');
45402	 class Sampler extends ThreeDOMElement {
45403	    get [$threeTexture$1]() {
45404	        var _a;
45405	        return (_a = this[$correlatedObjects]) === null || _a === void 0 ? void 0 : _a.values().next().value;
45406	    }
45407	    get [$threeTextures]() {
45408	        return this[$correlatedObjects];
45409	    }
45410	    get name() {
45411	        return this[$threeTexture$1].name || '';
45412	    }
45413	    get minFilter() {
45414	        return minificationToMinFilter.get(this[$threeTexture$1].minFilter);
45415	    }
45416	    get magFilter() {
45417	        return magnificationToMagFilter.get(this[$threeTexture$1].magFilter);
45418	    }
45419	    get wrapS() {
45420	        return wrappingToWrapMode.get(this[$threeTexture$1].wrapS);
45421	    }
45422	    get wrapT() {
45423	        return wrappingToWrapMode.get(this[$threeTexture$1].wrapT);
45424	    }
45425	    get rotation() {
45426	        return this[$threeTexture$1].rotation;
45427	    }
45428	    get scale() {
45429	        return toVector2D(this[$threeTexture$1].repeat);
45430	    }
45431	    get offset() {
45432	        return toVector2D(this[$threeTexture$1].offset);
45433	    }
45434	    setMinFilter(filter) {
45435	        this[$setProperty]('minFilter', minFilterToMinification.get(filter));
45436	    }
45437	    setMagFilter(filter) {
45438	        this[$setProperty]('magFilter', magFilterToMagnification.get(filter));
45439	    }
45440	    setWrapS(mode) {
45441	        this[$setProperty]('wrapS', wrapModeToWrapping.get(mode));
45442	    }
45443	    setWrapT(mode) {
45444	        this[$setProperty]('wrapT', wrapModeToWrapping.get(mode));
45445	    }
45446	    setRotation(rotation) {
45447	        if (rotation == null) {
45448	            rotation = 0;
45449	        }
45450	        this[$setProperty]('rotation', rotation);
45451	    }
45452	    setScale(scale) {
45453	        if (scale == null) {
45454	            scale = {
45455	                u: 1,
45456	                v: 1
45457	            };
45458	        }
45459	        this[$setProperty]('repeat', new Vector2(scale.u, scale.v));
45460	    }
45461	    setOffset(offset) {
45462	        if (offset == null) {
45463	            offset = {
45464	                u: 0,
45465	                v: 0
45466	            };
45467	        }
45468	        this[$setProperty]('offset', new Vector2(offset.u, offset.v));
45469	    }
45470	    [$setProperty](property, value) {
45471	        if (isValidSamplerValue(property, value)) {
45472	            for (const texture of this[$threeTextures]){
45473	                texture[property] = value;
45474	                texture.needsUpdate = true;
45475	            }
45476	        }
45477	        this[$onUpdate$1]();
45478	    }
45479	    constructor(onUpdate, texture){
45480	        super(onUpdate, new Set(texture ? [
45481	            texture
45482	        ] : []));
45483	    }
45484	}
45485
45486	const $image = Symbol('image');
45487	const $sampler = Symbol('sampler');
45488	const $threeTexture = Symbol('threeTexture');
45489	 class Texture extends ThreeDOMElement {
45490	    get [$threeTexture]() {
45491	        var _a;
45492	        return (_a = this[$correlatedObjects]) === null || _a === void 0 ? void 0 : _a.values().next().value;
45493	    }
45494	    get name() {
45495	        return this[$threeTexture].name || '';
45496	    }
45497	    set name(name) {
45498	        for (const texture of this[$correlatedObjects]){
45499	            texture.name = name;
45500	        }
45501	    }
45502	    get sampler() {
45503	        return this[$sampler];
45504	    }
45505	    get source() {
45506	        return this[$image];
45507	    }
45508	    constructor(onUpdate, threeTexture){
45509	        super(onUpdate, new Set(threeTexture ? [
45510	            threeTexture
45511	        ] : []));
45512	        this[$sampler] = new Sampler(onUpdate, threeTexture);
45513	        this[$image] = new Image$1(onUpdate, threeTexture);
45514	    }
45515	}
45516
45517	var _a$4, _b$4, _c$2;
45518	const $texture = Symbol('texture');
45519	const $transform = Symbol('transform');
45520	const $materials$1 = Symbol('materials');
45521	const $usage = Symbol('usage');
45522	const $onUpdate = Symbol('onUpdate');
45523	const $activeVideo = Symbol('activeVideo');
45524	var TextureUsage;
45525	(function(TextureUsage) {
45526	    TextureUsage[TextureUsage["Base"] = 0] = "Base";
45527	    TextureUsage[TextureUsage["MetallicRoughness"] = 1] = "MetallicRoughness";
45528	    TextureUsage[TextureUsage["Normal"] = 2] = "Normal";
45529	    TextureUsage[TextureUsage["Occlusion"] = 3] = "Occlusion";
45530	    TextureUsage[TextureUsage["Emissive"] = 4] = "Emissive";
45531	    TextureUsage[TextureUsage["Clearcoat"] = 5] = "Clearcoat";
45532	    TextureUsage[TextureUsage["ClearcoatRoughness"] = 6] = "ClearcoatRoughness";
45533	    TextureUsage[TextureUsage["ClearcoatNormal"] = 7] = "ClearcoatNormal";
45534	    TextureUsage[TextureUsage["SheenColor"] = 8] = "SheenColor";
45535	    TextureUsage[TextureUsage["SheenRoughness"] = 9] = "SheenRoughness";
45536	    TextureUsage[TextureUsage["Transmission"] = 10] = "Transmission";
45537	    TextureUsage[TextureUsage["Thickness"] = 11] = "Thickness";
45538	    TextureUsage[TextureUsage["Specular"] = 12] = "Specular";
45539	    TextureUsage[TextureUsage["SpecularColor"] = 13] = "SpecularColor";
45540	    TextureUsage[TextureUsage["Iridescence"] = 14] = "Iridescence";
45541	    TextureUsage[TextureUsage["IridescenceThickness"] = 15] = "IridescenceThickness";
45542	    TextureUsage[TextureUsage["Anisotropy"] = 16] = "Anisotropy";
45543	})(TextureUsage || (TextureUsage = {}));
45544	 class TextureInfo {
45545	    get texture() {
45546	        return this[$texture];
45547	    }
45548	    setTexture(texture) {
45549	        var _d, _e;
45550	        const threeTexture = texture != null ? texture.source[$threeTexture$2] : null;
45551	        const oldTexture = (_d = this[$texture]) === null || _d === void 0 ? void 0 : _d.source[$threeTexture$2];
45552	        if (oldTexture != null && oldTexture.isVideoTexture) {
45553	            this[$activeVideo] = false;
45554	        } else if ((_e = this[$texture]) === null || _e === void 0 ? void 0 : _e.source.animation) {
45555	            this[$texture].source.animation.removeEventListener('enterFrame', this[$onUpdate]);
45556	        }
45557	        this[$texture] = texture;
45558	        if (threeTexture != null && threeTexture.isVideoTexture) {
45559	            const element = threeTexture.image;
45560	            this[$activeVideo] = true;
45561	            if (element.requestVideoFrameCallback != null) {
45562	                const update = ()=>{
45563	                    if (!this[$activeVideo]) {
45564	                        return;
45565	                    }
45566	                    this[$onUpdate]();
45567	                    element.requestVideoFrameCallback(update);
45568	                };
45569	                element.requestVideoFrameCallback(update);
45570	            } else {
45571	                const update = ()=>{
45572	                    if (!this[$activeVideo]) {
45573	                        return;
45574	                    }
45575	                    this[$onUpdate]();
45576	                    requestAnimationFrame(update);
45577	                };
45578	                requestAnimationFrame(update);
45579	            }
45580	        } else if ((texture === null || texture === void 0 ? void 0 : texture.source.animation) != null) {
45581	            texture.source.animation.addEventListener('enterFrame', this[$onUpdate]);
45582	        }
45583	        let colorSpace = SRGBColorSpace;
45584	        if (this[$materials$1]) {
45585	            for (const material of this[$materials$1]){
45586	                switch(this[$usage]){
45587	                    case TextureUsage.Base:
45588	                        material.map = threeTexture;
45589	                        break;
45590	                    case TextureUsage.MetallicRoughness:
45591	                        colorSpace = LinearSRGBColorSpace;
45592	                        material.metalnessMap = threeTexture;
45593	                        material.roughnessMap = threeTexture;
45594	                        break;
45595	                    case TextureUsage.Normal:
45596	                        colorSpace = LinearSRGBColorSpace;
45597	                        material.normalMap = threeTexture;
45598	                        break;
45599	                    case TextureUsage.Occlusion:
45600	                        colorSpace = LinearSRGBColorSpace;
45601	                        material.aoMap = threeTexture;
45602	                        break;
45603	                    case TextureUsage.Emissive:
45604	                        material.emissiveMap = threeTexture;
45605	                        break;
45606	                    case TextureUsage.Clearcoat:
45607	                        material.clearcoatMap = threeTexture;
45608	                        break;
45609	                    case TextureUsage.ClearcoatRoughness:
45610	                        material.clearcoatRoughnessMap = threeTexture;
45611	                        break;
45612	                    case TextureUsage.ClearcoatNormal:
45613	                        material.clearcoatNormalMap = threeTexture;
45614	                        break;
45615	                    case TextureUsage.SheenColor:
45616	                        material.sheenColorMap = threeTexture;
45617	                        break;
45618	                    case TextureUsage.SheenRoughness:
45619	                        material.sheenRoughnessMap = threeTexture;
45620	                        break;
45621	                    case TextureUsage.Transmission:
45622	                        material.transmissionMap = threeTexture;
45623	                        break;
45624	                    case TextureUsage.Thickness:
45625	                        material.thicknessMap = threeTexture;
45626	                        break;
45627	                    case TextureUsage.Specular:
45628	                        material.specularIntensityMap = threeTexture;
45629	                        break;
45630	                    case TextureUsage.SpecularColor:
45631	                        material.specularColorMap = threeTexture;
45632	                        break;
45633	                    case TextureUsage.Iridescence:
45634	                        material.iridescenceMap = threeTexture;
45635	                        break;
45636	                    case TextureUsage.IridescenceThickness:
45637	                        material.iridescenceThicknessMap = threeTexture;
45638	                        break;
45639	                    case TextureUsage.Anisotropy:
45640	                        material.anisotropyMap = threeTexture;
45641	                        break;
45642	                }
45643	                material.needsUpdate = true;
45644	            }
45645	        }
45646	        if (threeTexture) {
45647	            threeTexture.colorSpace = colorSpace;
45648	            threeTexture.rotation = this[$transform].rotation;
45649	            threeTexture.repeat = this[$transform].scale;
45650	            threeTexture.offset = this[$transform].offset;
45651	        }
45652	        this[$onUpdate]();
45653	    }
45654	    constructor(onUpdate, usage, threeTexture, material){
45655	        this[_a$4] = null;
45656	        this[_b$4] = {
45657	            rotation: 0,
45658	            scale: new Vector2(1, 1),
45659	            offset: new Vector2(0, 0)
45660	        };
45661	        this[_c$2] = false;
45662	        if (threeTexture) {
45663	            this[$transform].rotation = threeTexture.rotation;
45664	            this[$transform].scale.copy(threeTexture.repeat);
45665	            this[$transform].offset.copy(threeTexture.offset);
45666	            this[$texture] = new Texture(onUpdate, threeTexture);
45667	        }
45668	        this[$onUpdate] = onUpdate;
45669	        this[$materials$1] = material;
45670	        this[$usage] = usage;
45671	    }
45672	}
45673	_a$4 = $texture, _b$4 = $transform, _c$2 = $activeVideo;
45674
45675	const $threeMaterial = Symbol('threeMaterial');
45676	const $threeMaterials = Symbol('threeMaterials');
45677	const $baseColorTexture = Symbol('baseColorTexture');
45678	const $metallicRoughnessTexture = Symbol('metallicRoughnessTexture');
45679	 class PBRMetallicRoughness extends ThreeDOMElement {
45680	    get [$threeMaterials]() {
45681	        return this[$correlatedObjects];
45682	    }
45683	    get [$threeMaterial]() {
45684	        var _a;
45685	        return (_a = this[$correlatedObjects]) === null || _a === void 0 ? void 0 : _a.values().next().value;
45686	    }
45687	    get baseColorFactor() {
45688	        const rgba = [
45689	            0,
45690	            0,
45691	            0,
45692	            this[$threeMaterial].opacity
45693	        ];
45694	        this[$threeMaterial].color.toArray(rgba);
45695	        return rgba;
45696	    }
45697	    get metallicFactor() {
45698	        return this[$threeMaterial].metalness;
45699	    }
45700	    get roughnessFactor() {
45701	        return this[$threeMaterial].roughness;
45702	    }
45703	    get baseColorTexture() {
45704	        return this[$baseColorTexture];
45705	    }
45706	    get metallicRoughnessTexture() {
45707	        return this[$metallicRoughnessTexture];
45708	    }
45709	    setBaseColorFactor(rgba) {
45710	        const color = new Color();
45711	        if (rgba instanceof Array) {
45712	            color.fromArray(rgba);
45713	        } else {
45714	            color.set(rgba);
45715	        }
45716	        for (const material of this[$threeMaterials]){
45717	            material.color.set(color);
45718	            if (rgba instanceof Array && rgba.length > 3) {
45719	                material.opacity = rgba[3];
45720	            } else {
45721	                rgba = [
45722	                    0,
45723	                    0,
45724	                    0,
45725	                    material.opacity
45726	                ];
45727	                color.toArray(rgba);
45728	            }
45729	        }
45730	        this[$onUpdate$1]();
45731	    }
45732	    setMetallicFactor(value) {
45733	        for (const material of this[$threeMaterials]){
45734	            material.metalness = value;
45735	        }
45736	        this[$onUpdate$1]();
45737	    }
45738	    setRoughnessFactor(value) {
45739	        for (const material of this[$threeMaterials]){
45740	            material.roughness = value;
45741	        }
45742	        this[$onUpdate$1]();
45743	    }
45744	    constructor(onUpdate, correlatedMaterials){
45745	        super(onUpdate, correlatedMaterials);
45746	        const { map, metalnessMap } = correlatedMaterials.values().next().value;
45747	        this[$baseColorTexture] = new TextureInfo(onUpdate, TextureUsage.Base, map, correlatedMaterials);
45748	        this[$metallicRoughnessTexture] = new TextureInfo(onUpdate, TextureUsage.MetallicRoughness, metalnessMap, correlatedMaterials);
45749	    }
45750	}
45751
45752	var _a$3, _b$3;
45753	const $pbrMetallicRoughness = Symbol('pbrMetallicRoughness');
45754	const $normalTexture = Symbol('normalTexture');
45755	const $occlusionTexture = Symbol('occlusionTexture');
45756	const $emissiveTexture = Symbol('emissiveTexture');
45757	const $backingThreeMaterial = Symbol('backingThreeMaterial');
45758	const $applyAlphaCutoff = Symbol('applyAlphaCutoff');
45759	const $getAlphaMode = Symbol('getAlphaMode');
45760	const $lazyLoadGLTFInfo = Symbol('lazyLoadGLTFInfo');
45761	const $initialize = Symbol('initialize');
45762	const $getLoadedMaterial = Symbol('getLoadedMaterial');
45763	const $ensureMaterialIsLoaded = Symbol('ensureMaterialIsLoaded');
45764	const $gltfIndex = Symbol('gltfIndex');
45765	const $setActive = Symbol('setActive');
45766	const $variantIndices = Symbol('variantIndices');
45767	const $isActive = Symbol('isActive');
45768	const $modelVariants = Symbol('modelVariants');
45769	const $name = Symbol('name');
45770	const $pbrTextures = Symbol('pbrTextures');
45771	 class Material extends ThreeDOMElement {
45772	    get [(_a$3 = $variantIndices, _b$3 = $pbrTextures, $backingThreeMaterial)]() {
45773	        return this[$correlatedObjects].values().next().value;
45774	    }
45775	    [$initialize]() {
45776	        const onUpdate = this[$onUpdate$1];
45777	        const correlatedMaterials = this[$correlatedObjects];
45778	        this[$pbrMetallicRoughness] = new PBRMetallicRoughness(onUpdate, correlatedMaterials);
45779	        const { normalMap, aoMap, emissiveMap } = correlatedMaterials.values().next().value;
45780	        this[$normalTexture] = new TextureInfo(onUpdate, TextureUsage.Normal, normalMap, correlatedMaterials);
45781	        this[$occlusionTexture] = new TextureInfo(onUpdate, TextureUsage.Occlusion, aoMap, correlatedMaterials);
45782	        this[$emissiveTexture] = new TextureInfo(onUpdate, TextureUsage.Emissive, emissiveMap, correlatedMaterials);
45783	        const createTextureInfo = (usage)=>{
45784	            this[$pbrTextures].set(usage, new TextureInfo(onUpdate, usage, null, correlatedMaterials));
45785	        };
45786	        createTextureInfo(TextureUsage.Clearcoat);
45787	        createTextureInfo(TextureUsage.ClearcoatRoughness);
45788	        createTextureInfo(TextureUsage.ClearcoatNormal);
45789	        createTextureInfo(TextureUsage.SheenColor);
45790	        createTextureInfo(TextureUsage.SheenRoughness);
45791	        createTextureInfo(TextureUsage.Transmission);
45792	        createTextureInfo(TextureUsage.Thickness);
45793	        createTextureInfo(TextureUsage.Specular);
45794	        createTextureInfo(TextureUsage.SpecularColor);
45795	        createTextureInfo(TextureUsage.Iridescence);
45796	        createTextureInfo(TextureUsage.IridescenceThickness);
45797	        createTextureInfo(TextureUsage.Anisotropy);
45798	    }
45799	    async [$getLoadedMaterial]() {
45800	        if (this[$lazyLoadGLTFInfo] != null) {
45801	            const material = await this[$lazyLoadGLTFInfo].doLazyLoad();
45802	            this[$initialize]();
45803	            this[$lazyLoadGLTFInfo] = undefined;
45804	            this.ensureLoaded = async ()=>{};
45805	            return material;
45806	        }
45807	        return null;
45808	    }
45809	    colorFromRgb(rgb) {
45810	        const color = new Color();
45811	        if (rgb instanceof Array) {
45812	            color.fromArray(rgb);
45813	        } else {
45814	            color.set(rgb);
45815	        }
45816	        return color;
45817	    }
45818	    [$ensureMaterialIsLoaded]() {
45819	        if (this[$lazyLoadGLTFInfo] == null) {
45820	            return;
45821	        }
45822	        throw new Error(`Material "${this.name}" has not been loaded, call 'await
45823    myMaterial.ensureLoaded()' before using an unloaded material.`);
45824	    }
45825	    async ensureLoaded() {
45826	        await this[$getLoadedMaterial]();
45827	    }
45828	    get isLoaded() {
45829	        return this[$lazyLoadGLTFInfo] == null;
45830	    }
45831	    get isActive() {
45832	        return this[$isActive];
45833	    }
45834	    [$setActive](isActive) {
45835	        this[$isActive] = isActive;
45836	    }
45837	    get name() {
45838	        return this[$name] || '';
45839	    }
45840	    set name(name) {
45841	        this[$name] = name;
45842	        if (this[$correlatedObjects] != null) {
45843	            for (const threeMaterial of this[$correlatedObjects]){
45844	                threeMaterial.name = name;
45845	            }
45846	        }
45847	    }
45848	    get pbrMetallicRoughness() {
45849	        this[$ensureMaterialIsLoaded]();
45850	        return this[$pbrMetallicRoughness];
45851	    }
45852	    get normalTexture() {
45853	        this[$ensureMaterialIsLoaded]();
45854	        return this[$normalTexture];
45855	    }
45856	    get occlusionTexture() {
45857	        this[$ensureMaterialIsLoaded]();
45858	        return this[$occlusionTexture];
45859	    }
45860	    get emissiveTexture() {
45861	        this[$ensureMaterialIsLoaded]();
45862	        return this[$emissiveTexture];
45863	    }
45864	    get emissiveFactor() {
45865	        this[$ensureMaterialIsLoaded]();
45866	        return this[$backingThreeMaterial].emissive.toArray();
45867	    }
45868	    get index() {
45869	        return this[$gltfIndex];
45870	    }
45871	    hasVariant(name) {
45872	        const variantData = this[$modelVariants].get(name);
45873	        return variantData != null && this[$variantIndices].has(variantData.index);
45874	    }
45875	    setEmissiveFactor(rgb) {
45876	        this[$ensureMaterialIsLoaded]();
45877	        const color = this.colorFromRgb(rgb);
45878	        for (const material of this[$correlatedObjects]){
45879	            material.emissive.set(color);
45880	        }
45881	        this[$onUpdate$1]();
45882	    }
45883	    [$getAlphaMode]() {
45884	        if (this[$backingThreeMaterial].transparent) {
45885	            return 'BLEND';
45886	        } else {
45887	            if (this[$backingThreeMaterial].alphaTest > 0.0) {
45888	                return 'MASK';
45889	            }
45890	        }
45891	        return 'OPAQUE';
45892	    }
45893	    [$applyAlphaCutoff]() {
45894	        this[$ensureMaterialIsLoaded]();
45895	        for (const material of this[$correlatedObjects]){
45896	            if (this[$getAlphaMode]() === 'MASK') {
45897	                if (material.alphaTest == undefined) {
45898	                    material.alphaTest = 0.5;
45899	                }
45900	            } else {
45901	                material.alphaTest = undefined;
45902	            }
45903	            material.needsUpdate = true;
45904	        }
45905	    }
45906	    setAlphaCutoff(cutoff) {
45907	        this[$ensureMaterialIsLoaded]();
45908	        for (const material of this[$correlatedObjects]){
45909	            material.alphaTest = cutoff;
45910	            material.needsUpdate = true;
45911	        }
45912	        this[$applyAlphaCutoff]();
45913	        this[$onUpdate$1]();
45914	    }
45915	    getAlphaCutoff() {
45916	        this[$ensureMaterialIsLoaded]();
45917	        return this[$backingThreeMaterial].alphaTest;
45918	    }
45919	    setDoubleSided(doubleSided) {
45920	        this[$ensureMaterialIsLoaded]();
45921	        for (const material of this[$correlatedObjects]){
45922	            material.side = doubleSided ? DoubleSide : FrontSide;
45923	            material.needsUpdate = true;
45924	        }
45925	        this[$onUpdate$1]();
45926	    }
45927	    getDoubleSided() {
45928	        this[$ensureMaterialIsLoaded]();
45929	        return this[$backingThreeMaterial].side == DoubleSide;
45930	    }
45931	    setAlphaMode(alphaMode) {
45932	        this[$ensureMaterialIsLoaded]();
45933	        const enableTransparency = (material, enabled)=>{
45934	            material.transparent = enabled;
45935	            material.depthWrite = !enabled;
45936	        };
45937	        for (const material of this[$correlatedObjects]){
45938	            enableTransparency(material, alphaMode === 'BLEND');
45939	            if (alphaMode === 'MASK') {
45940	                material.alphaTest = 0.5;
45941	            } else {
45942	                material.alphaTest = undefined;
45943	            }
45944	            material.needsUpdate = true;
45945	        }
45946	        this[$onUpdate$1]();
45947	    }
45948	    getAlphaMode() {
45949	        this[$ensureMaterialIsLoaded]();
45950	        return this[$getAlphaMode]();
45951	    }
45952	    get emissiveStrength() {
45953	        this[$ensureMaterialIsLoaded]();
45954	        return this[$backingThreeMaterial].emissiveIntensity;
45955	    }
45956	    setEmissiveStrength(emissiveStrength) {
45957	        this[$ensureMaterialIsLoaded]();
45958	        for (const material of this[$correlatedObjects]){
45959	            material.emissiveIntensity = emissiveStrength;
45960	        }
45961	        this[$onUpdate$1]();
45962	    }
45963	    get clearcoatFactor() {
45964	        this[$ensureMaterialIsLoaded]();
45965	        return this[$backingThreeMaterial].clearcoat;
45966	    }
45967	    get clearcoatRoughnessFactor() {
45968	        this[$ensureMaterialIsLoaded]();
45969	        return this[$backingThreeMaterial].clearcoatRoughness;
45970	    }
45971	    get clearcoatTexture() {
45972	        this[$ensureMaterialIsLoaded]();
45973	        return this[$pbrTextures].get(TextureUsage.Clearcoat);
45974	    }
45975	    get clearcoatRoughnessTexture() {
45976	        this[$ensureMaterialIsLoaded]();
45977	        return this[$pbrTextures].get(TextureUsage.ClearcoatRoughness);
45978	    }
45979	    get clearcoatNormalTexture() {
45980	        this[$ensureMaterialIsLoaded]();
45981	        return this[$pbrTextures].get(TextureUsage.ClearcoatNormal);
45982	    }
45983	    get clearcoatNormalScale() {
45984	        this[$ensureMaterialIsLoaded]();
45985	        return this[$backingThreeMaterial].clearcoatNormalScale.x;
45986	    }
45987	    setClearcoatFactor(clearcoatFactor) {
45988	        this[$ensureMaterialIsLoaded]();
45989	        for (const material of this[$correlatedObjects]){
45990	            material.clearcoat = clearcoatFactor;
45991	        }
45992	        this[$onUpdate$1]();
45993	    }
45994	    setClearcoatRoughnessFactor(clearcoatRoughnessFactor) {
45995	        this[$ensureMaterialIsLoaded]();
45996	        for (const material of this[$correlatedObjects]){
45997	            material.clearcoatRoughness = clearcoatRoughnessFactor;
45998	        }
45999	        this[$onUpdate$1]();
46000	    }
46001	    setClearcoatNormalScale(clearcoatNormalScale) {
46002	        this[$ensureMaterialIsLoaded]();
46003	        for (const material of this[$correlatedObjects]){
46004	            material.clearcoatNormalScale = new Vector2(clearcoatNormalScale, clearcoatNormalScale);
46005	        }
46006	        this[$onUpdate$1]();
46007	    }
46008	    get ior() {
46009	        this[$ensureMaterialIsLoaded]();
46010	        return this[$backingThreeMaterial].ior;
46011	    }
46012	    setIor(ior) {
46013	        this[$ensureMaterialIsLoaded]();
46014	        for (const material of this[$correlatedObjects]){
46015	            material.ior = ior;
46016	        }
46017	        this[$onUpdate$1]();
46018	    }
46019	    get sheenColorFactor() {
46020	        this[$ensureMaterialIsLoaded]();
46021	        return this[$backingThreeMaterial].sheenColor.toArray();
46022	    }
46023	    get sheenColorTexture() {
46024	        this[$ensureMaterialIsLoaded]();
46025	        return this[$pbrTextures].get(TextureUsage.SheenColor);
46026	    }
46027	    get sheenRoughnessFactor() {
46028	        this[$ensureMaterialIsLoaded]();
46029	        return this[$backingThreeMaterial].sheenRoughness;
46030	    }
46031	    get sheenRoughnessTexture() {
46032	        this[$ensureMaterialIsLoaded]();
46033	        return this[$pbrTextures].get(TextureUsage.SheenRoughness);
46034	    }
46035	    setSheenColorFactor(rgb) {
46036	        this[$ensureMaterialIsLoaded]();
46037	        const color = this.colorFromRgb(rgb);
46038	        for (const material of this[$correlatedObjects]){
46039	            material.sheenColor.set(color);
46040	            material.sheen = 1;
46041	        }
46042	        this[$onUpdate$1]();
46043	    }
46044	    setSheenRoughnessFactor(roughness) {
46045	        this[$ensureMaterialIsLoaded]();
46046	        for (const material of this[$correlatedObjects]){
46047	            material.sheenRoughness = roughness;
46048	            material.sheen = 1;
46049	        }
46050	        this[$onUpdate$1]();
46051	    }
46052	    get transmissionFactor() {
46053	        this[$ensureMaterialIsLoaded]();
46054	        return this[$backingThreeMaterial].transmission;
46055	    }
46056	    get transmissionTexture() {
46057	        this[$ensureMaterialIsLoaded]();
46058	        return this[$pbrTextures].get(TextureUsage.Transmission);
46059	    }
46060	    setTransmissionFactor(transmission) {
46061	        this[$ensureMaterialIsLoaded]();
46062	        for (const material of this[$correlatedObjects]){
46063	            material.transmission = transmission;
46064	        }
46065	        this[$onUpdate$1]();
46066	    }
46067	    get thicknessFactor() {
46068	        this[$ensureMaterialIsLoaded]();
46069	        return this[$backingThreeMaterial].thickness;
46070	    }
46071	    get thicknessTexture() {
46072	        this[$ensureMaterialIsLoaded]();
46073	        return this[$pbrTextures].get(TextureUsage.Thickness);
46074	    }
46075	    get attenuationDistance() {
46076	        this[$ensureMaterialIsLoaded]();
46077	        return this[$backingThreeMaterial].attenuationDistance;
46078	    }
46079	    get attenuationColor() {
46080	        this[$ensureMaterialIsLoaded]();
46081	        return this[$backingThreeMaterial].attenuationColor.toArray();
46082	    }
46083	    setThicknessFactor(thickness) {
46084	        this[$ensureMaterialIsLoaded]();
46085	        for (const material of this[$correlatedObjects]){
46086	            material.thickness = thickness;
46087	        }
46088	        this[$onUpdate$1]();
46089	    }
46090	    setAttenuationDistance(attenuationDistance) {
46091	        this[$ensureMaterialIsLoaded]();
46092	        for (const material of this[$correlatedObjects]){
46093	            material.attenuationDistance = attenuationDistance;
46094	        }
46095	        this[$onUpdate$1]();
46096	    }
46097	    setAttenuationColor(rgb) {
46098	        this[$ensureMaterialIsLoaded]();
46099	        const color = this.colorFromRgb(rgb);
46100	        for (const material of this[$correlatedObjects]){
46101	            material.attenuationColor.set(color);
46102	        }
46103	        this[$onUpdate$1]();
46104	    }
46105	    get specularFactor() {
46106	        this[$ensureMaterialIsLoaded]();
46107	        return this[$backingThreeMaterial].specularIntensity;
46108	    }
46109	    get specularTexture() {
46110	        this[$ensureMaterialIsLoaded]();
46111	        return this[$pbrTextures].get(TextureUsage.Specular);
46112	    }
46113	    get specularColorFactor() {
46114	        this[$ensureMaterialI
vendor: 18,141 bytes, lines 46114-46566
46114sLoaded]();
46115	        return this[$backingThreeMaterial].specularColor.toArray();
46116	    }
46117	    get specularColorTexture() {
46118	        this[$ensureMaterialIsLoaded]();
46119	        return this[$pbrTextures].get(TextureUsage.SheenColor);
46120	    }
46121	    setSpecularFactor(specularFactor) {
46122	        this[$ensureMaterialIsLoaded]();
46123	        for (const material of this[$correlatedObjects]){
46124	            material.specularIntensity = specularFactor;
46125	        }
46126	        this[$onUpdate$1]();
46127	    }
46128	    setSpecularColorFactor(rgb) {
46129	        this[$ensureMaterialIsLoaded]();
46130	        const color = this.colorFromRgb(rgb);
46131	        for (const material of this[$correlatedObjects]){
46132	            material.specularColor.set(color);
46133	        }
46134	        this[$onUpdate$1]();
46135	    }
46136	    get iridescenceFactor() {
46137	        this[$ensureMaterialIsLoaded]();
46138	        return this[$backingThreeMaterial].iridescence;
46139	    }
46140	    get iridescenceTexture() {
46141	        this[$ensureMaterialIsLoaded]();
46142	        return this[$pbrTextures].get(TextureUsage.Iridescence);
46143	    }
46144	    get iridescenceIor() {
46145	        this[$ensureMaterialIsLoaded]();
46146	        return this[$backingThreeMaterial].iridescenceIOR;
46147	    }
46148	    get iridescenceThicknessMinimum() {
46149	        this[$ensureMaterialIsLoaded]();
46150	        return this[$backingThreeMaterial].iridescenceThicknessRange[0];
46151	    }
46152	    get iridescenceThicknessMaximum() {
46153	        this[$ensureMaterialIsLoaded]();
46154	        return this[$backingThreeMaterial].iridescenceThicknessRange[1];
46155	    }
46156	    get iridescenceThicknessTexture() {
46157	        this[$ensureMaterialIsLoaded]();
46158	        return this[$pbrTextures].get(TextureUsage.IridescenceThickness);
46159	    }
46160	    setIridescenceFactor(iridescence) {
46161	        this[$ensureMaterialIsLoaded]();
46162	        for (const material of this[$correlatedObjects]){
46163	            material.iridescence = iridescence;
46164	        }
46165	        this[$onUpdate$1]();
46166	    }
46167	    setIridescenceIor(ior) {
46168	        this[$ensureMaterialIsLoaded]();
46169	        for (const material of this[$correlatedObjects]){
46170	            material.iridescenceIOR = ior;
46171	        }
46172	        this[$onUpdate$1]();
46173	    }
46174	    setIridescenceThicknessMinimum(thicknessMin) {
46175	        this[$ensureMaterialIsLoaded]();
46176	        for (const material of this[$correlatedObjects]){
46177	            material.iridescenceThicknessRange[0] = thicknessMin;
46178	        }
46179	        this[$onUpdate$1]();
46180	    }
46181	    setIridescenceThicknessMaximum(thicknessMax) {
46182	        this[$ensureMaterialIsLoaded]();
46183	        for (const material of this[$correlatedObjects]){
46184	            material.iridescenceThicknessRange[1] = thicknessMax;
46185	        }
46186	        this[$onUpdate$1]();
46187	    }
46188	    get anisotropyStrength() {
46189	        this[$ensureMaterialIsLoaded]();
46190	        return this[$backingThreeMaterial].anisotropy;
46191	    }
46192	    get anisotropyRotation() {
46193	        this[$ensureMaterialIsLoaded]();
46194	        return this[$backingThreeMaterial].anisotropyRotation;
46195	    }
46196	    get anisotropyTexture() {
46197	        this[$ensureMaterialIsLoaded]();
46198	        return this[$pbrTextures].get(TextureUsage.Anisotropy);
46199	    }
46200	    setAnisotropyStrength(strength) {
46201	        this[$ensureMaterialIsLoaded]();
46202	        for (const material of this[$correlatedObjects]){
46203	            material.anisotropy = strength;
46204	        }
46205	        this[$onUpdate$1]();
46206	    }
46207	    setAnisotropyRotation(rotation) {
46208	        this[$ensureMaterialIsLoaded]();
46209	        for (const material of this[$correlatedObjects]){
46210	            material.anisotropyRotation = rotation;
46211	        }
46212	        this[$onUpdate$1]();
46213	    }
46214	    constructor(onUpdate, gltfIndex, isActive, modelVariants, correlatedMaterials, name, lazyLoadInfo = undefined){
46215	        super(onUpdate, correlatedMaterials);
46216	        this[_a$3] = new Set();
46217	        this[_b$3] = new Map();
46218	        this[$gltfIndex] = gltfIndex;
46219	        this[$isActive] = isActive;
46220	        this[$modelVariants] = modelVariants;
46221	        this[$name] = name;
46222	        if (lazyLoadInfo == null) {
46223	            this[$initialize]();
46224	        } else {
46225	            this[$lazyLoadGLTFInfo] = lazyLoadInfo;
46226	        }
46227	    }
46228	}
46229
46230	let Node$1 = class Node {
46231	    constructor(name){
46232	        this.name = '';
46233	        this.children = new Array();
46234	        this.name = name;
46235	    }
46236	};
46237	class PrimitiveNode extends Node$1 {
46238	    async setActiveMaterial(material) {
46239	        const mvMaterial = this.materials.get(material);
46240	        if (material !== this.activeMaterialIdx) {
46241	            const backingMaterials = mvMaterial[$correlatedObjects];
46242	            const baseMaterial = await mvMaterial[$getLoadedMaterial]();
46243	            if (baseMaterial != null) {
46244	                this.mesh.material = baseMaterial;
46245	            } else {
46246	                this.mesh.material = backingMaterials.values().next().value;
46247	            }
46248	            this.parser.assignFinalMaterial(this.mesh);
46249	            backingMaterials.add(this.mesh.material);
46250	            this.activeMaterialIdx = material;
46251	        }
46252	        return this.mesh.material;
46253	    }
46254	    getActiveMaterial() {
46255	        return this.materials.get(this.activeMaterialIdx);
46256	    }
46257	    getMaterial(index) {
46258	        return this.materials.get(index);
46259	    }
46260	    async enableVariant(name) {
46261	        if (name == null) {
46262	            return this.setActiveMaterial(this.initialMaterialIdx);
46263	        }
46264	        if (this.variantToMaterialMap != null && this.modelVariants.has(name)) {
46265	            const modelVariants = this.modelVariants.get(name);
46266	            return this.enableVariantHelper(modelVariants.index);
46267	        }
46268	        return null;
46269	    }
46270	    async enableVariantHelper(index) {
46271	        if (this.variantToMaterialMap != null && index != null) {
46272	            const material = this.variantToMaterialMap.get(index);
46273	            if (material != null) {
46274	                return this.setActiveMaterial(material.index);
46275	            }
46276	        }
46277	        return null;
46278	    }
46279	    async instantiateVariants() {
46280	        if (this.variantToMaterialMap == null) {
46281	            return;
46282	        }
46283	        for (const index of this.variantToMaterialMap.keys()){
46284	            const variantMaterial = this.mesh.userData.variantMaterials.get(index);
46285	            if (variantMaterial.material != null) {
46286	                continue;
46287	            }
46288	            const threeMaterial = await this.enableVariantHelper(index);
46289	            if (threeMaterial != null) {
46290	                variantMaterial.material = threeMaterial;
46291	            }
46292	        }
46293	    }
46294	    get variantInfo() {
46295	        return this.variantToMaterialMap;
46296	    }
46297	    addVariant(materialVariant, variantName) {
46298	        if (!this.ensureVariantIsUnused(variantName)) {
46299	            return false;
46300	        }
46301	        if (!this.modelVariants.has(variantName)) {
46302	            this.modelVariants.set(variantName, {
46303	                name: variantName,
46304	                index: this.modelVariants.size
46305	            });
46306	        }
46307	        const modelVariantData = this.modelVariants.get(variantName);
46308	        const variantIndex = modelVariantData.index;
46309	        materialVariant[$variantIndices].add(variantIndex);
46310	        this.variantToMaterialMap.set(variantIndex, materialVariant);
46311	        this.materials.set(materialVariant.index, materialVariant);
46312	        this.updateVariantUserData(variantIndex, materialVariant);
46313	        return true;
46314	    }
46315	    deleteVariant(variantIndex) {
46316	        if (this.variantInfo.has(variantIndex)) {
46317	            this.variantInfo.delete(variantIndex);
46318	            const userDataMap = this.mesh.userData.variantMaterials;
46319	            if (userDataMap != null) {
46320	                userDataMap.delete(variantIndex);
46321	            }
46322	        }
46323	    }
46324	    updateVariantUserData(variantIndex, materialVariant) {
46325	        materialVariant[$variantIndices].add(variantIndex);
46326	        this.mesh.userData.variantData = this.modelVariants;
46327	        this.mesh.userData.variantMaterials = this.mesh.userData.variantMaterials || new Map();
46328	        const map = this.mesh.userData.variantMaterials;
46329	        map.set(variantIndex, {
46330	            material: materialVariant[$correlatedObjects].values().next().value,
46331	            gltfMaterialIndex: materialVariant.index
46332	        });
46333	    }
46334	    ensureVariantIsUnused(variantName) {
46335	        const modelVariants = this.modelVariants.get(variantName);
46336	        if (modelVariants != null && this.variantInfo.has(modelVariants.index)) {
46337	            console.warn(`Primitive cannot add variant '${variantName}' for this material, it already exists.`);
46338	            return false;
46339	        }
46340	        return true;
46341	    }
46342	    constructor(mesh, mvMaterials, modelVariants, correlatedSceneGraph){
46343	        super(mesh.name);
46344	        this.materials = new Map();
46345	        this.variantToMaterialMap = new Map();
46346	        this.initialMaterialIdx = 0;
46347	        this.activeMaterialIdx = 0;
46348	        this.mesh = mesh;
46349	        const { gltf, threeGLTF, threeObjectMap } = correlatedSceneGraph;
46350	        this.parser = threeGLTF.parser;
46351	        this.modelVariants = modelVariants;
46352	        this.mesh.userData.variantData = modelVariants;
46353	        const materialMappings = threeObjectMap.get(mesh.material);
46354	        if (materialMappings.materials != null) {
46355	            this.initialMaterialIdx = this.activeMaterialIdx = materialMappings.materials;
46356	        } else {
46357	            console.error(`Primitive (${mesh.name}) missing initial material reference.`);
46358	        }
46359	        const associations = mesh.userData.associations || {};
46360	        if (associations.meshes == null) {
46361	            console.error('Mesh is missing primitive index association');
46362	            return;
46363	        }
46364	        const meshElementArray = gltf['meshes'] || [];
46365	        const gltfPrimitives = meshElementArray[associations.meshes].primitives || [];
46366	        const gltfPrimitive = gltfPrimitives[associations.primitives];
46367	        if (gltfPrimitive == null) {
46368	            console.error('Mesh primitive definition is missing.');
46369	            return;
46370	        }
46371	        if (gltfPrimitive.material != null) {
46372	            this.materials.set(gltfPrimitive.material, mvMaterials[gltfPrimitive.material]);
46373	        } else {
46374	            const defaultIdx = mvMaterials.findIndex((mat)=>{
46375	                return mat.name === 'Default';
46376	            });
46377	            if (defaultIdx >= 0) {
46378	                this.materials.set(defaultIdx, mvMaterials[defaultIdx]);
46379	            } else {
46380	                console.warn('gltfPrimitive has no material!');
46381	            }
46382	        }
46383	        if (gltfPrimitive.extensions && gltfPrimitive.extensions['KHR_materials_variants']) {
46384	            const variantsExtension = gltfPrimitive.extensions['KHR_materials_variants'];
46385	            const extensions = threeGLTF.parser.json.extensions;
46386	            const variantNames = extensions['KHR_materials_variants'].variants;
46387	            for (const mapping of variantsExtension.mappings){
46388	                const mvMaterial = mvMaterials[mapping.material];
46389	                this.materials.set(mapping.material, mvMaterial);
46390	                for (const variant of mapping.variants){
46391	                    const { name } = variantNames[variant];
46392	                    this.variantToMaterialMap.set(variant, mvMaterial);
46393	                    mvMaterial[$variantIndices].add(variant);
46394	                    if (!modelVariants.has(name)) {
46395	                        modelVariants.set(name, {
46396	                            name,
46397	                            index: variant
46398	                        });
46399	                    }
46400	                }
46401	            }
46402	        }
46403	    }
46404	}
46405
46406	var _a$2, _b$2, _c$1, _d$1, _e$1, _f$1;
46407	const $materials = Symbol('materials');
46408	const $hierarchy = Symbol('hierarchy');
46409	const $roots = Symbol('roots');
46410	const $primitivesList = Symbol('primitives');
46411	const $prepareVariantsForExport = Symbol('prepareVariantsForExport');
46412	const $switchVariant = Symbol('switchVariant');
46413	const $materialFromPoint = Symbol('materialFromPoint');
46414	const $nodeFromPoint = Symbol('nodeFromPoint');
46415	const $nodeFromIndex = Symbol('nodeFromIndex');
46416	const $variantData = Symbol('variantData');
46417	const $availableVariants = Symbol('availableVariants');
46418	const $modelOnUpdate = Symbol('modelOnUpdate');
46419	const $cloneMaterial = Symbol('cloneMaterial');
46420	class LazyLoader {
46421	    constructor(gltf, gltfElementMap, mapKey, doLazyLoad){
46422	        this.gltf = gltf;
46423	        this.gltfElementMap = gltfElementMap;
46424	        this.mapKey = mapKey;
46425	        this.doLazyLoad = doLazyLoad;
46426	    }
46427	}
46428	 class Model {
46429	 get materials() {
46430	        return this[$materials];
46431	    }
46432	    [(_a$2 = $materials, _b$2 = $hierarchy, _c$1 = $roots, _d$1 = $primitivesList, _e$1 = $modelOnUpdate, _f$1 = $variantData, $availableVariants)]() {
46433	        const variants = Array.from(this[$variantData].values());
46434	        variants.sort((a, b)=>{
46435	            return a.index - b.index;
46436	        });
46437	        return variants.map((data)=>{
46438	            return data.name;
46439	        });
46440	    }
46441	    getMaterialByName(name) {
46442	        const matches = this[$materials].filter((material)=>{
46443	            return material.name === name;
46444	        });
46445	        if (matches.length > 0) {
46446	            return matches[0];
46447	        }
46448	        return null;
46449	    }
46450	    [$nodeFromIndex](mesh, primitive) {
46451	        const found = this[$hierarchy].find((node)=>{
46452	            if (node instanceof PrimitiveNode) {
46453	                const { meshes, primitives } = node.mesh.userData.associations;
46454	                if (meshes == mesh && primitives == primitive) {
46455	                    return true;
46456	                }
46457	            }
46458	            return false;
46459	        });
46460	        return found == null ? null : found;
46461	    }
46462	    [$nodeFromPoint](hit) {
46463	        return this[$hierarchy].find((node)=>{
46464	            if (node instanceof PrimitiveNode) {
46465	                const primitive = node;
46466	                if (primitive.mesh === hit.object) {
46467	                    return true;
46468	                }
46469	            }
46470	            return false;
46471	        });
46472	    }
46473	 [$materialFromPoint](hit) {
46474	        return this[$nodeFromPoint](hit).getActiveMaterial();
46475	    }
46476	 async [$switchVariant](variantName) {
46477	        for (const primitive of this[$primitivesList]){
46478	            await primitive.enableVariant(variantName);
46479	        }
46480	        for (const material of this.materials){
46481	            material[$setActive](false);
46482	        }
46483	        for (const primitive of this[$primitivesList]){
46484	            this.materials[primitive.getActiveMaterial().index][$setActive](true);
46485	        }
46486	    }
46487	    async [$prepareVariantsForExport]() {
46488	        const promises = new Array();
46489	        for (const primitive of this[$primitivesList]){
46490	            promises.push(primitive.instantiateVariants());
46491	        }
46492	        await Promise.all(promises);
46493	    }
46494	    [$cloneMaterial](index, newMaterialName) {
46495	        const material = this.materials[index];
46496	        if (!material.isLoaded) {
46497	            console.error(`Cloning an unloaded material,
46498           call 'material.ensureLoaded() before cloning the material.`);
46499	        }
46500	        const threeMaterialSet = material[$correlatedObjects];
46501	        const clonedSet = new Set();
46502	        for (const [i, threeMaterial] of threeMaterialSet.entries()){
46503	            const clone = threeMaterial.clone();
46504	            clone.name = newMaterialName + (threeMaterialSet.size > 1 ? '_inst' + i : '');
46505	            clonedSet.add(clone);
46506	        }
46507	        const clonedMaterial = new Material(this[$modelOnUpdate], this[$materials].length, false, this[$variantData], clonedSet, newMaterialName);
46508	        this[$materials].push(clonedMaterial);
46509	        return clonedMaterial;
46510	    }
46511	    createMaterialInstanceForVariant(originalMaterialIndex, newMaterialName, variantName, activateVariant = true) {
46512	        let variantMaterialInstance = null;
46513	        for (const primitive of this[$primitivesList]){
46514	            const variantData = this[$variantData].get(variantName);
46515	            if (variantData != null && primitive.variantInfo.has(variantData.index)) {
46516	                continue;
46517	            }
46518	            if (primitive.getMaterial(originalMaterialIndex) == null) {
46519	                continue;
46520	            }
46521	            if (!this.hasVariant(variantName)) {
46522	                this.createVariant(variantName);
46523	            }
46524	            if (variantMaterialInstance == null) {
46525	                variantMaterialInstance = this[$cloneMaterial](originalMaterialIndex, newMaterialName);
46526	            }
46527	            primitive.addVariant(variantMaterialInstance, variantName);
46528	        }
46529	        if (activateVariant && variantMaterialInstance != null) {
46530	            variantMaterialInstance[$setActive](true);
46531	            this.materials[originalMaterialIndex][$setActive](false);
46532	            for (const primitive of this[$primitivesList]){
46533	                primitive.enableVariant(variantName);
46534	            }
46535	        }
46536	        return variantMaterialInstance;
46537	    }
46538	    createVariant(variantName) {
46539	        if (!this[$variantData].has(variantName)) {
46540	            this[$variantData].set(variantName, {
46541	                name: variantName,
46542	                index: this[$variantData].size
46543	            });
46544	        } else {
46545	            console.warn(`Variant '${variantName}'' already exists`);
46546	        }
46547	    }
46548	    hasVariant(variantName) {
46549	        return this[$variantData].has(variantName);
46550	    }
46551	    setMaterialToVariant(materialIndex, targetVariantName) {
46552	        if (this[$availableVariants]().find((name)=>name === targetVariantName) == null) {
46553	            console.warn(`Can't add material to '${targetVariantName}', the variant does not exist.'`);
46554	            return;
46555	        }
46556	        if (materialIndex < 0 || materialIndex >= this.materials.length) {
46557	            console.error(`setMaterialToVariant(): materialIndex is out of bounds.`);
46558	            return;
46559	        }
46560	        for (const primitive of this[$primitivesList]){
46561	            const material = primitive.getMaterial(materialIndex);
46562	            if (material != null) {
46563	                primitive.addVariant(material, targetVariantName);
46564	            }
46565	        }
46566	    }
vendor: 15,708 bytes, lines 46567-46965
46567	    updateVariantName(currentName, newName) {
46568	        const variantData = this[$variantData].get(currentName);
46569	        if (variantData == null) {
46570	            return;
46571	        }
46572	        variantData.name = newName;
46573	        this[$variantData].set(newName, variantData);
46574	        this[$variantData].delete(currentName);
46575	    }
46576	    deleteVariant(variantName) {
46577	        const variant = this[$variantData].get(variantName);
46578	        if (variant == null) {
46579	            return;
46580	        }
46581	        for (const material of this.materials){
46582	            if (material.hasVariant(variantName)) {
46583	                material[$variantIndices].delete(variant.index);
46584	            }
46585	        }
46586	        for (const primitive of this[$primitivesList]){
46587	            primitive.deleteVariant(variant.index);
46588	        }
46589	        this[$variantData].delete(variantName);
46590	    }
46591	    constructor(correlatedSceneGraph, onUpdate = ()=>{}){
46592	        this[_a$2] = new Array();
46593	        this[_b$2] = new Array();
46594	        this[_c$1] = new Array();
46595	        this[_d$1] = new Array();
46596	        this[_e$1] = ()=>{};
46597	        this[_f$1] = new Map();
46598	        this[$modelOnUpdate] = onUpdate;
46599	        const { gltf, threeGLTF, gltfElementMap } = correlatedSceneGraph;
46600	        for (const [i, material] of gltf.materials.entries()){
46601	            const correlatedMaterial = gltfElementMap.get(material);
46602	            if (correlatedMaterial != null) {
46603	                this[$materials].push(new Material(onUpdate, i, true, this[$variantData], correlatedMaterial, material.name));
46604	            } else {
46605	                const elementArray = gltf['materials'] || [];
46606	                const gltfMaterialDef = elementArray[i];
46607	                const threeMaterialSet = new Set();
46608	                gltfElementMap.set(gltfMaterialDef, threeMaterialSet);
46609	                const materialLoadCallback = async ()=>{
46610	                    const threeMaterial = await threeGLTF.parser.getDependency('material', i);
46611	                    threeMaterialSet.add(threeMaterial);
46612	                    return threeMaterial;
46613	                };
46614	                this[$materials].push(new Material(onUpdate, i, false, this[$variantData], threeMaterialSet, material.name, new LazyLoader(gltf, gltfElementMap, gltfMaterialDef, materialLoadCallback)));
46615	            }
46616	        }
46617	        const parentMap = new Map();
46618	        const nodeStack = new Array();
46619	        for (const object of threeGLTF.scene.children){
46620	            nodeStack.push(object);
46621	        }
46622	        while(nodeStack.length > 0){
46623	            const object = nodeStack.pop();
46624	            let node = null;
46625	            if (object instanceof Mesh) {
46626	                node = new PrimitiveNode(object, this.materials, this[$variantData], correlatedSceneGraph);
46627	                this[$primitivesList].push(node);
46628	            } else {
46629	                node = new Node$1(object.name);
46630	            }
46631	            const parent = parentMap.get(object);
46632	            if (parent != null) {
46633	                parent.children.push(node);
46634	            } else {
46635	                this[$roots].push(node);
46636	            }
46637	            this[$hierarchy].push(node);
46638	            for (const child of object.children){
46639	                nodeStack.push(child);
46640	                parentMap.set(object, node);
46641	            }
46642	        }
46643	    }
46644	}
46645
46646	var __decorate$5 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
46647	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
46648	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
46649	    return c > 3 && r && Object.defineProperty(target, key, r), r;
46650	};
46651	const $currentGLTF = Symbol('currentGLTF');
46652	const $originalGltfJson = Symbol('originalGltfJson');
46653	const $model = Symbol('model');
46654	const $getOnUpdateMethod = Symbol('getOnUpdateMethod');
46655	const $buildTexture = Symbol('buildTexture');
46656	 const SceneGraphMixin = (ModelViewerElement)=>{
46657	    var _a, _b, _c;
46658	    class SceneGraphModelViewerElement extends ModelViewerElement {
46659	         get model() {
46660	            return this[$model];
46661	        }
46662	        get availableVariants() {
46663	            return this.model ? this.model[$availableVariants]() : [];
46664	        }
46665	 get originalGltfJson() {
46666	            return this[$originalGltfJson];
46667	        }
46668	        [(_a = $model, _b = $currentGLTF, _c = $originalGltfJson, $getOnUpdateMethod)]() {
46669	            return ()=>{
46670	                this[$needsRender]();
46671	            };
46672	        }
46673	        [$buildTexture](texture) {
46674	            texture.colorSpace = SRGBColorSpace;
46675	            texture.wrapS = RepeatWrapping;
46676	            texture.wrapT = RepeatWrapping;
46677	            return new Texture(this[$getOnUpdateMethod](), texture);
46678	        }
46679	        async createTexture(uri, type = 'image/png') {
46680	            const { textureUtils } = this[$renderer];
46681	            const texture = await textureUtils.loadImage(uri, this.withCredentials);
46682	            texture.userData.mimeType = type;
46683	            return this[$buildTexture](texture);
46684	        }
46685	        async createLottieTexture(uri, quality = 1) {
46686	            const { textureUtils } = this[$renderer];
46687	            const texture = await textureUtils.loadLottie(uri, quality, this.withCredentials);
46688	            return this[$buildTexture](texture);
46689	        }
46690	        createVideoTexture(uri) {
46691	            const video = document.createElement('video');
46692	            video.crossOrigin = this.withCredentials ? 'use-credentials' : 'anonymous';
46693	            video.src = uri;
46694	            video.muted = true;
46695	            video.playsInline = true;
46696	            video.loop = true;
46697	            video.play();
46698	            const texture = new VideoTexture(video);
46699	            return this[$buildTexture](texture);
46700	        }
46701	        createCanvasTexture() {
46702	            const canvas = document.createElement('canvas');
46703	            const texture = new CanvasTexture(canvas);
46704	            return this[$buildTexture](texture);
46705	        }
46706	        async updated(changedProperties) {
46707	            super.updated(changedProperties);
46708	            if (changedProperties.has('variantName')) {
46709	                const updateVariantProgress = this[$progressTracker].beginActivity('variant-update');
46710	                updateVariantProgress(0.1);
46711	                const model = this[$model];
46712	                const { variantName } = this;
46713	                if (model != null) {
46714	                    await model[$switchVariant](variantName);
46715	                    this[$needsRender]();
46716	                    this.dispatchEvent(new CustomEvent('variant-applied'));
46717	                }
46718	                updateVariantProgress(1.0);
46719	            }
46720	            if (changedProperties.has('orientation') || changedProperties.has('scale')) {
46721	                if (!this.loaded) {
46722	                    return;
46723	                }
46724	                const scene = this[$scene];
46725	                scene.applyTransform();
46726	                scene.updateBoundingBox();
46727	                scene.updateShadow();
46728	                this[$renderer].arRenderer.onUpdateScene();
46729	                this[$needsRender]();
46730	            }
46731	        }
46732	        [$onModelLoad]() {
46733	            super[$onModelLoad]();
46734	            const { currentGLTF } = this[$scene];
46735	            if (currentGLTF != null) {
46736	                const { correlatedSceneGraph } = currentGLTF;
46737	                if (correlatedSceneGraph != null && currentGLTF !== this[$currentGLTF]) {
46738	                    this[$model] = new Model(correlatedSceneGraph, this[$getOnUpdateMethod]());
46739	                    this[$originalGltfJson] = JSON.parse(JSON.stringify(correlatedSceneGraph.gltf));
46740	                }
46741	                if ('variants' in currentGLTF.userData) {
46742	                    this.requestUpdate('variantName');
46743	                }
46744	            }
46745	            this[$currentGLTF] = currentGLTF;
46746	        }
46747	         async exportScene(options) {
46748	            const scene = this[$scene];
46749	            return new Promise(async (resolve, reject)=>{
46750	                const opts = {
46751	                    binary: true,
46752	                    onlyVisible: true,
46753	                    maxTextureSize: Infinity,
46754	                    includeCustomExtensions: false,
46755	                    forceIndices: false
46756	                };
46757	                Object.assign(opts, options);
46758	                opts.animations = scene.animations;
46759	                opts.truncateDrawRange = true;
46760	                const shadow = scene.shadow;
46761	                let visible = false;
46762	                if (shadow != null) {
46763	                    visible = shadow.visible;
46764	                    shadow.visible = false;
46765	                }
46766	                await this[$model][$prepareVariantsForExport]();
46767	                const exporter = new GLTFExporter().register((writer)=>new GLTFExporterMaterialsVariantsExtension(writer));
46768	                exporter.parse(scene.model, (gltf)=>{
46769	                    return resolve(new Blob([
46770	                        opts.binary ? gltf : JSON.stringify(gltf)
46771	                    ], {
46772	                        type: opts.binary ? 'application/octet-stream' : 'application/json'
46773	                    }));
46774	                }, ()=>{
46775	                    return reject('glTF export failed');
46776	                }, opts);
46777	                if (shadow != null) {
46778	                    shadow.visible = visible;
46779	                }
46780	            });
46781	        }
46782	        materialFromPoint(pixelX, pixelY) {
46783	            const model = this[$model];
46784	            if (model == null) {
46785	                return null;
46786	            }
46787	            const scene = this[$scene];
46788	            const ndcCoords = scene.getNDC(pixelX, pixelY);
46789	            const hit = scene.hitFromPoint(ndcCoords);
46790	            if (hit == null || hit.face == null) {
46791	                return null;
46792	            }
46793	            return model[$materialFromPoint](hit);
46794	        }
46795	        constructor(){
46796	            super(...arguments);
46797	            this[_a] = undefined;
46798	            this[_b] = null;
46799	            this[_c] = null;
46800	            this.variantName = null;
46801	            this.orientation = '0 0 0';
46802	            this.scale = '1 1 1';
46803	        }
46804	    }
46805	    __decorate$5([
46806	        n$2({
46807	            type: String,
46808	            attribute: 'variant-name'
46809	        })
46810	    ], SceneGraphModelViewerElement.prototype, "variantName", void 0);
46811	    __decorate$5([
46812	        n$2({
46813	            type: String,
46814	            attribute: 'orientation'
46815	        })
46816	    ], SceneGraphModelViewerElement.prototype, "orientation", void 0);
46817	    __decorate$5([
46818	        n$2({
46819	            type: String,
46820	            attribute: 'scale'
46821	        })
46822	    ], SceneGraphModelViewerElement.prototype, "scale", void 0);
46823	    return SceneGraphModelViewerElement;
46824	};
46825
46826	class GroundedSkybox extends Mesh {
46827	    get map() {
46828	        return this.material.map;
46829	    }
46830	    set map(skybox) {
46831	        this.material.map = skybox;
46832	    }
46833	    isUsable() {
46834	        return this.height > 0 && this.radius > 0 && this.geometry != null && this.map != null;
46835	    }
46836	    updateGeometry(height = this.height, radius = this.radius, resolution = 128) {
46837	        if (height != this.height || radius != this.radius || resolution != this.resolution) {
46838	            this.height = height;
46839	            this.radius = radius;
46840	            this.resolution = resolution;
46841	            if (height > 0 && radius > 0) {
46842	                this.geometry.dispose();
46843	                this.geometry = makeGeometry(height, radius, resolution);
46844	            }
46845	        }
46846	    }
46847	    constructor(){
46848	        super(undefined, new MeshBasicMaterial({
46849	            depthWrite: false
46850	        }));
46851	        this.height = 0;
46852	        this.radius = 0;
46853	        this.resolution = 0;
46854	        this.userData.noHit = true;
46855	    }
46856	}
46857	function makeGeometry(height, radius, resolution) {
46858	    const geometry = new SphereGeometry(radius, 2 * resolution, resolution);
46859	    geometry.scale(1, 1, -1);
46860	    const pos = geometry.getAttribute('position');
46861	    const tmp = new Vector3();
46862	    for(let i = 0; i < pos.count; ++i){
46863	        tmp.fromBufferAttribute(pos, i);
46864	        if (tmp.y < 0) {
46865	            const y1 = -height * 3 / 2;
46866	            const f = tmp.y < y1 ? -height / tmp.y : 1 - tmp.y * tmp.y / (3 * y1 * y1);
46867	            tmp.multiplyScalar(f);
46868	            tmp.toArray(pos.array, 3 * i);
46869	        }
46870	    }
46871	    pos.needsUpdate = true;
46872	    return geometry;
46873	}
46874
46875	const a = new Vector3();
46876	const b = new Vector3();
46877	const c = new Vector3();
46878	const mat = new Matrix3();
46879	const triangle = new Triangle();
46880	const quat = new Quaternion();
46881	 class Hotspot extends CSS2DObject {
46882	    get facingCamera() {
46883	        return !this.element.classList.contains('hide');
46884	    }
46885	 show() {
46886	        if (!this.facingCamera || !this.initialized) {
46887	            this.updateVisibility(true);
46888	        }
46889	    }
46890	 hide() {
46891	        if (this.facingCamera || !this.initialized) {
46892	            this.updateVisibility(false);
46893	        }
46894	    }
46895	 increment() {
46896	        this.referenceCount++;
46897	    }
46898	 decrement() {
46899	        if (this.referenceCount > 0) {
46900	            --this.referenceCount;
46901	        }
46902	        return this.referenceCount === 0;
46903	    }
46904	 updatePosition(position) {
46905	        if (position == null) return;
46906	        const positionNodes = parseExpressions(position)[0].terms;
46907	        for(let i = 0; i < 3; ++i){
46908	            this.position.setComponent(i, normalizeUnit(positionNodes[i]).number);
46909	        }
46910	        this.updateMatrixWorld();
46911	    }
46912	 updateNormal(normal) {
46913	        if (normal == null) return;
46914	        const normalNodes = parseExpressions(normal)[0].terms;
46915	        for(let i = 0; i < 3; ++i){
46916	            this.normal.setComponent(i, normalNodes[i].number);
46917	        }
46918	    }
46919	    updateSurface() {
46920	        const { mesh, tri, bary } = this;
46921	        if (mesh == null || tri == null || bary == null) {
46922	            return;
46923	        }
46924	        mesh.getVertexPosition(tri.x, a);
46925	        mesh.getVertexPosition(tri.y, b);
46926	        mesh.getVertexPosition(tri.z, c);
46927	        a.toArray(mat.elements, 0);
46928	        b.toArray(mat.elements, 3);
46929	        c.toArray(mat.elements, 6);
46930	        this.position.copy(bary).applyMatrix3(mat);
46931	        const target = this.parent;
46932	        target.worldToLocal(mesh.localToWorld(this.position));
46933	        triangle.set(a, b, c);
46934	        triangle.getNormal(this.normal).transformDirection(mesh.matrixWorld);
46935	        const pivot = target.parent;
46936	        quat.setFromAxisAngle(a.set(0, 1, 0), -pivot.rotation.y);
46937	        this.normal.applyQuaternion(quat);
46938	    }
46939	    orient(radians) {
46940	        this.pivot.style.transform = `rotate(${radians}rad)`;
46941	    }
46942	    updateVisibility(show) {
46943	        this.element.classList.toggle('hide', !show);
46944	        this.slot.assignedNodes().forEach((node)=>{
46945	            if (node.nodeType !== Node.ELEMENT_NODE) {
46946	                return;
46947	            }
46948	            const element = node;
46949	            const visibilityAttribute = element.dataset.visibilityAttribute;
46950	            if (visibilityAttribute != null) {
46951	                const attributeName = `data-${visibilityAttribute}`;
46952	                element.toggleAttribute(attributeName, show);
46953	            }
46954	            element.dispatchEvent(new CustomEvent('hotspot-visibility', {
46955	                detail: {
46956	                    visible: show
46957	                }
46958	            }));
46959	        });
46960	        this.initialized = true;
46961	    }
46962	    constructor(config){
46963	        super(document.createElement('div'));
46964	        this.normal = new Vector3(0, 1, 0);
46965	        this.initialized = false;
vendor: 4,404 bytes, lines 46966-47107
46966	        this.referenceCount = 1;
46967	        this.pivot = document.createElement('div');
46968	        this.slot = document.createElement('slot');
46969	        this.element.classList.add('annotation-wrapper');
46970	        this.slot.name = config.name;
46971	        this.element.appendChild(this.pivot);
46972	        this.pivot.appendChild(this.slot);
46973	        this.updatePosition(config.position);
46974	        this.updateNormal(config.normal);
46975	        this.surface = config.surface;
46976	    }
46977	}
46978
46979	/**
46980	 * Two pass Gaussian blur filter (horizontal and vertical blur shaders)
46981	 * - see http://www.cake23.de/traveling-wavefronts-lit-up.html
46982	 *
46983	 * - 9 samples per pass
46984	 * - standard deviation 2.7
46985	 * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
46986	 */ const HorizontalBlurShader = {
46987	    name: 'HorizontalBlurShader',
46988	    uniforms: {
46989	        'tDiffuse': {
46990	            value: null
46991	        },
46992	        'h': {
46993	            value: 1.0 / 512.0
46994	        }
46995	    },
46996	    vertexShader: /* glsl */ `
46997
46998		varying vec2 vUv;
46999
47000		void main() {
47001
47002			vUv = uv;
47003			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
47004
47005		}`,
47006	    fragmentShader: /* glsl */ `
47007
47008		uniform sampler2D tDiffuse;
47009		uniform float h;
47010
47011		varying vec2 vUv;
47012
47013		void main() {
47014
47015			vec4 sum = vec4( 0.0 );
47016
47017			sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;
47018			sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;
47019			sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;
47020			sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;
47021			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
47022			sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;
47023			sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;
47024			sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;
47025			sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;
47026
47027			gl_FragColor = sum;
47028
47029		}`
47030	};
47031
47032	/**
47033	 * Two pass Gaussian blur filter (horizontal and vertical blur shaders)
47034	 * - see http://www.cake23.de/traveling-wavefronts-lit-up.html
47035	 *
47036	 * - 9 samples per pass
47037	 * - standard deviation 2.7
47038	 * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
47039	 */ const VerticalBlurShader = {
47040	    name: 'VerticalBlurShader',
47041	    uniforms: {
47042	        'tDiffuse': {
47043	            value: null
47044	        },
47045	        'v': {
47046	            value: 1.0 / 512.0
47047	        }
47048	    },
47049	    vertexShader: /* glsl */ `
47050
47051		varying vec2 vUv;
47052
47053		void main() {
47054
47055			vUv = uv;
47056			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
47057
47058		}`,
47059	    fragmentShader: /* glsl */ `
47060
47061		uniform sampler2D tDiffuse;
47062		uniform float v;
47063
47064		varying vec2 vUv;
47065
47066		void main() {
47067
47068			vec4 sum = vec4( 0.0 );
47069
47070			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;
47071			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;
47072			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;
47073			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;
47074			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
47075			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;
47076			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;
47077			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;
47078			sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;
47079
47080			gl_FragColor = sum;
47081
47082		}`
47083	};
47084
47085	/**
47086	 * Returns a value linearly interpolated from two known points based on the given interval -
47087	 * `t = 0` will return `x` and `t = 1` will return `y`.
47088	 *
47089	 * @param {number} x - The start point
47090	 * @param {number} y - The end point.
47091	 * @param {number} t - The interpolation factor in the closed interval `[0, 1]`.
47092	 * @return {number} The interpolated value.
47093	 */ function lerp(x, y, t) {
47094	    return (1 - t) * x + t * y;
47095	}
47096
47097	const LOG_MAX_RESOLUTION = 9;
47098	const LOG_MIN_RESOLUTION = 6;
47099	const ANIMATION_SCALING = 2;
47100	const DEFAULT_HARD_INTENSITY = 0.3;
47101	 class Shadow extends Object3D {
47102	 setScene(scene, softness, side) {
47103	        const { boundingBox, size, rotation, position } = this;
47104	        this.isAnimated = scene.animationNames.length > 0;
47105	        this.boundingBox.copy(scene.boundingBox);
47106	        this.size.copy(scene.size);
47107	        this.maxDimension = Math.max(size.x, size.y, size.z) * (this.isAnimated ? ANIMATION_
vendor: 10,021 bytes, lines 47107-47372
47107SCALING : 1);
47108	        this.boundingBox.getCenter(position);
47109	        if (side === 'back') {
47110	            const { min, max } = boundingBox;
47111	            [min.y, min.z] = [
47112	                min.z,
47113	                min.y
47114	            ];
47115	            [max.y, max.z] = [
47116	                max.z,
47117	                max.y
47118	            ];
47119	            [size.y, size.z] = [
47120	                size.z,
47121	                size.y
47122	            ];
47123	            rotation.x = Math.PI / 2;
47124	            rotation.y = Math.PI;
47125	        } else {
47126	            rotation.x = 0;
47127	            rotation.y = 0;
47128	        }
47129	        if (this.isAnimated) {
47130	            const minY = boundingBox.min.y;
47131	            const maxY = boundingBox.max.y;
47132	            size.y = this.maxDimension;
47133	            boundingBox.expandByVector(size.subScalar(this.maxDimension).multiplyScalar(-0.5));
47134	            boundingBox.min.y = minY;
47135	            boundingBox.max.y = maxY;
47136	            size.set(this.maxDimension, maxY - minY, this.maxDimension);
47137	        }
47138	        if (side === 'bottom') {
47139	            position.y = boundingBox.min.y;
47140	        } else {
47141	            position.z = boundingBox.min.y;
47142	        }
47143	        this.setSoftness(softness);
47144	    }
47145	 setSoftness(softness) {
47146	        this.softness = softness;
47147	        const { size, camera } = this;
47148	        const scaleY = this.isAnimated ? ANIMATION_SCALING : 1;
47149	        const resolution = scaleY * Math.pow(2, LOG_MAX_RESOLUTION - softness * (LOG_MAX_RESOLUTION - LOG_MIN_RESOLUTION));
47150	        this.setMapSize(resolution);
47151	        const softFar = size.y / 2;
47152	        const hardFar = size.y * scaleY;
47153	        camera.near = 0;
47154	        camera.far = lerp(hardFar, softFar, softness);
47155	        this.depthMaterial.opacity = 1.0 / softness;
47156	        camera.updateProjectionMatrix();
47157	        this.setIntensity(this.intensity);
47158	        this.setOffset(0);
47159	    }
47160	 setMapSize(maxMapSize) {
47161	        const { size } = this;
47162	        if (this.isAnimated) {
47163	            maxMapSize *= ANIMATION_SCALING;
47164	        }
47165	        const baseWidth = Math.floor(size.x > size.z ? maxMapSize : maxMapSize * size.x / size.z);
47166	        const baseHeight = Math.floor(size.x > size.z ? maxMapSize * size.z / size.x : maxMapSize);
47167	        const TAP_WIDTH = 10;
47168	        const width = TAP_WIDTH + baseWidth;
47169	        const height = TAP_WIDTH + baseHeight;
47170	        if (this.renderTarget != null && (this.renderTarget.width !== width || this.renderTarget.height !== height)) {
47171	            this.renderTarget.dispose();
47172	            this.renderTarget = null;
47173	            this.renderTargetBlur.dispose();
47174	            this.renderTargetBlur = null;
47175	        }
47176	        if (this.renderTarget == null) {
47177	            const params = {
47178	                format: RGBAFormat
47179	            };
47180	            this.renderTarget = new WebGLRenderTarget(width, height, params);
47181	            this.renderTargetBlur = new WebGLRenderTarget(width, height, params);
47182	            this.floor.material.map = this.renderTarget.texture;
47183	        }
47184	        this.camera.scale.set(size.x * (1 + TAP_WIDTH / baseWidth), size.z * (1 + TAP_WIDTH / baseHeight), 1);
47185	        this.needsUpdate = true;
47186	    }
47187	 setIntensity(intensity) {
47188	        this.intensity = intensity;
47189	        if (intensity > 0) {
47190	            this.visible = true;
47191	            this.floor.visible = true;
47192	            this.floor.material.opacity = intensity * lerp(DEFAULT_HARD_INTENSITY, 1, this.softness * this.softness);
47193	        } else {
47194	            this.visible = false;
47195	            this.floor.visible = false;
47196	        }
47197	    }
47198	    getIntensity() {
47199	        return this.intensity;
47200	    }
47201	 setOffset(offset) {
47202	        this.floor.position.z = -offset + this.gap();
47203	    }
47204	    gap() {
47205	        return 0.001 * this.maxDimension;
47206	    }
47207	    render(renderer, scene) {
47208	        scene.overrideMaterial = this.depthMaterial;
47209	        const initialClearAlpha = renderer.getClearAlpha();
47210	        renderer.setClearAlpha(0);
47211	        this.floor.visible = false;
47212	        const xrEnabled = renderer.xr.enabled;
47213	        renderer.xr.enabled = false;
47214	        const oldRenderTarget = renderer.getRenderTarget();
47215	        renderer.setRenderTarget(this.renderTarget);
47216	        renderer.render(scene, this.camera);
47217	        scene.overrideMaterial = null;
47218	        this.floor.visible = true;
47219	        this.blurShadow(renderer);
47220	        renderer.xr.enabled = xrEnabled;
47221	        renderer.setRenderTarget(oldRenderTarget);
47222	        renderer.setClearAlpha(initialClearAlpha);
47223	    }
47224	    blurShadow(renderer) {
47225	        const { camera, horizontalBlurMaterial, verticalBlurMaterial, renderTarget, renderTargetBlur, blurPlane } = this;
47226	        blurPlane.visible = true;
47227	        blurPlane.material = horizontalBlurMaterial;
47228	        horizontalBlurMaterial.uniforms.h.value = 1 / this.renderTarget.width;
47229	        horizontalBlurMaterial.uniforms.tDiffuse.value = this.renderTarget.texture;
47230	        renderer.setRenderTarget(renderTargetBlur);
47231	        renderer.render(blurPlane, camera);
47232	        blurPlane.material = verticalBlurMaterial;
47233	        verticalBlurMaterial.uniforms.v.value = 1 / this.renderTarget.height;
47234	        verticalBlurMaterial.uniforms.tDiffuse.value = this.renderTargetBlur.texture;
47235	        renderer.setRenderTarget(renderTarget);
47236	        renderer.render(blurPlane, camera);
47237	        blurPlane.visible = false;
47238	    }
47239	    dispose() {
47240	        if (this.renderTarget != null) {
47241	            this.renderTarget.dispose();
47242	        }
47243	        if (this.renderTargetBlur != null) {
47244	            this.renderTargetBlur.dispose();
47245	        }
47246	        this.depthMaterial.dispose();
47247	        this.horizontalBlurMaterial.dispose();
47248	        this.verticalBlurMaterial.dispose();
47249	        this.floor.material.dispose();
47250	        this.floor.geometry.dispose();
47251	        this.blurPlane.geometry.dispose();
47252	        this.removeFromParent();
47253	    }
47254	    constructor(scene, softness, side){
47255	        super();
47256	        this.camera = new OrthographicCamera();
47257	        this.renderTarget = null;
47258	        this.renderTargetBlur = null;
47259	        this.depthMaterial = new MeshDepthMaterial();
47260	        this.horizontalBlurMaterial = new ShaderMaterial(HorizontalBlurShader);
47261	        this.verticalBlurMaterial = new ShaderMaterial(VerticalBlurShader);
47262	        this.intensity = 0;
47263	        this.softness = 1;
47264	        this.boundingBox = new Box3;
47265	        this.size = new Vector3;
47266	        this.maxDimension = 0;
47267	        this.isAnimated = false;
47268	        this.needsUpdate = false;
47269	        const { camera } = this;
47270	        camera.rotation.x = Math.PI / 2;
47271	        camera.left = -0.5;
47272	        camera.right = 0.5;
47273	        camera.bottom = -0.5;
47274	        camera.top = 0.5;
47275	        this.add(camera);
47276	        const plane = new PlaneGeometry();
47277	        const shadowMaterial = new MeshBasicMaterial({
47278	            opacity: 1,
47279	            transparent: true,
47280	            side: BackSide
47281	        });
47282	        this.floor = new Mesh(plane, shadowMaterial);
47283	        this.floor.userData.noHit = true;
47284	        camera.add(this.floor);
47285	        this.blurPlane = new Mesh(plane);
47286	        this.blurPlane.visible = false;
47287	        camera.add(this.blurPlane);
47288	        scene.target.add(this);
47289	        this.depthMaterial.onBeforeCompile = function(shader) {
47290	            shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );', 'gl_FragColor = vec4( vec3( 0.0 ), ( 1.0 - fragCoordZ ) * opacity );');
47291	        };
47292	        this.depthMaterial.side = DoubleSide;
47293	        this.horizontalBlurMaterial.depthTest = false;
47294	        this.verticalBlurMaterial.depthTest = false;
47295	        this.setScene(scene, softness, side);
47296	    }
47297	}
47298
47299	const GROUNDED_SKYBOX_SIZE = 10;
47300	const MIN_SHADOW_RATIO = 100;
47301	const view = new Vector3();
47302	const target = new Vector3();
47303	const normalWorld = new Vector3();
47304	const raycaster = new Raycaster();
47305	const vector3 = new Vector3();
47306	const ndc = new Vector2();
47307	 class ModelScene extends Scene {
47308	 get context() {
47309	        return this.canvas.getContext('2d');
47310	    }
47311	    getCamera() {
47312	        return this.xrCamera != null ? this.xrCamera : this.camera;
47313	    }
47314	    queueRender() {
47315	        this.isDirty = true;
47316	    }
47317	    shouldRender() {
47318	        return this.isDirty;
47319	    }
47320	    hasRendered() {
47321	        this.isDirty = false;
47322	    }
47323	    forceRescale() {
47324	        this.scaleStep = -1;
47325	        this.queueRender();
47326	    }
47327	 async setObject(model) {
47328	        this.reset();
47329	        this._model = model;
47330	        this.target.add(model);
47331	        await this.setupScene();
47332	    }
47333	 async setSource(url, progressCallback = ()=>{}) {
47334	        if (!url || url === this.url) {
47335	            progressCallback(1);
47336	            return;
47337	        }
47338	        this.reset();
47339	        this.url = url;
47340	        if (this.externalRenderer != null) {
47341	            const framingInfo = await this.externalRenderer.load(progressCallback);
47342	            this.boundingSphere.radius = framingInfo.framedRadius;
47343	            this.idealAspect = framingInfo.fieldOfViewAspect;
47344	            return;
47345	        }
47346	        if (this.cancelPendingSourceChange != null) {
47347	            this.cancelPendingSourceChange();
47348	            this.cancelPendingSourceChange = null;
47349	        }
47350	        let gltf;
47351	        try {
47352	            gltf = await new Promise(async (resolve, reject)=>{
47353	                this.cancelPendingSourceChange = ()=>reject();
47354	                try {
47355	                    const result = await this.element[$renderer].loader.load(url, this.element, progressCallback);
47356	                    resolve(result);
47357	                } catch (error) {
47358	                    reject(error);
47359	                }
47360	            });
47361	        } catch (error) {
47362	            if (error == null) {
47363	                return;
47364	            }
47365	            throw error;
47366	        }
47367	        this.cancelPendingSourceChange = null;
47368	        this.reset();
47369	        this.url = url;
47370	        this._currentGLTF = gltf;
47371	        if (gltf != null) {
47372	            this._model = gltf.scene;
47373	            this.target.add(gltf.scene);
47374	        }
47375	        const { animations } = gltf;
47376	        const animationsByName = new Map();
47377	        const animationNames = [];
47378	        for (const animation of animations){
47379	            animationsByName.set(animation.name, animation);
47380	            animationNames.push(animation.name);
47381	        }
47382	        this.animations = animations;
47383	        this.animationsByName = animationsByName;
47384	        this.animationNames = animationNames;
47385	        await this.setupScene();
47386	    }
47387	    async setupScene() {
47388	        this.applyTransform();
47389	        this.updateBoundingBox();
47390	        await this.updateFraming();
47391	        this.updateShadow();
47392	        this.setShadowIntensity(this.shadowIntensity);
47393	        this.setGroundedSkybox();
47394	    }
47395	    reset() {
47396	        this.url = null;
47397	        this.renderCount = 0;
47398	        this.queueRender();
47399	        if (this.shadow != null) {
47400	            this.shadow.setIntensity(0);
47401	        }
47402	        this.bakedShadows.clear();
47403	        const { _model } = this;
47404	        if (_model != null) {
47405	            _model.removeFromParent();
47406	            this._model = null;
47407	        }
47408	        const gltf = this._currentGLTF;
47409	        if (gltf != null) {
47410	            gltf.dispose();
47411	            this._currentGLTF = null;
47412	        }
47413	        if (this.currentAnimationAction != null) {
47414	            this.currentAnimationAction.stop();
47415	            this.currentAnimationAction = null;
47416	        }
47417	        this.mixer.stopAllAction();
47418	        this.mixer.uncacheRoot(this);
47419	    }
47420	    dispose() {
47421	        this.reset();
47422	        if (this.shadow != null) {
47423	            this.shadow.dispose();
47424	            this.shadow = null;
47425	        }
47426	        this.element[$currentGLTF] = null;
47427	        this.element[$originalGltfJson] = null;
47428	        this.element[$model] = null;
47429	    }
47430	    get currentGLTF() {
47431	        return this._currentGLTF;
47432	    }
47433	 setSize(width, height) {
47434	        if (this.width === width && this.height === height) {
47435	            return;
47436	        }
47437	        this.width = Math.max(width, 1);
47438	        this.height = Math.max(height, 1);
47439	        this.annotationRenderer.setSize(width, height);
47440	        this.aspect = this.width / this.height;
47441	        if (this.externalRenderer != null) {
47442	            const dpr = window.devicePixelRatio;
47443	            this.externalRenderer.resize(width * dpr, height * dpr);
47444	        }
47445	        this.queueRender();
47446	    }
47447	    markBakedShadow(mesh) {
47448	        mesh.userData.noHit = true;
47449	        this.bakedShadows.add(mesh);
47450	    }
47451	    unmarkBakedShadow(mesh) {
47452	        mesh.userData.noHit = false;
47453	        mesh.visible = true;
47454	        this.bakedShadows.delete(mesh);
47455	        this.boundingBox.expandByObject(mesh);
47456	    }
47457	    findBakedShadows(group) {
47458	        const boundingBox = new Box3();
47459	        group.traverse((object)=>{
47460	            const mesh = object;
47461	            if (!mesh.material) {
47462	                return;
47463	            }
47464	            const material = mesh.material;
47465	            if (!material.transparent) {
47466	                return;
47467	            }
47468	            boundingBox.setFromObject(mesh);
47469	            const size = boundingBox.getSize(vector3);
47470	            const minDim = Math.min(size.x, size.y, size.z);
47471	            const maxDim = Math.max(size.x, size.y, size.z);
47472	            if (maxDim < MIN_SHADOW_RATIO * minDim) {
47473	                return;
47474	            }
47475	            this.markBakedShadow(mesh);
47476	        });
47477	    }
47478	    checkBakedShadows() {
47479	        const { min, max } = this.boundingBox;
47480	        const shadowBox = new Box3();
47481	        this.boundingBox.getSize(this.size);
47482	        for (const mesh of this.bakedShadows){
47483	            shadowBox.setFromObject(mesh);
47484	            if (shadowBox.min.y < min.y + this.size.y / MIN_SHADOW_RATIO && shadowBox.min.x <= min.x && shadowBox.max.x >= max.x && shadowBox.min.z <= min.z && shadowBox.max.z >= max.z) {
47485	                continue;
47486	            }
47487	            if (shadowBox.min.z < min.z + this.size.z / MIN_SHADOW_RATIO && shadowBox.min.x <= min.x && shadowBox.max.x >= max.x && shadowBox.min.y <= min.y && shadowBox.max.y >= max.y) {
47488	                continue;
47489	            }
47490	            this.unmarkBakedShadow(mesh);
47491	        }
47492	    }
47493	    applyTransform() {
47494	        const { model } = this;
47495	        if (model == null) {
47496	            return;
47497	        }
47498	        const orientation = parseExpressions(this.element.orientation)[0].terms;
47499	        const roll = normalizeUnit(orientation[0]).number;
47500	        const pitch = normalizeUnit(orientation[1]).number;
47501	        const yaw = normalizeUnit(orientation[2]).number;
47502	        model.quaternion.setFromEuler(new Euler(pitch, yaw, roll, 'YXZ'));
47503	        const scale = parseExpressions(this.element.scale)[0].terms;
47504	        model.scale.set(scale[0].number, scale[1].number, scale[2].number);
47505	    }
47506	    updateBoundingBox() {
47507	        const { model } = this;
47508	        if (model == null) {
47509	            return;
47510	        }
47511	        this.target.remove(model);
47512	        this.findBakedShadows(model);
47513	        const bound = (box, vertex)=>{
47514	            return box.expandByPoint(vertex);
47515	        };
47516	        this.setBakedShadowVisibility(false);
47517	        this.boundingBox = reduceVertices(model, bound, new Box3());
47518	        if (this.boundingBox.isEmpty()) {
47519	            this.setBakedShadowVisibility(true);
47520	            this.bakedShadows.forEach((mesh)=>this.unmarkBakedShadow(mesh));
47521	            this.boundingBox = reduceVertices(model, bound, new Box3());
47522	        }
47523	        this.checkBakedShadows();
47524	        this.setBakedShadowVisibility();
47525	        this.boundingBox.getSize(this.size);
47526	        this.target.add(model);
47527	    }
47528	 async updateFraming() {
47529	        const { model } = this;
47530	        if (model == null) {
47531	            return;
47532	        }
47533	        this.target.remove(model);
47534	        this.setBakedShadowVisibility(false);
47535	        const { center } = this.boundingSphere;
47536	        this.element.requestUpdate('cameraTarget');
47537	        await this.element.updateComplete;
47538	        center.copy(this.getTarget());
47539	        const radiusSquared = (value, vertex)=>{
47540	            return Math.max(value, center.distanceToSquared(vertex));
47541	        };
47542	        this.boundingSphere.radius = Math.sqrt(reduceVertices(model, radiusSquared, 0));
47543	        const horizontalTanFov = (value, vertex)=>{
47544	            vertex.sub(center);
47545	            const radiusXZ = Math.sqrt(vertex.x * vertex.x + vertex.z * vertex.z);
47546	            return Math.max(value, radiusXZ / (this.idealCameraDistance() - Math.abs(vertex.y)));
47547	        };
47548	        this.idealAspect = reduceVertices(model, horizontalTanFov, 0) / Math.tan(this.framedFoVDeg / 2 * Math.PI / 180);
47549	        this.setBakedShadowVisibility();
47550	        this.target.add(model);
47551	    }
47552	    setBakedShadowVisibility(visible = this.shadowIntensity <= 0) {
47553	        for (const shadow of this.bakedShadows){
47554	            shadow.visible = visible;
47555	        }
47556	    }
47557	    idealCameraDistance() {
47558	        const halfFovRad = this.framedFoVDeg / 2 * Math.PI / 180;
47559	        return this.boundingSphere.radius / Math.sin(halfFovRad);
47560	    }
47561	 adjustedFoV(fovDeg) {
47562	        const vertical = Math.tan(fovDeg / 2 * Math.PI / 180) * Math.max(1, this.idealAspect / this.aspect);
47563	        return 2 * Math.atan(vertical) * 180 / Math.PI;
47564	    }
47565	    getNDC(clientX, clientY) {
47566	        if (this.xrCamera != null) {
47567	            ndc.set(clientX / window.screen.width, clientY / window.screen.height);
47568	        } else {
47569	            const rect = this.element.getBoundingClientRect();
47570	            ndc.set((clientX - rect.x) / this.width, (clientY - rect.y
47570) / this.height);
47571	        }
47572	        ndc.multiplyScalar(2).subScalar(1);
47573	        ndc.y *= -1;
47574	        return ndc;
47575	    }
47576	 getSize() {
47577	        return {
47578	            width: this.width,
47579	            height: this.height
47580	        };
47581	    }
47582	    setEnvironmentAndSkybox(environment, skybox) {
47583	        if (this.element[$renderer].arRenderer.presentedScene === this) {
47584	            return;
47585	        }
47586	        this.environment = environment;
47587	        this.setBackground(skybox);
47588	        this.queueRender();
47589	    }
47590	    setBackground(skybox) {
47591	        this.groundedSkybox.map = skybox;
47592	        if (this.groundedSkybox.isUsable()) {
47593	            this.target.add(this.groundedSkybox);
47594	            this.background = null;
47595	        } else {
47596	            this.target.remove(this.groundedSkybox);
47597	            this.background = skybox;
47598	        }
47599	    }
47600	    farRadius() {
47601	        return this.boundingSphere.radius * (this.groundedSkybox.parent != null ? GROUNDED_SKYBOX_SIZE : 1);
47602	    }
47603	    setGroundedSkybox() {
47604	        const heightNode = parseExpressions(this.element.skyboxHeight)[0].terms[0];
47605	        const height = normalizeUnit(heightNode).number;
47606	        const radius = GROUNDED_SKYBOX_SIZE * this.boundingSphere.radius;
47607	        this.groundedSkybox.updateGeometry(height, radius);
47608	        this.groundedSkybox.position.y = height - (this.shadow ? 2 * this.shadow.gap() : 0);
47609	        this.setBackground(this.groundedSkybox.map);
47610	    }
47611	 setTarget(modelX, modelY, modelZ) {
47612	        this.goalTarget.set(-modelX, -modelY, -modelZ);
47613	    }
47614	 setTargetDamperDecayTime(decayMilliseconds) {
47615	        this.targetDamperX.setDecayTime(decayMilliseconds);
47616	        this.targetDamperY.setDecayTime(decayMilliseconds);
47617	        this.targetDamperZ.setDecayTime(decayMilliseconds);
47618	    }
47619	 getTarget() {
47620	        return this.goalTarget.clone().multiplyScalar(-1);
47621	    }
47622	 getDynamicTarget() {
47623	        return this.target.position.clone().multiplyScalar(-1);
47624	    }
47625	 jumpToGoal() {
47626	        this.updateTarget(SETTLING_TIME);
47627	    }
47628	 updateTarget(delta) {
47629	        const goal = this.goalTarget;
47630	        const target = this.target.position;
47631	        if (!goal.equals(target)) {
47632	            const normalization = this.boundingSphere.radius / 10;
47633	            let { x, y, z } = target;
47634	            x = this.targetDamperX.update(x, goal.x, delta, normalization);
47635	            y = this.targetDamperY.update(y, goal.y, delta, normalization);
47636	            z = this.targetDamperZ.update(z, goal.z, delta, normalization);
47637	            this.groundedSkybox.position.x = -x;
47638	            this.groundedSkybox.position.z = -z;
47639	            this.target.position.set(x, y, z);
47640	            this.target.updateMatrixWorld();
47641	            this.queueRender();
47642	            return true;
47643	        } else {
47644	            return false;
47645	        }
47646	    }
47647	 pointTowards(worldX, worldZ) {
47648	        const { x, z } = this.position;
47649	        this.yaw = Math.atan2(worldX - x, worldZ - z);
47650	    }
47651	    get model() {
47652	        return this._model;
47653	    }
47654	 set yaw(radiansY) {
47655	        this.pivot.rotation.y = radiansY;
47656	        this.groundedSkybox.rotation.y = -radiansY;
47657	        this.queueRender();
47658	    }
47659	    get yaw() {
47660	        return this.pivot.rotation.y;
47661	    }
47662	    set animationTime(value) {
47663	        this.mixer.setTime(value);
47664	        this.queueShadowRender();
47665	    }
47666	    get animationTime() {
47667	        if (this.currentAnimationAction != null) {
47668	            const loopCount = Math.max(this.currentAnimationAction._loopCount, 0);
47669	            if (this.currentAnimationAction.loop === LoopPingPong && (loopCount & 1) === 1) {
47670	                return this.duration - this.currentAnimationAction.time;
47671	            } else {
47672	                return this.currentAnimationAction.time;
47673	            }
47674	        }
47675	        return 0;
47676	    }
47677	    set animationTimeScale(value) {
47678	        this.mixer.timeScale = value;
47679	    }
47680	    get animationTimeScale() {
47681	        return this.mixer.timeScale;
47682	    }
47683	    get duration() {
47684	        if (this.currentAnimationAction != null && this.currentAnimationAction.getClip()) {
47685	            return this.currentAnimationAction.getClip().duration;
47686	        }
47687	        return 0;
47688	    }
47689	    get hasActiveAnimation() {
47690	        return this.currentAnimationAction != null;
47691	    }
47692	 playAnimation(name = null, crossfadeTime = 0, loopMode = LoopRepeat, repetitionCount = Infinity) {
47693	        if (this._currentGLTF == null) {
47694	            return;
47695	        }
47696	        const { animations } = this;
47697	        if (animations == null || animations.length === 0) {
47698	            return;
47699	        }
47700	        let animationClip = null;
47701	        if (name != null) {
47702	            animationClip = this.animationsByName.get(name);
47703	            if (animationClip == null) {
47704	                const parsedAnimationIndex = parseInt(name);
47705	                if (!isNaN(parsedAnimationIndex) && parsedAnimationIndex >= 0 && parsedAnimationIndex < animations.length) {
47706	                    animationClip = animations[parsedAnimationIndex];
47707	                }
47708	            }
47709	        }
47710	        if (animationClip == null) {
47711	            animationClip = animations[0];
47712	        }
47713	        try {
47714	            const { currentAnimationAction: lastAnimationAction } = this;
47715	            const action = this.mixer.clipAction(animationClip, this);
47716	            if (action.timeScale != this.element.timeScale) {
47717	                action.timeScale = this.element.timeScale;
47718	            }
47719	            this.currentAnimationAction = action;
47720	            if (this.element.paused) {
47721	                this.mixer.stopAllAction();
47722	            } else {
47723	                action.paused = false;
47724	                if (lastAnimationAction != null && action !== lastAnimationAction) {
47725	                    action.crossFadeFrom(lastAnimationAction, crossfadeTime, false);
47726	                } else if (this.animationTimeScale > 0 && this.animationTime == this.duration) {
47727	                    this.animationTime = 0;
47728	                }
47729	            }
47730	            action.setLoop(loopMode, repetitionCount);
47731	            action.enabled = true;
47732	            action.clampWhenFinished = true;
47733	            action.play();
47734	        } catch (error) {
47735	            console.error(error);
47736	        }
47737	    }
47738	    appendAnimation(name = '', loopMode = LoopRepeat, repetitionCount = Infinity, weight = 1, timeScale = 1, fade = false, warp = false, relativeWarp = true, time = null, needsToStop = false) {
47739	        if (this._currentGLTF == null || name === this.element.animationName) {
47740	            return;
47741	        }
47742	        const { animations } = this;
47743	        if (animations == null || animations.length === 0) {
47744	            return;
47745	        }
47746	        let animationClip = null;
47747	        const defaultFade = 1.25;
47748	        if (name) {
47749	            animationClip = this.animationsByName.get(name);
47750	        }
47751	        if (animationClip == null) {
47752	            return;
47753	        }
47754	        if (typeof repetitionCount === 'string') {
47755	            if (!isNaN(repetitionCount)) {
47756	                repetitionCount = Math.max(parseInt(repetitionCount), 1);
47757	            } else {
47758	                repetitionCount = Infinity;
47759	                console.warn('Invalid repetitionCount value, repetitionCount is set to Infinity');
47760	            }
47761	        } else if (typeof repetitionCount === 'number' && repetitionCount < 1) {
47762	            repetitionCount = 1;
47763	        }
47764	        if (repetitionCount === 1 && loopMode !== LoopOnce) {
47765	            loopMode = LoopOnce;
47766	        }
47767	        if (typeof weight === 'string') {
47768	            if (!isNaN(weight)) {
47769	                weight = parseFloat(weight);
47770	            } else {
47771	                weight = 1;
47772	                console.warn('Invalid weight value, weight is set to 1');
47773	            }
47774	        }
47775	        if (typeof timeScale === 'string') {
47776	            if (!isNaN(timeScale)) {
47777	                timeScale = parseFloat(timeScale);
47778	            } else {
47779	                timeScale = 1;
47780	                console.warn('Invalid timeScale value, timeScale is set to 1');
47781	            }
47782	        }
47783	        if (typeof fade === 'string') {
47784	            if (fade.toLowerCase().trim() === 'true') {
47785	                fade = true;
47786	            } else if (fade.toLowerCase().trim() === 'false') {
47787	                fade = false;
47788	            } else if (!isNaN(fade)) {
47789	                fade = parseFloat(fade);
47790	            } else {
47791	                fade = false;
47792	                console.warn('Invalid fade value, fade is set to false');
47793	            }
47794	        }
47795	        if (typeof warp === 'string') {
47796	            if (warp.toLowerCase().trim() === 'true') {
47797	                warp = true;
47798	            } else if (warp.toLowerCase().trim() === 'false') {
47799	                warp = false;
47800	            } else if (!isNaN(warp)) {
47801	                warp = parseFloat(warp);
47802	            } else {
47803	                warp = false;
47804	                console.warn('Invalid warp value, warp is set to false');
47805	            }
47806	        }
47807	        if (typeof time === 'string') {
47808	            if (!isNaN(time)) {
47809	                time = parseFloat(time);
47810	            }
47811	        }
47812	        try {
47813	            const action = this.mixer.existingAction(animationClip) || this.mixer.clipAction(animationClip, this);
47814	            const currentTimeScale = action.timeScale;
47815	            if (needsToStop && this.appendedAnimations.includes(name)) {
47816	                if (!this.markedAnimations.map((e)=>e.name).includes(name)) {
47817	                    this.markedAnimations.push({
47818	                        name,
47819	                        loopMode,
47820	                        repetitionCount
47821	                    });
47822	                }
47823	            }
47824	            if (typeof time === 'number') {
47825	                action.time = Math.min(Math.max(time, 0), animationClip.duration);
47826	            }
47827	            if (typeof fade === 'boolean' && fade) {
47828	                action.fadeIn(defaultFade);
47829	            } else if (typeof fade === 'number') {
47830	                action.fadeIn(Math.max(fade, 0));
47831	            } else {
47832	                if (weight >= 0) {
47833	                    action.weight = Math.min(Math.max(weight, 0), 1);
47834	                }
47835	            }
47836	            if (typeof warp === 'boolean' && warp) {
47837	                action.warp(relativeWarp ? currentTimeScale : 0, timeScale, defaultFade);
47838	            } else if (typeof warp === 'number') {
47839	                action.warp(relativeWarp ? currentTimeScale : 0, timeScale, Math.max(warp, 0));
47840	            } else {
47841	                action.timeScale = timeScale;
47842	            }
47843	            if (!action.isRunning()) {
47844	                if (action.time == animationClip.duration) {
47845	                    action.stop();
47846	                }
47847	                action.setLoop(loopMode, repetitionCount);
47848	                action.paused = false;
47849	                action.enabled = true;
47850	                action.clampWhenFinished = true;
47851	                action.play();
47852	            }
47853	            if (!this.appendedAnimations.includes(name)) {
47854	                this.element[$scene].appendedAnimations.push(name);
47855	            }
47856	        } catch (error) {
47857	            console.error(error);
47858	        }
47859	    }
47860	    detachAnimation(name = '', fade = true) {
47861	        if (this._currentGLTF == null || name === this.element.animationName) {
47862	            return;
47863	        }
47864	        const { animations } = this;
47865	        if (animations == null || animations.length === 0) {
47866	            return;
47867	        }
47868	        let animationClip = null;
47869	        const defaultFade = 1.5;
47870	        if (name) {
47871	            animationClip = this.animationsByName.get(name);
47872	        }
47873	        if (animationClip == null) {
47874	            return;
47875	        }
47876	        if (typeof fade === 'string') {
47877	            if (fade.toLowerCase().trim() === 'true') {
47878	                fade = true;
47879	            } else if (fade.toLowerCase().trim() === 'false') {
47880	                fade = false;
47881	            } else if (!isNaN(fade)) {
47882	                fade = parseFloat(fade);
47883	            } else {
47884	                fade = true;
47885	                console.warn('Invalid fade value, fade is set to true');
47886	            }
47887	        }
47888	        try {
47889	            const action = this.mixer.existingAction(animationClip) || this.mixer.clipAction(animationClip, this);
47890	            if (typeof fade === 'boolean' && fade) {
47891	                action.fadeOut(defaultFade);
47892	            } else if (typeof fade === 'number') {
47893	                action.fadeOut(Math.max(fade, 0));
47894	            } else {
47895	                action.stop();
47896	            }
47897	            const result = this.element[$scene].appendedAnimations.filter((i)=>i !== name);
47898	            this.element[$scene].appendedAnimations = result;
47899	        } catch (error) {
47900	            console.error(error);
47901	        }
47902	    }
47903	    updateAnimationLoop(name = '', loopMode = LoopRepeat, repetitionCount = Infinity) {
47904	        if (this._currentGLTF == null || name === this.element.animationName) {
47905	            return;
47906	        }
47907	        const { animations } = this;
47908	        if (animations == null || animations.length === 0) {
47909	            return;
47910	        }
47911	        let animationClip = null;
47912	        if (name) {
47913	            animationClip = this.animationsByName.get(name);
47914	        }
47915	        if (animationClip == null) {
47916	            return;
47917	        }
47918	        try {
47919	            const action = this.mixer.existingAction(animationClip) || this.mixer.clipAction(animationClip, this);
47920	            action.stop();
47921	            action.setLoop(loopMode, repetitionCount);
47922	            action.play();
47923	        } catch (error) {
47924	            console.error(error);
47925	        }
47926	    }
47927	    stopAnimation() {
47928	        this.currentAnimationAction = null;
47929	        this.mixer.stopAllAction();
47930	    }
47931	    updateAnimation(step) {
47932	        this.mixer.update(step);
47933	        this.queueShadowRender();
47934	    }
47935	    subscribeMixerEvent(event, callback) {
47936	        this.mixer.addEventListener(event, callback);
47937	    }
47938	 updateShadow() {
47939	        const shadow = this.shadow;
47940	        if (shadow != null) {
47941	            const side = this.element.arPlacement === 'wall' ? 'back' : 'bottom';
47942	            shadow.setScene(this, this.shadowSoftness, side);
47943	            shadow.needsUpdate = true;
47944	        }
47945	    }
47946	    renderShadow(renderer) {
47947	        const shadow = this.shadow;
47948	        if (shadow != null && shadow.needsUpdate == true) {
47949	            shadow.render(renderer, this);
47950	            shadow.needsUpdate = false;
47951	        }
47952	    }
47953	    queueShadowRender() {
47954	        if (this.shadow != null) {
47955	            this.shadow.needsUpdate = true;
47956	        }
47957	    }
47958	 setShadowIntensity(shadowIntensity) {
47959	        this.shadowIntensity = shadowIntensity;
47960	        if (this._currentGLTF == null) {
47961	            return;
47962	        }
47963	        this.setBakedShadowVisibility();
47964	        if (shadowIntensity <= 0 && this.shadow == null) {
47965	            return;
47966	        }
47967	        if (this.shadow == null) {
47968	            const side = this.element.arPlacement === 'wall' ? 'back' : 'bottom';
47969	            this.shadow = new Shadow(this, this.shadowSoftness, side);
47970	        }
47971	        this.shadow.setIntensity(shadowIntensity);
47972	    }
47973	 setShadowSoftness(softness) {
47974	        this.shadowSoftness = softness;
47975	        const shadow = this.shadow;
47976	        if (shadow != null) {
47977	            shadow.setSoftness(softness);
47978	        }
47979	    }
47980	 setShadowOffset(offset) {
47981	        const shadow = this.shadow;
47982	        if (shadow != null) {
47983	            shadow.setOffset(offset);
47984	        }
47985	    }
47986	    getHit(object = this) {
47987	        const hits = raycaster.intersectObject(object, true);
47988	        return hits.find((hit)=>hit.object.visible && !hit.object.userData.noHit);
47989	    }
47990	    hitFromController(controller, object = this) {
47991	        raycaster.setFromXRController(controller);
47992	        return this.getHit(object);
47993	    }
47994	    hitFromPoint(ndcPosition, object = this) {
47995	        raycaster.setFromCamera(ndcPosition, this.getCamera());
47996	        return this.getHit(object);
47997	    }
47998	 positionAndNormalFromPoint(ndcPosition, object = this) {
47999	        var _a;
48000	        const hit = this.hitFromPoint(ndcPosition, object);
48001	        if (hit == null) {
48002	            return null;
48003	        }
48004	        const position = hit.point;
48005	        const normal = hit.face != null ? hit.face.normal.clone().applyNormalMatrix(new Matrix3().getNormalMatrix(hit.object.matrixWorld)) : raycaster.ray.direction.clone().multiplyScalar(-1);
48006	        const uv = (_a = hit.uv) !== null && _a !== void 0 ? _a : null;
48007	        return {
48008	            position,
48009	            normal,
48010	            uv
48011	        };
48012	    }
48013	 surfaceFromPoint(ndcPosition, object = this) {
48014	        const model = this.element.model;
48015	        if (model == null) {
48016	            return null;
48017	        }
48018	        const hit = this.hitFromPoint(ndcPosition, object);
48019	        if (hit == null || hit.face == null) {
48020	            return null;
48021	        }
vendor: 9,449 bytes, lines 48022-48263
48022	        const node = model[$nodeFromPoint](hit);
48023	        const { meshes, primitives } = node.mesh.userData.associations;
48024	        const va = new Vector3();
48025	        const vb = new Vector3();
48026	        const vc = new Vector3();
48027	        const { a, b, c } = hit.face;
48028	        const mesh = hit.object;
48029	        mesh.getVertexPosition(a, va);
48030	        mesh.getVertexPosition(b, vb);
48031	        mesh.getVertexPosition(c, vc);
48032	        const tri = new Triangle(va, vb, vc);
48033	        const uvw = new Vector3();
48034	        tri.getBarycoord(mesh.worldToLocal(hit.point), uvw);
48035	        return `${meshes} ${primitives} ${a} ${b} ${c} ${uvw.x.toFixed(3)} ${uvw.y.toFixed(3)} ${uvw.z.toFixed(3)}`;
48036	    }
48037	 addHotspot(hotspot) {
48038	        this.target.add(hotspot);
48039	        this.annotationRenderer.domElement.appendChild(hotspot.element);
48040	        this.updateSurfaceHotspot(hotspot);
48041	    }
48042	    removeHotspot(hotspot) {
48043	        this.target.remove(hotspot);
48044	    }
48045	 forHotspots(func) {
48046	        const { children } = this.target;
48047	        for(let i = 0, l = children.length; i < l; i++){
48048	            const hotspot = children[i];
48049	            if (hotspot instanceof Hotspot) {
48050	                func(hotspot);
48051	            }
48052	        }
48053	    }
48054	 updateSurfaceHotspot(hotspot) {
48055	        if (hotspot.surface == null || this.element.model == null) {
48056	            return;
48057	        }
48058	        const nodes = parseExpressions(hotspot.surface)[0].terms;
48059	        if (nodes.length != 8) {
48060	            console.warn(hotspot.surface + ' does not have exactly 8 numbers.');
48061	            return;
48062	        }
48063	        const primitiveNode = this.element.model[$nodeFromIndex](nodes[0].number, nodes[1].number);
48064	        if (primitiveNode == null) {
48065	            console.warn(hotspot.surface + ' does not match a node/primitive in this glTF! Skipping this hotspot.');
48066	            return;
48067	        }
48068	        const numVert = primitiveNode.mesh.geometry.attributes.position.count;
48069	        const tri = new Vector3(nodes[2].number, nodes[3].number, nodes[4].number);
48070	        if (tri.x >= numVert || tri.y >= numVert || tri.z >= numVert) {
48071	            console.warn(hotspot.surface + ' vertex indices out of range in this glTF! Skipping this hotspot.');
48072	            return;
48073	        }
48074	        const bary = new Vector3(nodes[5].number, nodes[6].number, nodes[7].number);
48075	        hotspot.mesh = primitiveNode.mesh;
48076	        hotspot.tri = tri;
48077	        hotspot.bary = bary;
48078	        hotspot.updateSurface();
48079	    }
48080	 animateSurfaceHotspots() {
48081	        if (this.element.paused) {
48082	            return;
48083	        }
48084	        this.forHotspots((hotspot)=>{
48085	            hotspot.updateSurface();
48086	        });
48087	    }
48088	 updateHotspotsVisibility(viewerPosition) {
48089	        this.forHotspots((hotspot)=>{
48090	            view.copy(viewerPosition);
48091	            target.setFromMatrixPosition(hotspot.matrixWorld);
48092	            view.sub(target);
48093	            normalWorld.copy(hotspot.normal).transformDirection(this.target.matrixWorld);
48094	            if (view.dot(normalWorld) < 0) {
48095	                hotspot.hide();
48096	            } else {
48097	                hotspot.show();
48098	            }
48099	        });
48100	    }
48101	 orientHotspots(radians) {
48102	        this.forHotspots((hotspot)=>{
48103	            hotspot.orient(radians);
48104	        });
48105	    }
48106	 setHotspotsVisibility(visible) {
48107	        this.forHotspots((hotspot)=>{
48108	            hotspot.visible = visible;
48109	        });
48110	    }
48111	    updateSchema(src) {
48112	        var _a;
48113	        const { schemaElement, element } = this;
48114	        const { alt, poster, iosSrc } = element;
48115	        if (src != null) {
48116	            const encoding = [
48117	                {
48118	                    '@type': 'MediaObject',
48119	                    contentUrl: src,
48120	                    encodingFormat: ((_a = src.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'gltf' ? 'model/gltf+json' : 'model/gltf-binary'
48121	                }
48122	            ];
48123	            if (iosSrc) {
48124	                encoding.push({
48125	                    '@type': 'MediaObject',
48126	                    contentUrl: iosSrc,
48127	                    encodingFormat: 'model/vnd.usdz+zip'
48128	                });
48129	            }
48130	            const structuredData = {
48131	                '@context': 'http://schema.org/',
48132	                '@type': '3DModel',
48133	                image: poster !== null && poster !== void 0 ? poster : undefined,
48134	                name: alt !== null && alt !== void 0 ? alt : undefined,
48135	                encoding
48136	            };
48137	            schemaElement.textContent = JSON.stringify(structuredData);
48138	            document.head.appendChild(schemaElement);
48139	        } else if (schemaElement.parentElement != null) {
48140	            schemaElement.parentElement.removeChild(schemaElement);
48141	        }
48142	    }
48143	    constructor({ canvas, element, width, height }){
48144	        super();
48145	        this.annotationRenderer = new CSS2DRenderer();
48146	        this.effectRenderer = null;
48147	        this.schemaElement = document.createElement('script');
48148	        this.width = 1;
48149	        this.height = 1;
48150	        this.aspect = 1;
48151	        this.scaleStep = 0;
48152	        this.renderCount = 0;
48153	        this.externalRenderer = null;
48154	        this.appendedAnimations = [];
48155	        this.markedAnimations = [];
48156	        this.camera = new PerspectiveCamera(45, 1, 0.1, 100);
48157	        this.xrCamera = null;
48158	        this.url = null;
48159	        this.pivot = new Object3D();
48160	        this.target = new Object3D();
48161	        this.animationNames = [];
48162	        this.boundingBox = new Box3();
48163	        this.boundingSphere = new Sphere();
48164	        this.size = new Vector3();
48165	        this.idealAspect = 0;
48166	        this.framedFoVDeg = 0;
48167	        this.shadow = null;
48168	        this.shadowIntensity = 0;
48169	        this.shadowSoftness = 1;
48170	        this.bakedShadows = new Set();
48171	        this.exposure = 1;
48172	        this.toneMapping = NeutralToneMapping;
48173	        this.canScale = true;
48174	        this.isDirty = false;
48175	        this.goalTarget = new Vector3();
48176	        this.targetDamperX = new Damper();
48177	        this.targetDamperY = new Damper();
48178	        this.targetDamperZ = new Damper();
48179	        this._currentGLTF = null;
48180	        this._model = null;
48181	        this.cancelPendingSourceChange = null;
48182	        this.animationsByName = new Map();
48183	        this.currentAnimationAction = null;
48184	        this.groundedSkybox = new GroundedSkybox();
48185	        this.name = 'ModelScene';
48186	        this.element = element;
48187	        this.canvas = canvas;
48188	        this.camera = new PerspectiveCamera(45, 1, 0.1, 100);
48189	        this.camera.name = 'MainCamera';
48190	        this.add(this.pivot);
48191	        this.pivot.name = 'Pivot';
48192	        this.pivot.add(this.target);
48193	        this.setSize(width, height);
48194	        this.target.name = 'Target';
48195	        this.mixer = new AnimationMixer(this.target);
48196	        const { domElement } = this.annotationRenderer;
48197	        const { style } = domElement;
48198	        style.display = 'none';
48199	        style.pointerEvents = 'none';
48200	        style.position = 'absolute';
48201	        style.top = '0';
48202	        this.element.shadowRoot.querySelector('.default').appendChild(domElement);
48203	        this.schemaElement.setAttribute('type', 'application/ld+json');
48204	    }
48205	}
48206
48207	class ProgressTracker extends EventTarget {
48208	 get ongoingActivityCount() {
48209	        return this.ongoingActivities.size;
48210	    }
48211	 beginActivity(reason) {
48212	        const activity = {
48213	            progress: 0,
48214	            completed: false
48215	        };
48216	        this.ongoingActivities.add(activity);
48217	        if (this.ongoingActivityCount === 1) {
48218	            this.announceTotalProgress(activity, 0, reason);
48219	        }
48220	        return (progress)=>{
48221	            let nextProgress;
48222	            nextProgress = Math.max(clamp(progress, 0, 1), activity.progress);
48223	            if (nextProgress !== activity.progress) {
48224	                this.announceTotalProgress(activity, nextProgress, reason);
48225	            }
48226	            return activity.progress;
48227	        };
48228	    }
48229	    announceTotalProgress(updatedActivity, nextProgress, reason) {
48230	        let progressLeft = 0;
48231	        let completedActivities = 0;
48232	        if (nextProgress == 1.0) updatedActivity.completed = true;
48233	        for (const activity of this.ongoingActivities){
48234	            const { progress } = activity;
48235	            progressLeft += 1.0 - progress;
48236	            if (activity.completed) {
48237	                completedActivities++;
48238	            }
48239	        }
48240	        const lastProgress = updatedActivity.progress;
48241	        updatedActivity.progress = nextProgress;
48242	        this.totalProgress += (nextProgress - lastProgress) * (1.0 - this.totalProgress) / progressLeft;
48243	        const totalProgress = completedActivities === this.ongoingActivityCount ? 1.0 : this.totalProgress;
48244	        this.dispatchEvent(new CustomEvent('progress', {
48245	            detail: {
48246	                totalProgress,
48247	                reason
48248	            }
48249	        }));
48250	        if (completedActivities === this.ongoingActivityCount) {
48251	            this.totalProgress = 0.0;
48252	            this.ongoingActivities.clear();
48253	        }
48254	    }
48255	    constructor(){
48256	        super(...arguments);
48257	        this.ongoingActivities = new Set();
48258	        this.totalProgress = 0;
48259	    }
48260	}
48261
48262	var __decorate$4 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
48263	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
vendor: 10,572 bytes, lines 48264-48533
48264	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
48265	    return c > 3 && r && Object.defineProperty(target, key, r), r;
48266	};
48267	var _a$1, _b$1, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
48268	const CLEAR_MODEL_TIMEOUT_MS = 10;
48269	const FALLBACK_SIZE_UPDATE_THRESHOLD_MS = 50;
48270	const ANNOUNCE_MODEL_VISIBILITY_DEBOUNCE_THRESHOLD = 0;
48271	const UNSIZED_MEDIA_WIDTH = 300;
48272	const UNSIZED_MEDIA_HEIGHT = 150;
48273	const blobCanvas = document.createElement('canvas');
48274	const $fallbackResizeHandler = Symbol('fallbackResizeHandler');
48275	const $defaultAriaLabel = Symbol('defaultAriaLabel');
48276	const $resizeObserver = Symbol('resizeObserver');
48277	const $clearModelTimeout = Symbol('clearModelTimeout');
48278	const $onContextLost = Symbol('onContextLost');
48279	const $loaded = Symbol('loaded');
48280	const $status = Symbol('status');
48281	const $onFocus = Symbol('onFocus');
48282	const $onBlur = Symbol('onBlur');
48283	const $updateSize = Symbol('updateSize');
48284	const $intersectionObserver = Symbol('intersectionObserver');
48285	const $isElementInViewport = Symbol('isElementInViewport');
48286	const $announceModelVisibility = Symbol('announceModelVisibility');
48287	const $ariaLabel = Symbol('ariaLabel');
48288	const $altDefaulted = Symbol('altDefaulted');
48289	const $statusElement = Symbol('statusElement');
48290	const $updateStatus = Symbol('updateStatus');
48291	const $loadedTime = Symbol('loadedTime');
48292	const $updateSource = Symbol('updateSource');
48293	const $markLoaded = Symbol('markLoaded');
48294	const $container = Symbol('container');
48295	const $userInputElement = Symbol('input');
48296	const $canvas = Symbol('canvas');
48297	const $scene = Symbol('scene');
48298	const $needsRender = Symbol('needsRender');
48299	const $tick = Symbol('tick');
48300	const $onModelLoad = Symbol('onModelLoad');
48301	const $onResize = Symbol('onResize');
48302	const $renderer = Symbol('renderer');
48303	const $progressTracker = Symbol('progressTracker');
48304	const $getLoaded = Symbol('getLoaded');
48305	const $getModelIsVisible = Symbol('getModelIsVisible');
48306	const $shouldAttemptPreload = Symbol('shouldAttemptPreload');
48307	const toVector3D = (v)=>{
48308	    return {
48309	        x: v.x,
48310	        y: v.y,
48311	        z: v.z,
48312	        toString () {
48313	            return `${this.x}m ${this.y}m ${this.z}m`;
48314	        }
48315	    };
48316	};
48317	const toVector2D = (v)=>{
48318	    return {
48319	        u: v.x,
48320	        v: v.y,
48321	        toString () {
48322	            return `${this.u} ${this.v}`;
48323	        }
48324	    };
48325	};
48326	class ModelViewerElementBase extends b$1 {
48327	    static get is() {
48328	        return 'model-viewer';
48329	    }
48330	     static set modelCacheSize(value) {
48331	        CachingGLTFLoader[$evictionPolicy].evictionThreshold = value;
48332	    }
48333	     static get modelCacheSize() {
48334	        return CachingGLTFLoader[$evictionPolicy].evictionThreshold;
48335	    }
48336	     static set minimumRenderScale(value) {
48337	        if (value > 1) {
48338	            console.warn('<model-viewer> minimumRenderScale has been clamped to a maximum value of 1.');
48339	        }
48340	        if (value <= 0) {
48341	            console.warn('<model-viewer> minimumRenderScale has been clamped to a minimum value of 0.25.');
48342	        }
48343	        Renderer.singleton.minScale = value;
48344	    }
48345	     static get minimumRenderScale() {
48346	        return Renderer.singleton.minScale;
48347	    }
48348	     get loaded() {
48349	        return this[$getLoaded]();
48350	    }
48351	    get [(_a$1 = $isElementInViewport, _b$1 = $loaded, _c = $loadedTime, _d = $status, _e = $clearModelTimeout, _f = $fallbackResizeHandler, _g = $announceModelVisibility, _h = $resizeObserver, _j = $intersectionObserver, _k = $progressTracker, $renderer)]() {
48352	        return Renderer.singleton;
48353	    }
48354	     get modelIsVisible() {
48355	        return this[$getModelIsVisible]();
48356	    }
48357	    connectedCallback() {
48358	        super.connectedCallback && super.connectedCallback();
48359	        if (HAS_RESIZE_OBSERVER) {
48360	            this[$resizeObserver].observe(this);
48361	        } else {
48362	            self.addEventListener('resize', this[$fallbackResizeHandler]);
48363	        }
48364	        if (HAS_INTERSECTION_OBSERVER) {
48365	            this[$intersectionObserver].observe(this);
48366	        }
48367	        this.addEventListener('focus', this[$onFocus]);
48368	        this.addEventListener('blur', this[$onBlur]);
48369	        const renderer = this[$renderer];
48370	        renderer.addEventListener('contextlost', this[$onContextLost]);
48371	        renderer.registerScene(this[$scene]);
48372	        if (this[$clearModelTimeout] != null) {
48373	            self.clearTimeout(this[$clearModelTimeout]);
48374	            this[$clearModelTimeout] = null;
48375	            this.requestUpdate('src', null);
48376	        }
48377	    }
48378	    disconnectedCallback() {
48379	        super.disconnectedCallback && super.disconnectedCallback();
48380	        if (HAS_RESIZE_OBSERVER) {
48381	            this[$resizeObserver].unobserve(this);
48382	        } else {
48383	            self.removeEventListener('resize', this[$fallbackResizeHandler]);
48384	        }
48385	        if (HAS_INTERSECTION_OBSERVER) {
48386	            this[$intersectionObserver].unobserve(this);
48387	        }
48388	        this.removeEventListener('focus', this[$onFocus]);
48389	        this.removeEventListener('blur', this[$onBlur]);
48390	        const renderer = this[$renderer];
48391	        renderer.removeEventListener('contextlost', this[$onContextLost]);
48392	        renderer.unregisterScene(this[$scene]);
48393	        this[$clearModelTimeout] = self.setTimeout(()=>{
48394	            this[$scene].dispose();
48395	            this[$clearModelTimeout] = null;
48396	        }, CLEAR_MODEL_TIMEOUT_MS);
48397	    }
48398	    updated(changedProperties) {
48399	        super.updated(changedProperties);
48400	        if (changedProperties.has('src')) {
48401	            if (this.src == null) {
48402	                this[$loaded] = false;
48403	                this[$loadedTime] = 0;
48404	                this[$scene].reset();
48405	            } else if (this.src !== this[$scene].url) {
48406	                this[$loaded] = false;
48407	                this[$loadedTime] = 0;
48408	                this[$updateSource]();
48409	            }
48410	        }
48411	        if (changedProperties.has('alt')) {
48412	            this[$userInputElement].setAttribute('aria-label', this[$ariaLabel]);
48413	        }
48414	        if (changedProperties.has('generateSchema')) {
48415	            if (this.generateSchema) {
48416	                this[$scene].updateSchema(this.src);
48417	            } else {
48418	                this[$scene].updateSchema(null);
48419	            }
48420	        }
48421	    }
48422	     toDataURL(type, encoderOptions) {
48423	        return this[$renderer].displayCanvas(this[$scene]).toDataURL(type, encoderOptions);
48424	    }
48425	     async toBlob(options) {
48426	        const mimeType = options ? options.mimeType : undefined;
48427	        const qualityArgument = options ? options.qualityArgument : undefined;
48428	        const useIdealAspect = options ? options.idealAspect : undefined;
48429	        const { width, height, idealAspect, aspect } = this[$scene];
48430	        const { dpr, scaleFactor } = this[$renderer];
48431	        let outputWidth = width * scaleFactor * dpr;
48432	        let outputHeight = height * scaleFactor * dpr;
48433	        let offsetX = 0;
48434	        let offsetY = 0;
48435	        if (useIdealAspect === true) {
48436	            if (idealAspect > aspect) {
48437	                const oldHeight = outputHeight;
48438	                outputHeight = Math.round(outputWidth / idealAspect);
48439	                offsetY = (oldHeight - outputHeight) / 2;
48440	            } else {
48441	                const oldWidth = outputWidth;
48442	                outputWidth = Math.round(outputHeight * idealAspect);
48443	                offsetX = (oldWidth - outputWidth) / 2;
48444	            }
48445	        }
48446	        blobCanvas.width = outputWidth;
48447	        blobCanvas.height = outputHeight;
48448	        try {
48449	            return new Promise(async (resolve, reject)=>{
48450	                blobCanvas.getContext('2d').drawImage(this[$renderer].displayCanvas(this[$scene]), offsetX, offsetY, outputWidth, outputHeight, 0, 0, outputWidth, outputHeight);
48451	                blobCanvas.toBlob((blob)=>{
48452	                    if (!blob) {
48453	                        return reject(new Error('Unable to retrieve canvas blob'));
48454	                    }
48455	                    resolve(blob);
48456	                }, mimeType, qualityArgument);
48457	            });
48458	        } finally{
48459	            this[$updateSize]({
48460	                width,
48461	                height
48462	            });
48463	        }
48464	    }
48465	 registerEffectComposer(effectComposer) {
48466	        effectComposer.setRenderer(this[$renderer].threeRenderer);
48467	        effectComposer.setMainCamera(this[$scene].getCamera());
48468	        effectComposer.setMainScene(this[$scene]);
48469	        this[$scene].effectRenderer = effectComposer;
48470	    }
48471	 unregisterEffectComposer() {
48472	        this[$scene].effectRenderer = null;
48473	    }
48474	    registerRenderer(renderer) {
48475	        this[$scene].externalRenderer = renderer;
48476	    }
48477	    unregisterRenderer() {
48478	        this[$scene].externalRenderer = null;
48479	    }
48480	    get [$ariaLabel]() {
48481	        return this[$altDefaulted];
48482	    }
48483	    get [$altDefaulted]() {
48484	        return this.alt == null || this.alt === 'null' ? this[$defaultAriaLabel] : this.alt;
48485	    }
48486	    [$getLoaded]() {
48487	        return this[$loaded];
48488	    }
48489	    [$getModelIsVisible]() {
48490	        return this.loaded && this[$isElementInViewport];
48491	    }
48492	    [$shouldAttemptPreload]() {
48493	        return !!this.src && this[$isElementInViewport];
48494	    }
48495	 [$updateSize]({ width, height }) {
48496	        if (width === 0 || height === 0) {
48497	            return;
48498	        }
48499	        this[$container].style.width = `${width}px`;
48500	        this[$container].style.height = `${height}px`;
48501	        this[$onResize]({
48502	            width,
48503	            height
48504	        });
48505	    }
48506	    [$tick](time, delta) {
48507	        var _p;
48508	        (_p = this[$scene].effectRenderer) === null || _p === void 0 ? void 0 : _p.beforeRender(time, delta);
48509	    }
48510	    [$markLoaded]() {
48511	        if (this[$loaded]) {
48512	            return;
48513	        }
48514	        this[$loaded] = true;
48515	        this[$loadedTime] = performance.now();
48516	    }
48517	    [$needsRender]() {
48518	        this[$scene].queueRender();
48519	    }
48520	    [$onModelLoad]() {}
48521	    [$updateStatus](status) {
48522	        this[$status] = status;
48523	        const rootNode = this.getRootNode();
48524	        if (rootNode != null && rootNode.activeElement === this && this[$statusElement].textContent != status) {
48525	            this[$statusElement].textContent = status;
48526	        }
48527	    }
48528	    [(_l = $onFocus, _m = $onBlur, $onResize)](e) {
48529	        this[$scene].setSize(e.width, e.height);
48530	    }
48531	 async [(_o = $onContextLost, $updateSource)]() {
48532	        const scene = this[$scene];
48533	        if (this.loaded || !this[$shouldAttemptPreload]() || this.src === sce
48533ne.url) {
48534	            return;
48535	        }
48536	        if (this.generateSchema) {
48537	            scene.updateSchema(this.src);
48538	        }
48539	        this[$updateStatus]('Loading');
48540	        scene.stopAnimation();
48541	        const updateSourceProgress = this[$progressTracker].beginActivity('model-load');
48542	        const source = this.src;
48543	        try {
48544	            const srcUpdated = scene.setSource(source, (progress)=>updateSourceProgress(clamp(progress, 0, 1) * 0.95));
48545	            const envUpdated = this[$updateEnvironment]();
48546	            await Promise.all([
48547	                srcUpdated,
48548	                envUpdated
48549	            ]);
48550	            this[$markLoaded]();
48551	            this[$onModelLoad]();
48552	            this.updateComplete.then(()=>{
48553	                this.dispatchEvent(new CustomEvent('before-render'));
48554	            });
48555	            await new Promise((resolve)=>{
48556	                requestAnimationFrame(()=>{
48557	                    requestAnimationFrame(()=>{
48558	                        this.dispatchEvent(new CustomEvent('load', {
48559	                            detail: {
48560	                                url: source
48561	                            }
48562	                        }));
48563	                        resolve();
48564	                    });
48565	                });
48566	            });
48567	        } catch (error) {
48568	            this.dispatchEvent(new CustomEvent('error', {
48569	                detail: {
48570	                    type: 'loadfailure',
48571	                    sourceError: error
48572	                }
48573	            }));
48574	        } finally{
48575	            updateSourceProgress(1.0);
48576	        }
48577	    }
48578	 constructor(){
48579	        super();
48580	        this.alt = null;
48581	        this.src = null;
48582	        this.withCredentials = false;
48583	 this.generateSchema = false;
48584	        this[_a$1] = false;
48585	        this[_b$1] = false;
48586	        this[_c] = 0;
48587	        this[_d] = '';
48588	        this[_e] = null;
48589	        this[_f] = debounce(()=>{
48590	            const boundingRect = this.getBoundingClientRect();
48591	            this[$updateSize](boundingRect);
48592	        }, FALLBACK_SIZE_UPDATE_THRESHOLD_MS);
48593	        this[_g] = debounce((oldVisibility)=>{
48594	            const newVisibility = this.modelIsVisible;
48595	            if (newVisibility !== oldVisibility) {
48596	                this.dispatchEvent(new CustomEvent('model-visibility', {
48597	                    detail: {
48598	                        visible: newVisibility
48599	                    }
48600	                }));
48601	            }
48602	        }, ANNOUNCE_MODEL_VISIBILITY_DEBOUNCE_THRESHOLD);
48603	        this[_h] = null;
48604	        this[_j] = null;
48605	        this[_k] = new ProgressTracker();
48606	        this[_l] = ()=>{
48607	            this[$statusElement].textContent = this[$status];
48608	        };
48609	        this[_m] = ()=>{
48610	            this[$statusElement].textContent = '';
48611	        };
48612	        this[_o] = (event)=>{
48613	            this.dispatchEvent(new CustomEvent('error', {
48614	                detail: {
48615	                    type: 'webglcontextlost',
48616	                    sourceError: event.sourceEvent
48617	                }
48618	            }));
48619	        };
48620	        this.attachShadow({
48621	            mode: 'open'
48622	        });
48623	        const shadowRoot = this.shadowRoot;
48624	        makeTemplate(shadowRoot);
48625	        this[$container] = shadowRoot.querySelector('.container');
48626	        this[$userInputElement] = shadowRoot.querySelector('.userInput');
48627	        this[$canvas] = shadowRoot.querySelector('canvas');
48628	        this[$statusElement] = shadowRoot.querySelector('#status');
vendor: 4,779 bytes, lines 48629-48772
48629	        this[$defaultAriaLabel] = this[$userInputElement].getAttribute('aria-label');
48630	        let width, height;
48631	        if (this.isConnected) {
48632	            const rect = this.getBoundingClientRect();
48633	            width = rect.width;
48634	            height = rect.height;
48635	        } else {
48636	            width = UNSIZED_MEDIA_WIDTH;
48637	            height = UNSIZED_MEDIA_HEIGHT;
48638	        }
48639	        this[$scene] = new ModelScene({
48640	            canvas: this[$canvas],
48641	            element: this,
48642	            width,
48643	            height
48644	        });
48645	        Promise.resolve().then(()=>{
48646	            this[$updateSize](this.getBoundingClientRect());
48647	        });
48648	        if (HAS_RESIZE_OBSERVER) {
48649	            this[$resizeObserver] = new ResizeObserver((entries)=>{
48650	                if (this[$renderer].isPresenting) {
48651	                    return;
48652	                }
48653	                for (let entry of entries){
48654	                    if (entry.target === this) {
48655	                        this[$updateSize](entry.contentRect);
48656	                    }
48657	                }
48658	            });
48659	        }
48660	        if (HAS_INTERSECTION_OBSERVER) {
48661	            this[$intersectionObserver] = new IntersectionObserver((entries)=>{
48662	                for (let entry of entries){
48663	                    if (entry.target === this) {
48664	                        const oldVisibility = this.modelIsVisible;
48665	                        this[$isElementInViewport] = entry.isIntersecting;
48666	                        this[$announceModelVisibility](oldVisibility);
48667	                        if (this[$isElementInViewport] && !this.loaded) {
48668	                            this[$updateSource]();
48669	                        }
48670	                    }
48671	                }
48672	            }, {
48673	                root: null,
48674	                rootMargin: '0px',
48675	                threshold: 0.00001
48676	            });
48677	        } else {
48678	            this[$isElementInViewport] = true;
48679	        }
48680	    }
48681	}
48682	__decorate$4([
48683	    n$2({
48684	        type: String
48685	    })
48686	], ModelViewerElementBase.prototype, "alt", void 0);
48687	__decorate$4([
48688	    n$2({
48689	        type: String
48690	    })
48691	], ModelViewerElementBase.prototype, "src", void 0);
48692	__decorate$4([
48693	    n$2({
48694	        type: Boolean,
48695	        attribute: 'with-credentials'
48696	    })
48697	], ModelViewerElementBase.prototype, "withCredentials", void 0);
48698	__decorate$4([
48699	    n$2({
48700	        type: Boolean,
48701	        attribute: 'generate-schema'
48702	    })
48703	], ModelViewerElementBase.prototype, "generateSchema", void 0);
48704
48705	var __decorate$3 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
48706	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
48707	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
48708	    return c > 3 && r && Object.defineProperty(target, key, r), r;
48709	};
48710	const MILLISECONDS_PER_SECOND = 1000.0;
48711	const $changeAnimation = Symbol('changeAnimation');
48712	const $appendAnimation = Symbol('appendAnimation');
48713	const $detachAnimation = Symbol('detachAnimation');
48714	const $paused = Symbol('paused');
48715	const DEFAULT_PLAY_OPTIONS = {
48716	    repetitions: Infinity,
48717	    pingpong: false
48718	};
48719	const DEFAULT_APPEND_OPTIONS = {
48720	    pingpong: false,
48721	    repetitions: null,
48722	    weight: 1,
48723	    timeScale: 1,
48724	    fade: false,
48725	    warp: false,
48726	    relativeWarp: true,
48727	    time: null
48728	};
48729	const DEFAULT_DETACH_OPTIONS = {
48730	    fade: true
48731	};
48732	const AnimationMixin = (ModelViewerElement)=>{
48733	    var _a;
48734	    class AnimationModelViewerElement extends ModelViewerElement {
48735	 get availableAnimations() {
48736	            if (this.loaded) {
48737	                return this[$scene].animationNames;
48738	            }
48739	            return [];
48740	        }
48741	        get duration() {
48742	            return this[$scene].duration;
48743	        }
48744	        get paused() {
48745	            return this[$paused];
48746	        }
48747	        get currentTime() {
48748	            return this[$scene].animationTime;
48749	        }
48750	        get appendedAnimations() {
48751	            return this[$scene].appendedAnimations;
48752	        }
48753	        set currentTime(value) {
48754	            this[$scene].animationTime = value;
48755	            this[$needsRender]();
48756	        }
48757	        get timeScale() {
48758	            return this[$scene].animationTimeScale;
48759	        }
48760	        set timeScale(value) {
48761	            this[$scene].animationTimeScale = value;
48762	        }
48763	        pause() {
48764	            if (this[$paused]) {
48765	                return;
48766	            }
48767	            this[$paused] = true;
48768	            this.dispatchEvent(new CustomEvent('pause'));
48769	        }
48770	        play(options) {
48771	            if (this.availableAnimations.length > 0) {
48772	                this[$paused] = false;
vendor: 4,213 bytes, lines 48773-48859
48773	                this[$changeAnimation](options);
48774	                this.dispatchEvent(new CustomEvent('play'));
48775	            }
48776	        }
48777	        appendAnimation(animationName, options) {
48778	            if (this.availableAnimations.length > 0) {
48779	                this[$paused] = false;
48780	                this[$appendAnimation](animationName, options);
48781	                this.dispatchEvent(new CustomEvent('append-animation'));
48782	            }
48783	        }
48784	        detachAnimation(animationName, options) {
48785	            if (this.availableAnimations.length > 0) {
48786	                this[$paused] = false;
48787	                this[$detachAnimation](animationName, options);
48788	                this.dispatchEvent(new CustomEvent('detach-animation'));
48789	            }
48790	        }
48791	        [(_a = $paused, $onModelLoad)]() {
48792	            super[$onModelLoad]();
48793	            this[$paused] = true;
48794	            if (this.animationName != null) {
48795	                this[$changeAnimation]();
48796	            }
48797	            if (this.autoplay) {
48798	                this.play();
48799	            }
48800	        }
48801	        [$tick](_time, delta) {
48802	            super[$tick](_time, delta);
48803	            if (this[$paused] || !this[$getModelIsVisible]() && !this[$renderer].isPresenting) {
48804	                return;
48805	            }
48806	            this[$scene].updateAnimation(delta / MILLISECONDS_PER_SECOND);
48807	            this[$needsRender]();
48808	        }
48809	        updated(changedProperties) {
48810	            super.updated(changedProperties);
48811	            if (changedProperties.has('autoplay') && this.autoplay) {
48812	                this.play();
48813	            }
48814	            if (changedProperties.has('animationName')) {
48815	                this[$changeAnimation]();
48816	            }
48817	        }
48818	        [$changeAnimation](options = DEFAULT_PLAY_OPTIONS) {
48819	            var _b;
48820	            const repetitions = (_b = options.repetitions) !== null && _b !== void 0 ? _b : Infinity;
48821	            const mode = options.pingpong ? LoopPingPong : repetitions === 1 ? LoopOnce : LoopRepeat;
48822	            this[$scene].playAnimation(this.animationName, this.animationCrossfadeDuration / MILLISECONDS_PER_SECOND, mode, repetitions);
48823	            if (this[$paused]) {
48824	                this[$scene].updateAnimation(0);
48825	                this[$needsRender]();
48826	            }
48827	        }
48828	        [$appendAnimation](animationName = '', options = DEFAULT_APPEND_OPTIONS) {
48829	            var _b;
48830	            const repetitions = (_b = options.repetitions) !== null && _b !== void 0 ? _b : Infinity;
48831	            const mode = options.pingpong ? LoopPingPong : repetitions === 1 ? LoopOnce : LoopRepeat;
48832	            const needsToStop = !!options.repetitions || 'pingpong' in options;
48833	            this[$scene].appendAnimation(animationName ? animationName : this.animationName, mode, repetitions, options.weight, options.timeScale, options.fade, options.warp, options.relativeWarp, options.time, needsToStop);
48834	            if (this[$paused]) {
48835	                this[$scene].updateAnimation(0);
48836	                this[$needsRender]();
48837	            }
48838	        }
48839	        [$detachAnimation](animationName = '', options = DEFAULT_DETACH_OPTIONS) {
48840	            this[$scene].detachAnimation(animationName ? animationName : this.animationName, options.fade);
48841	            if (this[$paused]) {
48842	                this[$scene].updateAnimation(0);
48843	                this[$needsRender]();
48844	            }
48845	        }
48846	        constructor(...args){
48847	            super(args);
48848	            this.autoplay = false;
48849	            this.animationName = undefined;
48850	            this.animationCrossfadeDuration = 300;
48851	            this[_a] = true;
48852	            this[$scene].subscribeMixerEvent('loop', (e)=>{
48853	                const count = e.action._loopCount;
48854	                const name = e.action._clip.name;
48855	                const uuid = e.action._clip.uuid;
48856	                const targetAnimation = this[$scene].markedAnimations.find((e)=>e.name === name);
48857	                if (targetAnimation) {
48858	                    this[$scene].updateAnimationLoop(targetAnimation.name, targetAnimation.loopMode, targetAnimation.repetitionCount);
48859	                    const filtredArr = this[$scene].markedAnimations.filter((e)=>
vendor: 4,599 bytes, lines 48859-48977
48859e.name !== name);
48860	                    this[$scene].markedAnimations = filtredArr;
48861	                }
48862	                this.dispatchEvent(new CustomEvent('loop', {
48863	                    detail: {
48864	                        count,
48865	                        name,
48866	                        uuid
48867	                    }
48868	                }));
48869	            });
48870	            this[$scene].subscribeMixerEvent('finished', (e)=>{
48871	                if (!this[$scene].appendedAnimations.includes(e.action._clip.name)) {
48872	                    this[$paused] = true;
48873	                } else {
48874	                    const filterdList = this[$scene].appendedAnimations.filter((i)=>i !== e.action._clip.name);
48875	                    this[$scene].appendedAnimations = filterdList;
48876	                }
48877	                this.dispatchEvent(new CustomEvent('finished'));
48878	            });
48879	        }
48880	    }
48881	    __decorate$3([
48882	        n$2({
48883	            type: Boolean
48884	        })
48885	    ], AnimationModelViewerElement.prototype, "autoplay", void 0);
48886	    __decorate$3([
48887	        n$2({
48888	            type: String,
48889	            attribute: 'animation-name'
48890	        })
48891	    ], AnimationModelViewerElement.prototype, "animationName", void 0);
48892	    __decorate$3([
48893	        n$2({
48894	            type: Number,
48895	            attribute: 'animation-crossfade-duration'
48896	        })
48897	    ], AnimationModelViewerElement.prototype, "animationCrossfadeDuration", void 0);
48898	    return AnimationModelViewerElement;
48899	};
48900
48901	const $hotspotMap = Symbol('hotspotMap');
48902	const $mutationCallback = Symbol('mutationCallback');
48903	const $observer = Symbol('observer');
48904	const $addHotspot = Symbol('addHotspot');
48905	const $removeHotspot = Symbol('removeHotspot');
48906	const worldToModel = new Matrix4();
48907	 const AnnotationMixin = (ModelViewerElement)=>{
48908	    var _a, _b, _c;
48909	    class AnnotationModelViewerElement extends ModelViewerElement {
48910	        connectedCallback() {
48911	            super.connectedCallback();
48912	            for(let i = 0; i < this.children.length; ++i){
48913	                this[$addHotspot](this.children[i]);
48914	            }
48915	            const { ShadyDOM } = self;
48916	            if (ShadyDOM == null) {
48917	                this[$observer].observe(this, {
48918	                    childList: true
48919	                });
48920	            } else {
48921	                this[$observer] = ShadyDOM.observeChildren(this, this[$mutationCallback]);
48922	            }
48923	        }
48924	        disconnectedCallback() {
48925	            super.disconnectedCallback();
48926	            const { ShadyDOM } = self;
48927	            if (ShadyDOM == null) {
48928	                this[$observer].disconnect();
48929	            } else {
48930	                ShadyDOM.unobserveChildren(this[$observer]);
48931	            }
48932	        }
48933	        [(_a = $hotspotMap, _b = $mutationCallback, _c = $observer, $onModelLoad)]() {
48934	            super[$onModelLoad]();
48935	            const scene = this[$scene];
48936	            scene.forHotspots((hotspot)=>{
48937	                scene.updateSurfaceHotspot(hotspot);
48938	            });
48939	        }
48940	        [$tick](time, delta) {
48941	            super[$tick](time, delta);
48942	            const scene = this[$scene];
48943	            const { annotationRenderer } = scene;
48944	            const camera = scene.getCamera();
48945	            if (scene.shouldRender()) {
48946	                scene.animateSurfaceHotspots();
48947	                scene.updateHotspotsVisibility(camera.position);
48948	                annotationRenderer.domElement.style.display = '';
48949	                annotationRenderer.render(scene, camera);
48950	            }
48951	        }
48952	 updateHotspot(config) {
48953	            const hotspot = this[$hotspotMap].get(config.name);
48954	            if (hotspot == null) {
48955	                return;
48956	            }
48957	            hotspot.updatePosition(config.position);
48958	            hotspot.updateNormal(config.normal);
48959	            hotspot.surface = config.surface;
48960	            this[$scene].updateSurfaceHotspot(hotspot);
48961	            this[$needsRender]();
48962	        }
48963	 queryHotspot(name) {
48964	            const hotspot = this[$hotspotMap].get(name);
48965	            if (hotspot == null) {
48966	                return null;
48967	            }
48968	            const position = toVector3D(hotspot.position);
48969	            const normal = toVector3D(hotspot.normal);
48970	            const facingCamera = hotspot.facingCamera;
48971	            const scene = this[$scene];
48972	            const camera = scene.getCamera();
48973	            const vector = new Vector3();
48974	            vector.setFromMatrixPosition(hotspot.matrixWorld);
48975	            vector.project(camera);
48976	            const widthHalf = scene.width / 2;
48977	            const heightHalf = scene.height / 2;
vendor: 4,034 bytes, lines 48978-49079
48978	            vector.x = vector.x * widthHalf + widthHalf;
48979	            vector.y = -(vector.y * heightHalf) + heightHalf;
48980	            const canvasPosition = toVector3D(new Vector3(vector.x, vector.y, vector.z));
48981	            if (!Number.isFinite(canvasPosition.x) || !Number.isFinite(canvasPosition.y)) {
48982	                return null;
48983	            }
48984	            return {
48985	                position,
48986	                normal,
48987	                canvasPosition,
48988	                facingCamera
48989	            };
48990	        }
48991	 positionAndNormalFromPoint(pixelX, pixelY) {
48992	            const scene = this[$scene];
48993	            const ndcPosition = scene.getNDC(pixelX, pixelY);
48994	            const hit = scene.positionAndNormalFromPoint(ndcPosition);
48995	            if (hit == null) {
48996	                return null;
48997	            }
48998	            worldToModel.copy(scene.target.matrixWorld).invert();
48999	            const position = toVector3D(hit.position.applyMatrix4(worldToModel));
49000	            const normal = toVector3D(hit.normal.transformDirection(worldToModel));
49001	            let uv = null;
49002	            if (hit.uv != null) {
49003	                uv = toVector2D(hit.uv);
49004	            }
49005	            return {
49006	                position: position,
49007	                normal: normal,
49008	                uv: uv
49009	            };
49010	        }
49011	 surfaceFromPoint(pixelX, pixelY) {
49012	            const scene = this[$scene];
49013	            const ndcPosition = scene.getNDC(pixelX, pixelY);
49014	            return scene.surfaceFromPoint(ndcPosition);
49015	        }
49016	        [$addHotspot](node) {
49017	            if (!(node instanceof HTMLElement && node.slot.indexOf('hotspot') === 0)) {
49018	                return;
49019	            }
49020	            let hotspot = this[$hotspotMap].get(node.slot);
49021	            if (hotspot != null) {
49022	                hotspot.increment();
49023	            } else {
49024	                hotspot = new Hotspot({
49025	                    name: node.slot,
49026	                    position: node.dataset.position,
49027	                    normal: node.dataset.normal,
49028	                    surface: node.dataset.surface
49029	                });
49030	                this[$hotspotMap].set(node.slot, hotspot);
49031	                this[$scene].addHotspot(hotspot);
49032	            }
49033	            this[$scene].queueRender();
49034	        }
49035	        [$removeHotspot](node) {
49036	            if (!(node instanceof HTMLElement)) {
49037	                return;
49038	            }
49039	            const hotspot = this[$hotspotMap].get(node.slot);
49040	            if (!hotspot) {
49041	                return;
49042	            }
49043	            if (hotspot.decrement()) {
49044	                this[$scene].removeHotspot(hotspot);
49045	                this[$hotspotMap].delete(node.slot);
49046	            }
49047	            this[$scene].queueRender();
49048	        }
49049	        constructor(){
49050	            super(...arguments);
49051	            this[_a] = new Map();
49052	            this[_b] = (mutations)=>{
49053	                mutations.forEach((mutation)=>{
49054	                    if (!(mutation instanceof MutationRecord) || mutation.type === 'childList') {
49055	                        mutation.addedNodes.forEach((node)=>{
49056	                            this[$addHotspot](node);
49057	                        });
49058	                        mutation.removedNodes.forEach((node)=>{
49059	                            this[$removeHotspot](node);
49060	                        });
49061	                        this[$needsRender]();
49062	                    }
49063	                });
49064	            };
49065	            this[_c] = new MutationObserver(this[$mutationCallback]);
49066	        }
49067	    }
49068	    return AnnotationModelViewerElement;
49069	};
49070
49071	/*!
49072	fflate - fast JavaScript compression/decompression
49073	<https://101arrowz.github.io/fflate>
49074	Licensed under MIT. https://github.com/101arrowz/fflate/blob/master/LICENSE
49075	version 0.8.2
49076	*/ // DEFLATE is a complex format; to read this code, you should probably check the RFC first:
49077	// https://tools.ietf.org/html/rfc1951
49078	// You may also wish to take a look at the guide I made about this program:
49079	// https://gist.github.com/101arrowz/253f31eb5abc3d9275ab943003ffecad
vendor: 5,986 bytes, lines 49080-49326
49080	// Some of the following code is similar to that of UZIP.js:
49081	// https://github.com/photopea/UZIP.js
49082	// However, the vast majority of the codebase has diverged from UZIP.js to increase performance and reduce bundle size.
49083	// Sometimes 0 will appear where -1 would be more appropriate. This is because using a uint
49084	// is better for memory in most engines (I *think*).
49085	// aliases for shorter compressed code (most minifers don't do this)
49086	var u8 = Uint8Array, u16 = Uint16Array, i32 = Int32Array;
49087	// fixed length extra bits
49088	var fleb = new u8([
49089	    0,
49090	    0,
49091	    0,
49092	    0,
49093	    0,
49094	    0,
49095	    0,
49096	    0,
49097	    1,
49098	    1,
49099	    1,
49100	    1,
49101	    2,
49102	    2,
49103	    2,
49104	    2,
49105	    3,
49106	    3,
49107	    3,
49108	    3,
49109	    4,
49110	    4,
49111	    4,
49112	    4,
49113	    5,
49114	    5,
49115	    5,
49116	    5,
49117	    0,
49118	    /* unused */ 0,
49119	    0,
49120	    /* impossible */ 0
49121	]);
49122	// fixed distance extra bits
49123	var fdeb = new u8([
49124	    0,
49125	    0,
49126	    0,
49127	    0,
49128	    1,
49129	    1,
49130	    2,
49131	    2,
49132	    3,
49133	    3,
49134	    4,
49135	    4,
49136	    5,
49137	    5,
49138	    6,
49139	    6,
49140	    7,
49141	    7,
49142	    8,
49143	    8,
49144	    9,
49145	    9,
49146	    10,
49147	    10,
49148	    11,
49149	    11,
49150	    12,
49151	    12,
49152	    13,
49153	    13,
49154	    /* unused */ 0,
49155	    0
49156	]);
49157	// code length index map
49158	var clim = new u8([
49159	    16,
49160	    17,
49161	    18,
49162	    0,
49163	    8,
49164	    7,
49165	    9,
49166	    6,
49167	    10,
49168	    5,
49169	    11,
49170	    4,
49171	    12,
49172	    3,
49173	    13,
49174	    2,
49175	    14,
49176	    1,
49177	    15
49178	]);
49179	// get base, reverse index map from extra bits
49180	var freb = function(eb, start) {
49181	    var b = new u16(31);
49182	    for(var i = 0; i < 31; ++i){
49183	        b[i] = start += 1 << eb[i - 1];
49184	    }
49185	    // numbers here are at max 18 bits
49186	    var r = new i32(b[30]);
49187	    for(var i = 1; i < 30; ++i){
49188	        for(var j = b[i]; j < b[i + 1]; ++j){
49189	            r[j] = j - b[i] << 5 | i;
49190	        }
49191	    }
49192	    return {
49193	        b: b,
49194	        r: r
49195	    };
49196	};
49197	var _a = freb(fleb, 2), fl = _a.b, revfl = _a.r;
49198	// we can ignore the fact that the other numbers are wrong; they never happen anyway
49199	fl[28] = 258, revfl[258] = 28;
49200	var _b = freb(fdeb, 0), revfd = _b.r;
49201	// map of value to reverse (assuming 16 bits)
49202	var rev = new u16(32768);
49203	for(var i = 0; i < 32768; ++i){
49204	    // reverse table algorithm from SO
49205	    var x = (i & 0xAAAA) >> 1 | (i & 0x5555) << 1;
49206	    x = (x & 0xCCCC) >> 2 | (x & 0x3333) << 2;
49207	    x = (x & 0xF0F0) >> 4 | (x & 0x0F0F) << 4;
49208	    rev[i] = ((x & 0xFF00) >> 8 | (x & 0x00FF) << 8) >> 1;
49209	}
49210	// create huffman tree from u8 "map": index -> code length for code index
49211	// mb (max bits) must be at most 15
49212	// TODO: optimize/split up?
49213	var hMap = function(cd, mb, r) {
49214	    var s = cd.length;
49215	    // index
49216	    var i = 0;
49217	    // u16 "map": index -> # of codes with bit length = index
49218	    var l = new u16(mb);
49219	    // length of cd must be 288 (total # of codes)
49220	    for(; i < s; ++i){
49221	        if (cd[i]) ++l[cd[i] - 1];
49222	    }
49223	    // u16 "map": index -> minimum code for bit length = index
49224	    var le = new u16(mb);
49225	    for(i = 1; i < mb; ++i){
49226	        le[i] = le[i - 1] + l[i - 1] << 1;
49227	    }
49228	    var co;
49229	    if (r) {
49230	        // u16 "map": index -> number of actual bits, symbol for code
49231	        co = new u16(1 << mb);
49232	        // bits to remove for reverser
49233	        var rvb = 15 - mb;
49234	        for(i = 0; i < s; ++i){
49235	            // ignore 0 lengths
49236	            if (cd[i]) {
49237	                // num encoding both symbol and bits read
49238	                var sv = i << 4 | cd[i];
49239	                // free bits
49240	                var r_1 = mb - cd[i];
49241	                // start value
49242	                var v = le[cd[i] - 1]++ << r_1;
49243	                // m is end value
49244	                for(var m = v | (1 << r_1) - 1; v <= m; ++v){
49245	                    // every 16 bit value starting with the code yields the same result
49246	                    co[rev[v] >> rvb] = sv;
49247	                }
49248	            }
49249	        }
49250	    } else {
49251	        co = new u16(s);
49252	        for(i = 0; i < s; ++i){
49253	            if (cd[i]) {
49254	                co[i] = rev[le[cd[i] - 1]++] >> 15 - cd[i];
49255	            }
49256	        }
49257	    }
49258	    return co;
49259	};
49260	// fixed length tree
49261	var flt = new u8(288);
49262	for(var i = 0; i < 144; ++i)flt[i] = 8;
49263	for(var i = 144; i < 256; ++i)flt[i] = 9;
49264	for(var i = 256; i < 280; ++i)flt[i] = 7;
49265	for(var i = 280; i < 288; ++i)flt[i] = 8;
49266	// fixed distance tree
49267	var fdt = new u8(32);
49268	for(var i = 0; i < 32; ++i)fdt[i] = 5;
49269	// fixed length map
49270	var flm = /*#__PURE__*/ hMap(flt, 9, 0);
49271	// fixed distance map
49272	var fdm = /*#__PURE__*/ hMap(fdt, 5, 0);
49273	// get end of byte
49274	var shft = function(p) {
49275	    return (p + 7) / 8 | 0;
49276	};
49277	// typed array slice - allows garbage collector to free original reference,
49278	// while being more compatible than .slice
49279	var slc = function(v, s, e) {
49280	    if (e == null || e > v.length) e = v.length;
49281	    // can't use .constructor in case user-supplied
49282	    return new u8(v.subarray(s, e));
49283	};
49284	// error codes
49285	var ec = [
49286	    'unexpected EOF',
49287	    'invalid block type',
49288	    'invalid length/literal',
49289	    'invalid distance',
49290	    'stream finished',
49291	    'no stream handler',
49292	    ,
49293	    'no callback',
49294	    'invalid UTF-8 data',
49295	    'extra field too long',
49296	    'date not in range 1980-2099',
49297	    'filename too long',
49298	    'stream finishing',
49299	    'invalid zip data'
49300	];
49301	var err = function(ind, msg, nt) {
49302	    var e = new Error(msg || ec[ind]);
49303	    e.code = ind;
49304	    if (Error.captureStackTrace) Error.captureStackTrace(e, err);
49305	    if (!nt) throw e;
49306	    return e;
49307	};
49308	// starting at p, write the minimum number of bits that can hold v to d
49309	var wbits = function(d, p, v) {
49310	    v <<= p & 7;
49311	    var o = p / 8 | 0;
49312	    d[o] |= v;
49313	    d[o + 1] |= v >> 8;
49314	};
49315	// starting at p, write the minimum number of bits (>8) that can hold v to d
49316	var wbits16 = function(d, p, v) {
49317	    v <<= p & 7;
49318	    var o = p / 8 | 0;
49319	    d[o] |= v;
49320	    d[o + 1] |= v >> 8;
49321	    d[o + 2] |= v >> 16;
49322	};
49323	// creates code lengths from a frequency table
49324	var hTree = function(d, mb) {
49325	    // Need extra info to make a tree
49326	    var t = [];
vendor: 10,065 bytes, lines 49327-49613
49327	    for(var i = 0; i < d.length; ++i){
49328	        if (d[i]) t.push({
49329	            s: i,
49330	            f: d[i]
49331	        });
49332	    }
49333	    var s = t.length;
49334	    var t2 = t.slice();
49335	    if (!s) return {
49336	        t: et,
49337	        l: 0
49338	    };
49339	    if (s == 1) {
49340	        var v = new u8(t[0].s + 1);
49341	        v[t[0].s] = 1;
49342	        return {
49343	            t: v,
49344	            l: 1
49345	        };
49346	    }
49347	    t.sort(function(a, b) {
49348	        return a.f - b.f;
49349	    });
49350	    // after i2 reaches last ind, will be stopped
49351	    // freq must be greater than largest possible number of symbols
49352	    t.push({
49353	        s: -1,
49354	        f: 25001
49355	    });
49356	    var l = t[0], r = t[1], i0 = 0, i1 = 1, i2 = 2;
49357	    t[0] = {
49358	        s: -1,
49359	        f: l.f + r.f,
49360	        l: l,
49361	        r: r
49362	    };
49363	    // efficient algorithm from UZIP.js
49364	    // i0 is lookbehind, i2 is lookahead - after processing two low-freq
49365	    // symbols that combined have high freq, will start processing i2 (high-freq,
49366	    // non-composite) symbols instead
49367	    // see https://reddit.com/r/photopea/comments/ikekht/uzipjs_questions/
49368	    while(i1 != s - 1){
49369	        l = t[t[i0].f < t[i2].f ? i0++ : i2++];
49370	        r = t[i0 != i1 && t[i0].f < t[i2].f ? i0++ : i2++];
49371	        t[i1++] = {
49372	            s: -1,
49373	            f: l.f + r.f,
49374	            l: l,
49375	            r: r
49376	        };
49377	    }
49378	    var maxSym = t2[0].s;
49379	    for(var i = 1; i < s; ++i){
49380	        if (t2[i].s > maxSym) maxSym = t2[i].s;
49381	    }
49382	    // code lengths
49383	    var tr = new u16(maxSym + 1);
49384	    // max bits in tree
49385	    var mbt = ln(t[i1 - 1], tr, 0);
49386	    if (mbt > mb) {
49387	        // more algorithms from UZIP.js
49388	        // TODO: find out how this code works (debt)
49389	        //  ind    debt
49390	        var i = 0, dt = 0;
49391	        //    left            cost
49392	        var lft = mbt - mb, cst = 1 << lft;
49393	        t2.sort(function(a, b) {
49394	            return tr[b.s] - tr[a.s] || a.f - b.f;
49395	        });
49396	        for(; i < s; ++i){
49397	            var i2_1 = t2[i].s;
49398	            if (tr[i2_1] > mb) {
49399	                dt += cst - (1 << mbt - tr[i2_1]);
49400	                tr[i2_1] = mb;
49401	            } else break;
49402	        }
49403	        dt >>= lft;
49404	        while(dt > 0){
49405	            var i2_2 = t2[i].s;
49406	            if (tr[i2_2] < mb) dt -= 1 << mb - tr[i2_2]++ - 1;
49407	            else ++i;
49408	        }
49409	        for(; i >= 0 && dt; --i){
49410	            var i2_3 = t2[i].s;
49411	            if (tr[i2_3] == mb) {
49412	                --tr[i2_3];
49413	                ++dt;
49414	            }
49415	        }
49416	        mbt = mb;
49417	    }
49418	    return {
49419	        t: new u8(tr),
49420	        l: mbt
49421	    };
49422	};
49423	// get the max length and assign length codes
49424	var ln = function(n, l, d) {
49425	    return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
49426	};
49427	// length codes generation
49428	var lc = function(c) {
49429	    var s = c.length;
49430	    // Note that the semicolon was intentional
49431	    while(s && !c[--s]);
49432	    var cl = new u16(++s);
49433	    //  ind      num         streak
49434	    var cli = 0, cln = c[0], cls = 1;
49435	    var w = function(v) {
49436	        cl[cli++] = v;
49437	    };
49438	    for(var i = 1; i <= s; ++i){
49439	        if (c[i] == cln && i != s) ++cls;
49440	        else {
49441	            if (!cln && cls > 2) {
49442	                for(; cls > 138; cls -= 138)w(32754);
49443	                if (cls > 2) {
49444	                    w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
49445	                    cls = 0;
49446	                }
49447	            } else if (cls > 3) {
49448	                w(cln), --cls;
49449	                for(; cls > 6; cls -= 6)w(8304);
49450	                if (cls > 2) w(cls - 3 << 5 | 8208), cls = 0;
49451	            }
49452	            while(cls--)w(cln);
49453	            cls = 1;
49454	            cln = c[i];
49455	        }
49456	    }
49457	    return {
49458	        c: cl.subarray(0, cli),
49459	        n: s
49460	    };
49461	};
49462	// calculate the length of output from tree, code lengths
49463	var clen = function(cf, cl) {
49464	    var l = 0;
49465	    for(var i = 0; i < cl.length; ++i)l += cf[i] * cl[i];
49466	    return l;
49467	};
49468	// writes a fixed block
49469	// returns the new bit pos
49470	var wfblk = function(out, pos, dat) {
49471	    // no need to write 00 as type: TypedArray defaults to 0
49472	    var s = dat.length;
49473	    var o = shft(pos + 2);
49474	    out[o] = s & 255;
49475	    out[o + 1] = s >> 8;
49476	    out[o + 2] = out[o] ^ 255;
49477	    out[o + 3] = out[o + 1] ^ 255;
49478	    for(var i = 0; i < s; ++i)out[o + i + 4] = dat[i];
49479	    return (o + 4 + s) * 8;
49480	};
49481	// writes a block
49482	var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
49483	    wbits(out, p++, final);
49484	    ++lf[256];
49485	    var _a = hTree(lf, 15), dlt = _a.t, mlb = _a.l;
49486	    var _b = hTree(df, 15), ddt = _b.t, mdb = _b.l;
49487	    var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
49488	    var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
49489	    var lcfreq = new u16(19);
49490	    for(var i = 0; i < lclt.length; ++i)++lcfreq[lclt[i] & 31];
49491	    for(var i = 0; i < lcdt.length; ++i)++lcfreq[lcdt[i] & 31];
49492	    var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
49493	    var nlcc = 19;
49494	    for(; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc);
49495	    var flen = bl + 5 << 3;
49496	    var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
49497	    var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
49498	    if (bs >= 0 && flen <= ftlen && flen <= dtlen) return wfblk(out, p, dat.subarray(bs, bs + bl));
49499	    var lm, ll, dm, dl;
49500	    wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
49501	    if (dtlen < ftlen) {
49502	        lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
49503	        var llm = hMap(lct, mlcb, 0);
49504	        wbits(out, p, nlc - 257);
49505	        wbits(out, p + 5, ndc - 1);
49506	        wbits(out, p + 10, nlcc - 4);
49507	        p += 14;
49508	        for(var i = 0; i < nlcc; ++i)wbits(out, p + 3 * i, lct[clim[i]]);
49509	        p += 3 * nlcc;
49510	        var lcts = [
49511	            lclt,
49512	            lcdt
49513	        ];
49514	        for(var it = 0; it < 2; ++it){
49515	            var clct = lcts[it];
49516	            for(var i = 0; i < clct.length; ++i){
49517	                var len = clct[i] & 31;
49518	                wbits(out, p, llm[len]), p += lct[len];
49519	                if (len > 15) wbits(out, p, clct[i] >> 5 & 127), p += clct[i] >> 12;
49520	            }
49521	        }
49522	    } else {
49523	        lm = flm, ll = flt, dm = fdm, dl = fdt;
49524	    }
49525	    for(var i = 0; i < li; ++i){
49526	        var sym = syms[i];
49527	        if (sym > 255) {
49528	            var len = sym >> 18 & 31;
49529	            wbits16(out, p, lm[len + 257]), p += ll[len + 257];
49530	            if (len > 7) wbits(out, p, sym >> 23 & 31), p += fleb[len];
49531	            var dst = sym & 31;
49532	            wbits16(out, p, dm[dst]), p += dl[dst];
49533	            if (dst > 3) wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
49534	        } else {
49535	            wbits16(out, p, lm[sym]), p += ll[sym];
49536	        }
49537	    }
49538	    wbits16(out, p, lm[256]);
49539	    return p + ll[256];
49540	};
49541	// deflate options (nice << 13) | chain
49542	var deo = /*#__PURE__*/ new i32([
49543	    65540,
49544	    131080,
49545	    131088,
49546	    131104,
49547	    262176,
49548	    1048704,
49549	    1048832,
49550	    2114560,
49551	    2117632
49552	]);
49553	// empty
49554	var et = /*#__PURE__*/ new u8(0);
49555	// compresses data into a raw DEFLATE buffer
49556	var dflt = function(dat, lvl, plvl, pre, post, st) {
49557	    var s = st.z || dat.length;
49558	    var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
49559	    // writing to this writes to the output buffer
49560	    var w = o.subarray(pre, o.length - post);
49561	    var lst = st.l;
49562	    var pos = (st.r || 0) & 7;
49563	    if (lvl) {
49564	        if (pos) w[0] = st.r >> 3;
49565	        var opt = deo[lvl - 1];
49566	        var n = opt >> 13, c = opt & 8191;
49567	        var msk_1 = (1 << plvl) - 1;
49568	        //    prev 2-byte val map    curr 2-byte val map
49569	        var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
49570	        var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
49571	        var hsh = function(i) {
49572	            return (dat[i] ^ dat[i + 1] << bs1_1 ^ dat[i + 2] << bs2_1) & msk_1;
49573	        };
49574	        // 24576 is an arbitrary number of maximum symbols per block
49575	        // 424 buffer for last block
49576	        var syms = new i32(25000);
49577	        // length/literal freq   distance freq
49578	        var lf = new u16(288), df = new u16(32);
49579	        //  l/lcnt  exbits  index          l/lind  waitdx          blkpos
49580	        var lc_1 = 0, eb = 0, i = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
49581	        for(; i + 2 < s; ++i){
49582	            // hash value
49583	            var hv = hsh(i);
49584	            // index mod 32768    previous index mod
49585	            var imod = i & 32767, pimod = head[hv];
49586	            prev[imod] = pimod;
49587	            head[hv] = imod;
49588	            // We always should modify head and prev, but only add symbols if
49589	            // this data is not yet processed ("wait" for wait index)
49590	            if (wi <= i) {
49591	                // bytes remaining
49592	                var rem = s - i;
49593	                if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {
49594	                    pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i - bs, pos);
49595	                    li = lc_1 = eb = 0, bs = i;
49596	                    for(var j = 0; j < 286; ++j)lf[j] = 0;
49597	                    for(var j = 0; j < 30; ++j)df[j] = 0;
49598	                }
49599	                //  len    dist   chain
49600	                var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
49601	                if (rem > 2 && hv == hsh(i - dif)) {
49602	                    var maxn = Math.min(n, rem) - 1;
49603	                    var maxd = Math.min(32767, i);
49604	                    // max possible length
49605	                    // not capped at dif because decompressors implement "rolling" index population
49606	                    var ml = Math.min(258, rem);
49607	                    while(dif <= maxd && --ch_1 && imod != pimod){
49608	                        if (dat[i + l] == dat[i + l - dif]) {
49609	                            var nl = 0;
49610	                            for(; nl < ml && dat[i + nl] == dat[i + nl - dif]; ++nl);
49611	                            if (nl > l) {
49612	                                l = nl, d = dif;
49613	                                // break out early when we reach "nice" 
vendor: 16,127 bytes, lines 49613-50072
49613(we are satisfied enough)
49614	                                if (nl > maxn) break;
49615	                                // now, find the rarest 2-byte sequence within this
49616	                                // length of literals and search for that instead.
49617	                                // Much faster than just using the start
49618	                                var mmd = Math.min(dif, nl - 2);
49619	                                var md = 0;
49620	                                for(var j = 0; j < mmd; ++j){
49621	                                    var ti = i - dif + j & 32767;
49622	                                    var pti = prev[ti];
49623	                                    var cd = ti - pti & 32767;
49624	                                    if (cd > md) md = cd, pimod = ti;
49625	                                }
49626	                            }
49627	                        }
49628	                        // check the previous match
49629	                        imod = pimod, pimod = prev[imod];
49630	                        dif += imod - pimod & 32767;
49631	                    }
49632	                }
49633	                // d will be nonzero only when a match was found
49634	                if (d) {
49635	                    // store both dist and len data in one int32
49636	                    // Make sure this is recognized as a len/dist with 28th bit (2^28)
49637	                    syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
49638	                    var lin = revfl[l] & 31, din = revfd[d] & 31;
49639	                    eb += fleb[lin] + fdeb[din];
49640	                    ++lf[257 + lin];
49641	                    ++df[din];
49642	                    wi = i + l;
49643	                    ++lc_1;
49644	                } else {
49645	                    syms[li++] = dat[i];
49646	                    ++lf[dat[i]];
49647	                }
49648	            }
49649	        }
49650	        for(i = Math.max(i, wi); i < s; ++i){
49651	            syms[li++] = dat[i];
49652	            ++lf[dat[i]];
49653	        }
49654	        pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i - bs, pos);
49655	        if (!lst) {
49656	            st.r = pos & 7 | w[pos / 8 | 0] << 3;
49657	            // shft(pos) now 1 less if pos & 7 != 0
49658	            pos -= 7;
49659	            st.h = head, st.p = prev, st.i = i, st.w = wi;
49660	        }
49661	    } else {
49662	        for(var i = st.w || 0; i < s + lst; i += 65535){
49663	            // end
49664	            var e = i + 65535;
49665	            if (e >= s) {
49666	                // write final block
49667	                w[pos / 8 | 0] = lst;
49668	                e = s;
49669	            }
49670	            pos = wfblk(w, pos + 1, dat.subarray(i, e));
49671	        }
49672	        st.i = s;
49673	    }
49674	    return slc(o, 0, pre + shft(pos) + post);
49675	};
49676	// CRC32 table
49677	var crct = /*#__PURE__*/ function() {
49678	    var t = new Int32Array(256);
49679	    for(var i = 0; i < 256; ++i){
49680	        var c = i, k = 9;
49681	        while(--k)c = (c & 1 && -306674912) ^ c >>> 1;
49682	        t[i] = c;
49683	    }
49684	    return t;
49685	}();
49686	// CRC32
49687	var crc = function() {
49688	    var c = -1;
49689	    return {
49690	        p: function(d) {
49691	            // closures have awful performance
49692	            var cr = c;
49693	            for(var i = 0; i < d.length; ++i)cr = crct[cr & 255 ^ d[i]] ^ cr >>> 8;
49694	            c = cr;
49695	        },
49696	        d: function() {
49697	            return ~c;
49698	        }
49699	    };
49700	};
49701	// deflate with opts
49702	var dopt = function(dat, opt, pre, post, st) {
49703	    if (!st) {
49704	        st = {
49705	            l: 1
49706	        };
49707	        if (opt.dictionary) {
49708	            var dict = opt.dictionary.subarray(-32768);
49709	            var newDat = new u8(dict.length + dat.length);
49710	            newDat.set(dict);
49711	            newDat.set(dat, dict.length);
49712	            dat = newDat;
49713	            st.w = dict.length;
49714	        }
49715	    }
49716	    return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
49717	};
49718	// Walmart object spread
49719	var mrg = function(a, b) {
49720	    var o = {};
49721	    for(var k in a)o[k] = a[k];
49722	    for(var k in b)o[k] = b[k];
49723	    return o;
49724	};
49725	// write bytes
49726	var wbytes = function(d, b, v) {
49727	    for(; v; ++b)d[b] = v, v >>>= 8;
49728	};
49729	/**
49730	 * Compresses data with DEFLATE without any wrapper
49731	 * @param data The data to compress
49732	 * @param opts The compression options
49733	 * @returns The deflated version of the data
49734	 */ function deflateSync(data, opts) {
49735	    return dopt(data, opts || {}, 0, 0);
49736	}
49737	// flatten a directory structure
49738	var fltn = function(d, p, t, o) {
49739	    for(var k in d){
49740	        var val = d[k], n = p + k, op = o;
49741	        if (Array.isArray(val)) op = mrg(o, val[1]), val = val[0];
49742	        if (val instanceof u8) t[n] = [
49743	            val,
49744	            op
49745	        ];
49746	        else {
49747	            t[n += '/'] = [
49748	                new u8(0),
49749	                op
49750	            ];
49751	            fltn(val, n, t, o);
49752	        }
49753	    }
49754	};
49755	// text encoder
49756	var te = typeof TextEncoder != 'undefined' && /*#__PURE__*/ new TextEncoder();
49757	// text decoder
49758	var td = typeof TextDecoder != 'undefined' && /*#__PURE__*/ new TextDecoder();
49759	// text decoder stream
49760	var tds = 0;
49761	try {
49762	    td.decode(et, {
49763	        stream: true
49764	    });
49765	    tds = 1;
49766	} catch (e) {}
49767	/**
49768	 * Converts a string into a Uint8Array for use with compression/decompression methods
49769	 * @param str The string to encode
49770	 * @param latin1 Whether or not to interpret the data as Latin-1. This should
49771	 *               not need to be true unless decoding a binary string.
49772	 * @returns The string encoded in UTF-8/Latin-1 binary
49773	 */ function strToU8(str, latin1) {
49774	    var i; 
49775	    if (te) return te.encode(str);
49776	    var l = str.length;
49777	    var ar = new u8(str.length + (str.length >> 1));
49778	    var ai = 0;
49779	    var w = function(v) {
49780	        ar[ai++] = v;
49781	    };
49782	    for(var i = 0; i < l; ++i){
49783	        if (ai + 5 > ar.length) {
49784	            var n = new u8(ai + 8 + (l - i << 1));
49785	            n.set(ar);
49786	            ar = n;
49787	        }
49788	        var c = str.charCodeAt(i);
49789	        if (c < 128 || latin1) w(c);
49790	        else if (c < 2048) w(192 | c >> 6), w(128 | c & 63);
49791	        else if (c > 55295 && c < 57344) c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
49792	        else w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
49793	    }
49794	    return slc(ar, 0, ai);
49795	}
49796	// extra field length
49797	var exfl = function(ex) {
49798	    var le = 0;
49799	    if (ex) {
49800	        for(var k in ex){
49801	            var l = ex[k].length;
49802	            if (l > 65535) err(9);
49803	            le += l + 4;
49804	        }
49805	    }
49806	    return le;
49807	};
49808	// write zip header
49809	var wzh = function(d, b, f, fn, u, c, ce, co) {
49810	    var fl = fn.length, ex = f.extra, col = co && co.length;
49811	    var exl = exfl(ex);
49812	    wbytes(d, b, ce != null ? 0x2014B50 : 0x4034B50), b += 4;
49813	    if (ce != null) d[b++] = 20, d[b++] = f.os;
49814	    d[b] = 20, b += 2; // spec compliance? what's that?
49815	    d[b++] = f.flag << 1 | (c < 0 && 8), d[b++] = u && 8;
49816	    d[b++] = f.compression & 255, d[b++] = f.compression >> 8;
49817	    var dt = new Date(f.mtime == null ? Date.now() : f.mtime), y = dt.getFullYear() - 1980;
49818	    if (y < 0 || y > 119) err(10);
49819	    wbytes(d, b, y << 25 | dt.getMonth() + 1 << 21 | dt.getDate() << 16 | dt.getHours() << 11 | dt.getMinutes() << 5 | dt.getSeconds() >> 1), b += 4;
49820	    if (c != -1) {
49821	        wbytes(d, b, f.crc);
49822	        wbytes(d, b + 4, c < 0 ? -c - 2 : c);
49823	        wbytes(d, b + 8, f.size);
49824	    }
49825	    wbytes(d, b + 12, fl);
49826	    wbytes(d, b + 14, exl), b += 16;
49827	    if (ce != null) {
49828	        wbytes(d, b, col);
49829	        wbytes(d, b + 6, f.attrs);
49830	        wbytes(d, b + 10, ce), b += 14;
49831	    }
49832	    d.set(fn, b);
49833	    b += fl;
49834	    if (exl) {
49835	        for(var k in ex){
49836	            var exf = ex[k], l = exf.length;
49837	            wbytes(d, b, +k);
49838	            wbytes(d, b + 2, l);
49839	            d.set(exf, b + 4), b += 4 + l;
49840	        }
49841	    }
49842	    if (col) d.set(co, b), b += col;
49843	    return b;
49844	};
49845	// write zip footer (end of central directory)
49846	var wzf = function(o, b, c, d, e) {
49847	    wbytes(o, b, 0x6054B50); // skip disk
49848	    wbytes(o, b + 8, c);
49849	    wbytes(o, b + 10, c);
49850	    wbytes(o, b + 12, d);
49851	    wbytes(o, b + 16, e);
49852	};
49853	/**
49854	 * Synchronously creates a ZIP file. Prefer using `zip` for better performance
49855	 * with more than one file.
49856	 * @param data The directory structure for the ZIP archive
49857	 * @param opts The main options, merged with per-file options
49858	 * @returns The generated ZIP archive
49859	 */ function zipSync(data, opts) {
49860	    if (!opts) opts = {};
49861	    var r = {};
49862	    var files = [];
49863	    fltn(data, '', r, opts);
49864	    var o = 0;
49865	    var tot = 0;
49866	    for(var fn in r){
49867	        var _a = r[fn], file = _a[0], p = _a[1];
49868	        var compression = p.level == 0 ? 0 : 8;
49869	        var f = strToU8(fn), s = f.length;
49870	        var com = p.comment, m = com && strToU8(com), ms = m && m.length;
49871	        var exl = exfl(p.extra);
49872	        if (s > 65535) err(11);
49873	        var d = compression ? deflateSync(file, p) : file, l = d.length;
49874	        var c = crc();
49875	        c.p(file);
49876	        files.push(mrg(p, {
49877	            size: file.length,
49878	            crc: c.d(),
49879	            c: d,
49880	            f: f,
49881	            m: m,
49882	            u: s != fn.length || m && com.length != ms,
49883	            o: o,
49884	            compression: compression
49885	        }));
49886	        o += 30 + s + exl + l;
49887	        tot += 76 + 2 * (s + exl) + (ms || 0) + l;
49888	    }
49889	    var out = new u8(tot + 22), oe = o, cdl = tot - o;
49890	    for(var i = 0; i < files.length; ++i){
49891	        var f = files[i];
49892	        wzh(out, f.o, f, f.f, f.u, f.c.length);
49893	        var badd = 30 + f.f.length + exfl(f.extra);
49894	        out.set(f.c, f.o + badd);
49895	        wzh(out, o, f, f.f, f.u, f.c.length, f.o, f.m), o += 16 + badd + (f.m ? f.m.length : 0);
49896	    }
49897	    wzf(out, o, files.length, cdl, oe);
49898	    return out;
49899	}
49900
49901	class USDZExporter {
49902	    setTextureUtils(utils) {
49903	        this.textureUtils = utils;
49904	    }
49905	    parse(scene, onDone, onError, options) {
49906	        this.parseAsync(scene, options).then(onDone).catch(onError);
49907	    }
49908	    async parseAsync(scene, options = {}) {
49909	        options = Object.assign({
49910	            ar: {
49911	                anchoring: {
49912	                    type: 'plane'
49913	                },
49914	                planeAnchoring: {
49915	                    alignment: 'horizontal'
49916	                }
49917	            },
49918	            includeAnchoringProperties: true,
49919	            quickLookCompatible: false,
49920	            maxTextureSize: 1024
49921	        }, options);
49922	        const files = {};
49923	        const modelFileName = 'model.usda';
49924	        // model file should be first in USDZ archive so we init it here
49925	        files[modelFileName] = null;
49926	        let output = buildHeader();
49927	        output += buildSceneStart(options);
49928	        const materials = {};
49929	        const textures = {};
49930	        scene.traverseVisible((object)=>{
49931	            if (object.isMesh) {
49932	                const geometry = object.geometry;
49933	                const material = object.material;
49934	                if (material.isMeshStandardMaterial) {
49935	                    const geometryFileName = 'geometries/Geometry_' + geometry.id + '.usda';
49936	                    if (!(geometryFileName in files)) {
49937	                        const meshObject = buildMeshObject(geometry);
49938	                        files[geometryFileName] = buildUSDFileAsString(meshObject);
49939	                    }
49940	                    if (!(material.uuid in materials)) {
49941	                        materials[material.uuid] = material;
49942	                    }
49943	                    output += buildXform(object, geometry, material);
49944	                } else {
49945	                    console.warn('THREE.USDZExporter: Unsupported material type (USDZ only supports MeshStandardMaterial)', object);
49946	                }
49947	            } else if (object.isCamera) {
49948	                output += buildCamera(object);
49949	            }
49950	        });
49951	        output += buildSceneEnd();
49952	        output += buildMaterials(materials, textures, options.quickLookCompatible);
49953	        files[modelFileName] = strToU8(output);
49954	        output = null;
49955	        for(const id in textures){
49956	            let texture = textures[id];
49957	            if (texture.isCompressedTexture === true) {
49958	                if (this.textureUtils === null) {
49959	                    throw new Error('THREE.USDZExporter: setTextureUtils() must be called to process compressed textures.');
49960	                } else {
49961	                    texture = await this.textureUtils.decompress(texture);
49962	                }
49963	            }
49964	            const canvas = imageToCanvas(texture.image, texture.flipY, options.maxTextureSize);
49965	            const blob = await new Promise((resolve)=>canvas.toBlob(resolve, 'image/png', 1));
49966	            files[`textures/Texture_${id}.png`] = new Uint8Array(await blob.arrayBuffer());
49967	        }
49968	        // 64 byte alignment
49969	        // https://github.com/101arrowz/fflate/issues/39#issuecomment-777263109
49970	        let offset = 0;
49971	        for(const filename in files){
49972	            const file = files[filename];
49973	            const headerSize = 34 + filename.length;
49974	            offset += headerSize;
49975	            const offsetMod64 = offset & 63;
49976	            if (offsetMod64 !== 4) {
49977	                const padLength = 64 - offsetMod64;
49978	                const padding = new Uint8Array(padLength);
49979	                files[filename] = [
49980	                    file,
49981	                    {
49982	                        extra: {
49983	                            12345: padding
49984	                        }
49985	                    }
49986	                ];
49987	            }
49988	            offset = file.length;
49989	        }
49990	        return zipSync(files, {
49991	            level: 0
49992	        });
49993	    }
49994	    constructor(){
49995	        this.textureUtils = null;
49996	    }
49997	}
49998	function imageToCanvas(image, flipY, maxTextureSize) {
49999	    if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof OffscreenCanvas !== 'undefined' && image instanceof OffscreenCanvas || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
50000	        const scale = maxTextureSize / Math.max(image.width, image.height);
50001	        const canvas = document.createElement('canvas');
50002	        canvas.width = image.width * Math.min(1, scale);
50003	        canvas.height = image.height * Math.min(1, scale);
50004	        const context = canvas.getContext('2d');
50005	        // TODO: We should be able to do this in the UsdTransform2d?
50006	        if (flipY === true) {
50007	            context.translate(0, canvas.height);
50008	            context.scale(1, -1);
50009	        }
50010	        context.drawImage(image, 0, 0, canvas.width, canvas.height);
50011	        return canvas;
50012	    } else {
50013	        throw new Error('THREE.USDZExporter: No valid image data found. Unable to process texture.');
50014	    }
50015	}
50016	//
50017	const PRECISION = 7;
50018	function buildHeader() {
50019	    return `#usda 1.0
50020(
50021	customLayerData = {
50022		string creator = "Three.js USDZExporter"
50023	}
50024	defaultPrim = "Root"
50025	metersPerUnit = 1
50026	upAxis = "Y"
50027)
50028
50029`;
50030	}
50031	function buildSceneStart(options) {
50032	    const alignment = options.includeAnchoringProperties === true ? `
50033		token preliminary:anchoring:type = "${options.ar.anchoring.type}"
50034		token preliminary:planeAnchoring:alignment = "${options.ar.planeAnchoring.alignment}"
50035	` : '';
50036	    return `def Xform "Root"
50037{
50038	def Scope "Scenes" (
50039		kind = "sceneLibrary"
50040	)
50041	{
50042		def Xform "Scene" (
50043			customData = {
50044				bool preliminary_collidesWithEnvironment = 0
50045				string sceneName = "Scene"
50046			}
50047			sceneName = "Scene"
50048		)
50049		{${alignment}
50050`;
50051	}
50052	function buildSceneEnd() {
50053	    return `
50054		}
50055	}
50056}
50057
50058`;
50059	}
50060	function buildUSDFileAsString(dataToInsert) {
50061	    let output = buildHeader();
50062	    output += dataToInsert;
50063	    return strToU8(output);
50064	}
50065	// Xform
50066	function buildXform(object, geometry, material) {
50067	    const name = 'Object_' + object.id;
50068	    const transform = buildMatrix(object.matrixWorld);
50069	    if (object.matrixWorld.determinant() < 0) {
50070	        console.warn('THREE.USDZExporter: USDZ does not support negative scales', object);
50071	    }
50072	    return `def Xform "${name}" (
50073	prepend references = @./geometries/Geometry_${geometry.id}.usda@</Geometry>
50074	prepend apiSchemas = ["MaterialBindingAPI"]
50075)
50076{
50077	matrix4d xformOp:transform = ${transform}
50078	uniform token[] xformOpOrder = ["xformOp:transform"]
50079
50080	rel material:binding = </Materials/Material_${material.id}>
50081}
50082
50083`;
50084	}
50085	function buildMatrix(matrix) {
50086	    const array = matrix.elements;
50087	    return `( ${buildMatrixRow(array, 0)}, ${buildMatrixRow(array, 4)}, ${buildMatrixRow(array, 8)}, ${buildMatrixRow(array, 12)} )`;
50088	}
50089	function buildMatrixRow(array, offset) {
50090	    return `(${array[offset + 0]}, ${array[offset + 1]}, ${array[offset + 2]}, ${array[offset + 3]})`;
50091	}
50092	// Mesh
50093	function buildMeshObject(geometry) {
50094	    const mesh = buildMesh(geometry);
50095	    return `
50096def "Geometry"
50097{
50098${mesh}
50099}
50100`;
50101	}
50102	function buildMesh(geometry) {
50103	    const name = 'Geometry';
50104	    const attributes = geometry.attributes;
50105	    const count = attributes.position.count;
50106	    return `
50107	def Mesh "${name}"
50108	{
50109		int[] faceVertexCounts = [${buildMeshVertexCount(geometry)}]
50110		int[] faceVertexIndices = [${buildMeshVertexIndices(geometry)}]
50111		normal3f[] normals = [${buildVector3Array(attributes.normal, count)}] (
50112			interpolation = "vertex"
50113		)
50114		point3f[] points = [${buildVector3Array(attributes.position, count)}
50114]
50115${buildPrimvars(attributes)}
50116		uniform token subdivisionScheme = "none"
50117	}
50118`;
50119	}
50120	function buildMeshVertexCount(geometry) {
50121	    const count = geometry.index !== null ? geometry.index.count : geometry.attributes.position.count;
50122	    return Array(count / 3).fill(3).join(', ');
50123	}
50124	function buildMeshVertexIndices(geometry) {
50125	    const index = geometry.index;
50126	    const array = [];
50127	    if (index !== null) {
50128	        for(let i = 0; i < index.count; i++){
50129	            array.push(index.getX(i));
50130	        }
50131	    } else {
50132	        const length = geometry.attributes.position.count;
50133	        for(let i = 0; i < length; i++){
50134	            array.push(i);
50135	        }
50136	    }
50137	    return array.join(', ');
50138	}
50139	function buildVector3Array(attribute, count) {
50140	    if (attribute === undefined) {
50141	        console.warn('USDZExporter: Normals missing.');
50142	        return Array(count).fill('(0, 0, 0)').join(', ');
50143	    }
50144	    const array = [];
50145	    for(let i = 0; i < attribute.count; i++){
50146	        const x = attribute.getX(i);
50147	        const y = attribute.getY(i);
50148	        const z = attribute.getZ(i);
50149	        array.push(`(${x.toPrecision(PRECISION)}, ${y.toPrecision(PRECISION)}, ${z.toPrecision(PRECISION)})`);
50150	    }
50151	    return array.join(', ');
50152	}
50153	function buildVector2Array(attribute) {
50154	    const array = [];
50155	    for(let i = 0; i < attribute.count; i++){
50156	        const x = attribute.getX(i);
50157	        const y = attribute.getY(i);
50158	        array.push(`(${x.toPrecision(PRECISION)}, ${1 - y.toPrecision(PRECISION)})`);
50159	    }
50160	    return array.join(', ');
50161	}
50162	function buildPrimvars(attributes) {
50163	    let string = '';
50164	    for(let i = 0; i < 4; i++){
50165	        const id = i > 0 ? i : '';
50166	        const attribute = attributes['uv' + id];
50167	        if (attribute !== undefined) {
50168	            string += `
50169		texCoord2f[] primvars:st${id} = [${buildVector2Array(attribute)}] (
50170			interpolation = "vertex"
50171		)`;
50172	        }
50173	    }
50174	    // vertex colors
50175	    const colorAttribute = attributes.color;
50176	    if (colorAttribute !== undefined) {
50177	        const count = colorAttribute.count;
50178	        string += `
50179	color3f[] primvars:displayColor = [${buildVector3Array(colorAttribute, count)}] (
50180		interpolation = "vertex"
50181		)`;
50182	    }
50183	    return string;
50184	}
50185	// Materials
50186	function buildMaterials(materials, textures, quickLookCompatible = false) {
50187	    const array = [];
50188	    for(const uuid in materials){
50189	        const material = materials[uuid];
50190	        array.push(buildMaterial(material, textures, quickLookCompatible));
50191	    }
50192	    return `def "Materials"
50193{
50194${array.join('')}
50195}
50196
50197`;
50198	}
50199	function buildMaterial(material, textures, quickLookCompatible = false) {
50200	    // https://graphics.pixar.com/usd/docs/UsdPreviewSurface-Proposal.html
50201	    const pad = '			';
50202	    const inputs = [];
50203	    const samplers = [];
50204	    function buildTexture(texture, mapType, color) {
50205	        const id = texture.source.id + '_' + texture.flipY;
50206	        textures[id] = texture;
50207	        const uv = texture.channel > 0 ? 'st' + texture.channel : 'st';
50208	        const WRAPPINGS = {
50209	            1000: 'repeat',
50210	            1001: 'clamp',
50211	            1002: 'mirror' // MirroredRepeatWrapping
50212	        };
50213	        const repeat = texture.repeat.clone();
50214	        const offset = texture.offset.clone();
50215	        const rotation = texture.rotation;
50216	        // rotation is around the wrong point. after rotation we need to shift offset again so that we're rotating around the right spot
50217	        const xRotationOffset = Math.sin(rotation);
50218	        const yRotationOffset = Math.cos(rotation);
50219	        // texture coordinates start in the opposite corner, need to correct
50220	        offset.y = 1 - offset.y - repeat.y;
50221	        // turns out QuickLook is buggy and interprets texture repeat inverted/applies operations in a different order.
50222	        // Apple Feedback: 	FB10036297 and FB11442287
50223	        if (quickLookCompatible) {
50224	            // This is NOT correct yet in QuickLook, but comes close for a range of models.
50225	            // It becomes more incorrect the bigger the offset is
50226	            offset.x = offset.x / repeat.x;
50227	            offset.y = offset.y / repeat.y;
50228	            offset.x += xRotationOffset / repeat.x;
50229	            offset.y += yRotationOffset - 1;
50230	        } else {
50231	            // results match glTF results exactly. verified correct in usdview.
50232	            offset.x += xRotationOffset * repeat.x;
50233	            offset.y += (1 - yRotationOffset) * repeat.y;
50234	        }
50235	        return `
50236		def Shader "PrimvarReader_${mapType}"
50237		{
50238			uniform token info:id = "UsdPrimvarReader_float2"
50239			float2 inputs:fallback = (0.0, 0.0)
50240			token inputs:varname = "${uv}"
50241			float2 outputs:result
50242		}
50243
50244		def Shader "Transform2d_${mapType}"
50245		{
50246			uniform token info:id = "UsdTransform2d"
50247			token inputs:in.connect = </Materials/Material_${material.id}/PrimvarReader_${mapType}.outputs:result>
50248			float inputs:rotation = ${(rotation * (180 / Math.PI)).toFixed(PRECISION)}
50249			float2 inputs:scale = ${buildVector2(repeat)}
50250			float2 inputs:translation = ${buildVector2(offset)}
50251			float2 outputs:result
50252		}
50253
50254		def Shader "Texture_${texture.id}_${mapType}"
50255		{
50256			uniform token info:id = "UsdUVTexture"
50257			asset inputs:file = @textures/Texture_${id}.png@
50258			float2 inputs:st.connect = </Materials/Material_${material.id}/Transform2d_${mapType}.outputs:result>
50259			${color !== undefined ? 'float4 inputs:scale = ' + buildColor4(color) : ''}
50260			token inputs:sourceColorSpace = "${texture.colorSpace === NoColorSpace ? 'raw' : 'sRGB'}"
50261			token inputs:wrapS = "${WRAPPINGS[texture.wrapS]}"
50262			token inputs:wrapT = "${WRAPPINGS[texture.wrapT]}"
50263			float outputs:r
50264			float outputs:g
50265			float outputs:b
50266			float3 outputs:rgb
50267			${material.transparent || material.alphaTest > 0.0 ? 'float outputs:a' : ''}
50268		}`;
50269	    }
50270	    if (material.side === DoubleSide) {
50271	        console.warn('THREE.USDZExporter: USDZ does not support double sided materials', material);
50272	    }
50273	    if (material.map !== null) {
50274	        inputs.push(`${pad}color3f inputs:diffuseColor.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:rgb>`);
50275	        if (material.transparent) {
50276	            inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`);
50277	        } else if (material.alphaTest > 0.0) {
50278	            inputs.push(`${pad}float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.map.id}_diffuse.outputs:a>`);
50279	            inputs.push(`${pad}float inputs:opacityThreshold = ${material.alphaTest}`);
50280	        }
50281	        samplers.push(buildTexture(material.map, 'diffuse', material.color));
50282	    } else {
50283	        inputs.push(`${pad}color3f inputs:diffuseColor = ${buildColor(material.color)}`);
50284	    }
50285	    if (material.emissiveMap !== null) {
50286	        inputs.push(`${pad}color3f inputs:emissiveColor.connect = </Materials/Material_${material.id}/Texture_${material.emissiveMap.id}_emissive.outputs:rgb>`);
50287	        samplers.push(buildTexture(material.emissiveMap, 'emissive', new Color(material.emissive.r * material.emissiveIntensity, material.emissive.g * material.emissiveIntensity, material.emissive.b * material.emissiveIntensity)));
50288	    } else if (material.emissive.getHex() > 0) {
50289	        inputs.push(`${pad}color3f inputs:emissiveColor = ${buildColor(material.emissive)}`);
50290	    }
50291	    if (material.normalMap !== null) {
50292	        inputs.push(`${pad}normal3f inputs:normal.connect = </Materials/Material_${material.id}/Texture_${material.normalMap.id}_normal.outputs:rgb>`);
50293	        samplers.push(buildTexture(material.normalMap, 'normal'));
50294	    }
50295	    if (material.aoMap !== null) {
50296	        inputs.push(`${pad}float inputs:occlusion.connect = </Materials/Material_${material.id}/Texture_${material.aoMap.id}_occlusion.outputs:r>`);
50297	        samplers.push(buildTexture(material.aoMap, 'occlusion', new Color(material.aoMapIntensity, material.aoMapIntensity, material.aoMapIntensity)));
50298	    }
50299	    if (material.roughnessMap !== null) {
50300	        inputs.push(`${pad}float inputs:roughness.connect = </Materials/Material_${material.id}/Texture_${material.roughnessMap.id}_roughness.outputs:g>`);
50301	        samplers.push(buildTexture(material.roughnessMap, 'roughness', new Color(material.roughness, material.roughness, material.roughness)));
50302	    } else {
50303	        inputs.push(`${pad}float inputs:roughness = ${material.roughness}`);
50304	    }
50305	    if (material.metalnessMap !== null) {
50306	        inputs.push(`${pad}float inputs:metallic.connect = </Materials/Material_${material.id}/Texture_${material.metalnessMap.id}_metallic.outputs:b>`);
50307	        samplers.push(buildTexture(material.metalnessMap, 'metallic', new Color(material.metalness, material.metalness, material.metalness)));
50308	    } else {
50309	        inputs.push(`${pad}float inputs:metallic = ${material.metalness}`);
50310	    }
50311	    if (material.alphaMap !== null) {
50312	        inputs.push(`${pad}
50312float inputs:opacity.connect = </Materials/Material_${material.id}/Texture_${material.alphaMap.id}_opacity.outputs:r>`);
50313	        inputs.push(`${pad}float inputs:opacityThreshold = 0.0001`);
50314	        samplers.push(buildTexture(material.alphaMap, 'opacity'));
50315	    } else {
50316	        inputs.push(`${pad}float inputs:opacity = ${material.opacity}`);
50317	    }
50318	    if (material.isMeshPhysicalMaterial) {
50319	        if (material.clearcoatMap !== null) {
50320	            inputs.push(`${pad}float inputs:clearcoat.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatMap.id}_clearcoat.outputs:r>`);
50321	            samplers.push(buildTexture(material.clearcoatMap, 'clearcoat', new Color(material.clearcoat, material.clearcoat, material.clearcoat)));
50322	        } else {
50323	            inputs.push(`${pad}float inputs:clearcoat = ${material.clearcoat}`);
50324	        }
50325	        if (material.clearcoatRoughnessMap !== null) {
50326	            inputs.push(`${pad}float inputs:clearcoatRoughness.connect = </Materials/Material_${material.id}/Texture_${material.clearcoatRoughnessMap.id}_clearcoatRoughness.outputs:g>`);
50327	            samplers.push(buildTexture(material.clearcoatRoughnessMap, 'clearcoatRoughness', new Color(material.clearcoatRoughness, material.clearcoatRoughness, material.clearcoatRoughness)));
50328	        } else {
50329	            inputs.push(`${pad}float inputs:clearcoatRoughness = ${material.clearcoatRoughness}`);
50330	        }
50331	        inputs.push(`${pad}float inputs:ior = ${material.ior}`);
50332	    }
50333	    return `
50334	def Material "Material_${material.id}"
50335	{
50336		def Shader "PreviewSurface"
50337		{
50338			uniform token info:id = "UsdPreviewSurface"
50339${inputs.join('\n')}
50340			int inputs:useSpecularWorkflow = 0
50341			token outputs:surface
50342		}
50343
50344		token outputs:surface.connect = </Materials/Material_${material.id}/PreviewSurface.outputs:surface>
50345
50346${samplers.join('\n')}
50347
50348	}
50349`;
50350	}
50351	function buildColor(color) {
50352	    return `(${color.r}, ${color.g}, ${color.b})`;
50353	}
50354	function buildColor4(color) {
50355	    return `(${color.r}, ${color.g}, ${color.b}, 1.0)`;
50356	}
50357	function buildVector2(vector) {
50358	    return `(${vector.x}, ${vector.y})`;
50359	}
50360	function buildCamera(camera) {
50361	    const name = camera.name ? camera.name : 'Camera_' + camera.id;
50362	    const transform = buildMatrix(camera.matrixWorld);
50363	    if (camera.matrixWorld.determinant() < 0) {
50364	        console.warn('THREE.USDZExporter: USDZ does not support negative scales', camera);
50365	    }
50366	    if (camera.isOrthographicCamera) {
50367	        return `def Camera "${name}"
50368		{
50369			matrix4d xformOp:transform = ${transform}
50370			uniform token[] xformOpOrder = ["xformOp:transform"]
50371
50372			float2 clippingRange = (${camera.near.toPrecision(PRECISION)}, ${camera.far.toPrecision(PRECISION)})
50373			float horizontalAperture = ${((Math.abs(camera.left) + Math.abs(camera.right)) * 10).toPrecision(PRECISION)}
50374			float verticalAperture = ${((Math.abs(camera.top) + Math.abs(camera.bottom)) * 10).toPrecision(PRECISION)}
50375			token projection = "orthographic"
50376		}
50377	
50378	`;
50379	    } else {
50380	        return `def Camera "${name}"
50381		{
50382			matrix4d xformOp:transform = ${transform}
50383			uniform token[] xformOpOrder = ["xformOp:transform"]
50384
50385			float2 clippingRange = (${camera.near.toPrecision(PRECISION)}, ${camera.far.toPrecision(PRECISION)})
50386			float focalLength = ${camera.getFocalLength().toPrecision(PRECISION)}
50387			float focusDistance = ${camera.focus.toPrecision(PRECISION)}
50388			float horizontalAperture = ${camera.getFilmWidth().toPrecision(PRECISION)}
50389			token projection = "perspective"
50390			float verticalAperture = ${camera.getFilmHeight().toPrecision(PRECISION)}
50391		}
50392	
50393	`;
50394	    }
50395	}
50396
50397	const enumerationDeserializer = (allowedNames)=>(valueString)=>{
50398	        try {
50399	            const expressions = parseExpressions(valueString);
50400	            const names = (expressions.length ? expressions[0].terms : []).filter((valueNode)=>valueNode && valueNode.type === 'ident').map((valueNode)=>valueNode.value).filter((name)=>allowedNames.indexOf(name) > -1);
50401	            return new Set(names);
50402	        } catch (_error) {}
50403	        return new Set();
50404	    };
50405
50406	var __decorate$2 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
50407	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
vendor: 11,770 bytes, lines 50408-50653
50408	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
50409	    return c > 3 && r && Object.defineProperty(target, key, r), r;
50410	};
50411	let isWebXRBlocked = false;
50412	let isSceneViewerBlocked = false;
50413	const noArViewerSigil = '#model-viewer-no-ar-fallback';
50414	const deserializeARModes = enumerationDeserializer([
50415	    'quick-look',
50416	    'scene-viewer',
50417	    'webxr',
50418	    'none'
50419	]);
50420	const DEFAULT_AR_MODES = 'webxr scene-viewer quick-look';
50421	const ARMode = {
50422	    QUICK_LOOK: 'quick-look',
50423	    SCENE_VIEWER: 'scene-viewer',
50424	    WEBXR: 'webxr',
50425	    NONE: 'none'
50426	};
50427	const $arButtonContainer = Symbol('arButtonContainer');
50428	const $enterARWithWebXR = Symbol('enterARWithWebXR');
50429	const $openSceneViewer = Symbol('openSceneViewer');
50430	const $openIOSARQuickLook = Symbol('openIOSARQuickLook');
50431	const $canActivateAR = Symbol('canActivateAR');
50432	const $arMode = Symbol('arMode');
50433	const $arModes = Symbol('arModes');
50434	const $arAnchor = Symbol('arAnchor');
50435	const $preload = Symbol('preload');
50436	const $onARButtonContainerClick = Symbol('onARButtonContainerClick');
50437	const $onARStatus = Symbol('onARStatus');
50438	const $onARTracking = Symbol('onARTracking');
50439	const $onARTap = Symbol('onARTap');
50440	const $selectARMode = Symbol('selectARMode');
50441	const $triggerLoad = Symbol('triggerLoad');
50442	const ARMixin = (ModelViewerElement)=>{
50443	    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
50444	    class ARModelViewerElement extends ModelViewerElement {
50445	        get canActivateAR() {
50446	            return this[$arMode] !== ARMode.NONE;
50447	        }
50448	        connectedCallback() {
50449	            super.connectedCallback();
50450	            this[$renderer].arRenderer.addEventListener('status', this[$onARStatus]);
50451	            this.setAttribute('ar-status', ARStatus.NOT_PRESENTING);
50452	            this[$renderer].arRenderer.addEventListener('tracking', this[$onARTracking]);
50453	            this[$arAnchor].addEventListener('message', this[$onARTap]);
50454	        }
50455	        disconnectedCallback() {
50456	            super.disconnectedCallback();
50457	            this[$renderer].arRenderer.removeEventListener('status', this[$onARStatus]);
50458	            this[$renderer].arRenderer.removeEventListener('tracking', this[$onARTracking]);
50459	            this[$arAnchor].removeEventListener('message', this[$onARTap]);
50460	        }
50461	        update(changedProperties) {
50462	            super.update(changedProperties);
50463	            if (changedProperties.has('arScale')) {
50464	                this[$scene].canScale = this.arScale !== 'fixed';
50465	            }
50466	            if (changedProperties.has('arPlacement')) {
50467	                this[$scene].updateShadow();
50468	                this[$needsRender]();
50469	            }
50470	            if (changedProperties.has('arModes')) {
50471	                this[$arModes] = deserializeARModes(this.arModes);
50472	            }
50473	            if (changedProperties.has('ar') || changedProperties.has('arModes') || changedProperties.has('src') || changedProperties.has('iosSrc') || changedProperties.has('arUsdzMaxTextureSize')) {
50474	                this[$selectARMode]();
50475	            }
50476	        }
50477	 async activateAR() {
50478	            switch(this[$arMode]){
50479	                case ARMode.QUICK_LOOK:
50480	                    await this[$openIOSARQuickLook]();
50481	                    break;
50482	                case ARMode.WEBXR:
50483	                    await this[$enterARWithWebXR]();
50484	                    break;
50485	                case ARMode.SCENE_VIEWER:
50486	                    this[$openSceneViewer]();
50487	                    break;
50488	                default:
50489	                    console.warn('No AR Mode can be activated. This is probably due to missing \
50490configuration or device capabilities');
50491	                    break;
50492	            }
50493	        }
50494	        async [(_a = $canActivateAR, _b = $arButtonContainer, _c = $arAnchor, _d = $arModes, _e = $arMode, _f = $preload, _g = $onARButtonContainerClick, _h = $onARStatus, _j = $onARTracking, _k = $onARTap, $selectARMode)]() {
50495	            var _l;
50496	            let arMode = ARMode.NONE;
50497	            if (this.ar) {
50498	                if (this.src != null) {
50499	                    for (const value of this[$arModes]){
50500	                        if (value === 'webxr' && IS_WEBXR_AR_CANDIDATE && !isWebXRBlocked && await this[$renderer].arRenderer.supportsPresentation()) {
50501	                            arMode = ARMode.WEBXR;
50502	                            break;
50503	                        }
50504	                        if (value === 'scene-viewer' && !isSceneViewerBlocked && (IS_SCENEVIEWER_CANDIDATE || navigator.userAgentData && navigator.userAgentData.getHighEntropyValues && ((_l = (await navigator.userAgentData.getHighEntropyValues([
50505	                            'formFactor'
50506	                        ])).formFactor) === null || _l === void 0 ? void 0 : _l.includes('XR')))) {
50507	                            arMode = ARMode.SCENE_VIEWER;
50508	                            break;
50509	                        }
50510	                        if (value === 'quick-look' && IS_AR_QUICKLOOK_CANDIDATE) {
50511	                            arMode = ARMode.QUICK_LOOK;
50512	                            break;
50513	                        }
50514	                    }
50515	                }
50516	                if (arMode === ARMode.NONE && this.iosSrc != null && IS_AR_QUICKLOOK_CANDIDATE) {
50517	                    arMode = ARMode.QUICK_LOOK;
50518	                }
50519	            }
50520	            if (arMode !== ARMode.NONE) {
50521	                this[$arButtonContainer].classList.add('enabled');
50522	                this[$arButtonContainer].addEventListener('click', this[$onARButtonContainerClick]);
50523	            } else if (this[$arButtonContainer].classList.contains('enabled')) {
50524	                this[$arButtonContainer].removeEventListener('click', this[$onARButtonContainerClick]);
50525	                this[$arButtonContainer].classList.remove('enabled');
50526	                const status = ARStatus.FAILED;
50527	                this.setAttribute('ar-status', status);
50528	                this.dispatchEvent(new CustomEvent('ar-status', {
50529	                    detail: {
50530	                        status
50531	                    }
50532	                }));
50533	            }
50534	            this[$arMode] = arMode;
50535	        }
50536	        async [$enterARWithWebXR]() {
50537	            console.log('Attempting to present in AR with WebXR...');
50538	            await this[$triggerLoad]();
50539	            try {
50540	                this[$arButtonContainer].removeEventListener('click', this[$onARButtonContainerClick]);
50541	                const { arRenderer } = this[$renderer];
50542	                arRenderer.placeOnWall = this.arPlacement === 'wall';
50543	                await arRenderer.present(this[$scene], this.xrEnvironment);
50544	            } catch (error) {
50545	                console.warn('Error while trying to present in AR with WebXR');
50546	                console.error(error);
50547	                await this[$renderer].arRenderer.stopPresenting();
50548	                isWebXRBlocked = true;
50549	                console.warn('Falling back to next ar-mode');
50550	                await this[$selectARMode]();
50551	                this.activateAR();
50552	            } finally{
50553	                this[$selectARMode]();
50554	            }
50555	        }
50556	        async [$triggerLoad]() {
50557	            if (!this.loaded) {
50558	                this[$preload] = true;
50559	                this[$updateSource]();
50560	                await waitForEvent(this, 'load');
50561	                this[$preload] = false;
50562	            }
50563	        }
50564	        [$shouldAttemptPreload]() {
50565	            return super[$shouldAttemptPreload]() || this[$preload];
50566	        }
50567	 [$openSceneViewer]() {
50568	            const location = self.location.toString();
50569	            const locationUrl = new URL(location);
50570	            const modelUrl = new URL(this.src, location);
50571	            if (modelUrl.hash) modelUrl.hash = '';
50572	            const params = new URLSearchParams(modelUrl.search);
50573	            locationUrl.hash = noArViewerSigil;
50574	            params.set('mode', 'ar_preferred');
50575	            if (!params.has('disable_occlusion')) {
50576	                params.set('disable_occlusion', 'true');
50577	            }
50578	            if (this.arScale === 'fixed') {
50579	                params.set('resizable', 'false');
50580	            }
50581	            if (this.arPlacement === 'wall') {
50582	                params.set('enable_vertical_placement', 'true');
50583	            }
50584	            if (params.has('sound')) {
50585	                const soundUrl = new URL(params.get('sound'), location);
50586	                params.set('sound', soundUrl.toString());
50587	            }
50588	            if (params.has('link')) {
50589	                const linkUrl = new URL(params.get('link'), location);
50590	                params.set('link', linkUrl.toString());
50591	            }
50592	            const intent = `intent://arvr.google.com/scene-viewer/1.2?${params.toString() + '&file=' + encodeURIComponent(modelUrl.toString())}#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;S.browser_fallback_url=${encodeURIComponent(locationUrl.toString())};end;`;
50593	            const undoHashChange = ()=>{
50594	                if (self.location.hash === noArViewerSigil) {
50595	                    isSceneViewerBlocked = true;
50596	                    self.history.back();
50597	                    console.warn('Error while trying to present in AR with Scene Viewer');
50598	                    console.warn('Falling back to next ar-mode');
50599	                    this[$selectARMode]();
50600	                }
50601	            };
50602	            self.addEventListener('hashchange', undoHashChange, {
50603	                once: true
50604	            });
50605	            this[$arAnchor].setAttribute('href', intent);
50606	            console.log('Attempting to present in AR with Scene Viewer...');
50607	            this[$arAnchor].click();
50608	        }
50609	 async [$openIOSARQuickLook]() {
50610	            const generateUsdz = !this.iosSrc;
50611	            this[$arButtonContainer].classList.remove('enabled');
50612	            const objectURL = generateUsdz ? await this.prepareUSDZ() : this.iosSrc;
50613	            const modelUrl = new URL(objectURL, self.location.toString());
50614	            if (generateUsdz) {
50615	                const location = self.location.toString();
50616	                const locationUrl = new URL(location);
50617	                const srcUrl = new URL(this.src, locationUrl);
50618	                if (srcUrl.hash) {
50619	                    modelUrl.hash = srcUrl.hash;
50620	                }
50621	            }
50622	            if (this.arScale === 'fixed') {
50623	                if (modelUrl.hash) {
50624	                    modelUrl.hash += '&';
50625	                }
50626	                modelUrl.hash += 'allowsContentScaling=0';
50627	            }
50628	            const anchor = this[$arAnchor];
50629	            anchor.setAttribute('rel', 'ar');
50630	            const img = document.createElement('img');
50631	            anchor.appendChild(img);
50632	            anchor.setAttribute('href', modelUrl.toString());
50633	            if (generateUsdz) {
50634	                anchor.setAttribute('download', 'model.usdz');
50635	            }
50636	            anchor.style.display = 'none';
50637	            if (!anchor.isConnected) this.shadowRoot.appendChild(anchor);
50638	            console.log('Attempting to present in AR with Quick Look...');
50639	            anchor.click();
50640	            anchor.removeChild(img);
50641	            if (generateUsdz) {
50642	                URL.revokeObjectURL(objectURL);
50643	            }
50644	            this[$arButtonContainer].classList.add('enabled');
50645	        }
50646	        async prepareUSDZ() {
50647	            const updateSourceProgress = this[$progressTracker].beginActivity('usdz-conversion');
50648	            await this[$triggerLoad]();
50649	            const { model, shadow, target } = this[$scene];
50650	            if (model == null) {
50651	                return '';
50652	            }
50653	            let visible = false;
vendor: 9,616 bytes, lines 50654-50880
50654	            if (shadow != null) {
50655	                visible = shadow.visible;
50656	                shadow.visible = false;
50657	            }
50658	            updateSourceProgress(0.2);
50659	            const exporter = new USDZExporter();
50660	            target.remove(model);
50661	            model.position.copy(target.position);
50662	            model.updateWorldMatrix(false, true);
50663	            const arraybuffer = await exporter.parseAsync(model, {
50664	                maxTextureSize: isNaN(this.arUsdzMaxTextureSize) ? Infinity : Math.max(parseInt(this.arUsdzMaxTextureSize), 16)
50665	            });
50666	            model.position.set(0, 0, 0);
50667	            target.add(model);
50668	            const blob = new Blob([
50669	                arraybuffer
50670	            ], {
50671	                type: 'model/vnd.usdz+zip'
50672	            });
50673	            const url = URL.createObjectURL(blob);
50674	            updateSourceProgress(1);
50675	            if (shadow != null) {
50676	                shadow.visible = visible;
50677	            }
50678	            return url;
50679	        }
50680	        constructor(){
50681	            super(...arguments);
50682	            this.ar = false;
50683	            this.arScale = 'auto';
50684	            this.arUsdzMaxTextureSize = 'auto';
50685	            this.arPlacement = 'floor';
50686	            this.arModes = DEFAULT_AR_MODES;
50687	            this.iosSrc = null;
50688	            this.xrEnvironment = false;
50689	            this[_a] = false;
50690	            this[_b] = this.shadowRoot.querySelector('.ar-button');
50691	            this[_c] = document.createElement('a');
50692	            this[_d] = new Set();
50693	            this[_e] = ARMode.NONE;
50694	            this[_f] = false;
50695	            this[_g] = (event)=>{
50696	                event.preventDefault();
50697	                this.activateAR();
50698	            };
50699	            this[_h] = ({ status })=>{
50700	                if (status === ARStatus.NOT_PRESENTING || this[$renderer].arRenderer.presentedScene === this[$scene]) {
50701	                    this.setAttribute('ar-status', status);
50702	                    this.dispatchEvent(new CustomEvent('ar-status', {
50703	                        detail: {
50704	                            status
50705	                        }
50706	                    }));
50707	                    if (status === ARStatus.NOT_PRESENTING) {
50708	                        this.removeAttribute('ar-tracking');
50709	                    } else if (status === ARStatus.SESSION_STARTED) {
50710	                        this.setAttribute('ar-tracking', ARTracking.TRACKING);
50711	                    }
50712	                }
50713	            };
50714	            this[_j] = ({ status })=>{
50715	                this.setAttribute('ar-tracking', status);
50716	                this.dispatchEvent(new CustomEvent('ar-tracking', {
50717	                    detail: {
50718	                        status
50719	                    }
50720	                }));
50721	            };
50722	            this[_k] = (event)=>{
50723	                if (event.data == '_apple_ar_quicklook_button_tapped') {
50724	                    this.dispatchEvent(new CustomEvent('quick-look-button-tapped'));
50725	                }
50726	            };
50727	        }
50728	    }
50729	    __decorate$2([
50730	        n$2({
50731	            type: Boolean,
50732	            attribute: 'ar'
50733	        })
50734	    ], ARModelViewerElement.prototype, "ar", void 0);
50735	    __decorate$2([
50736	        n$2({
50737	            type: String,
50738	            attribute: 'ar-scale'
50739	        })
50740	    ], ARModelViewerElement.prototype, "arScale", void 0);
50741	    __decorate$2([
50742	        n$2({
50743	            type: String,
50744	            attribute: 'ar-usdz-max-texture-size'
50745	        })
50746	    ], ARModelViewerElement.prototype, "arUsdzMaxTextureSize", void 0);
50747	    __decorate$2([
50748	        n$2({
50749	            type: String,
50750	            attribute: 'ar-placement'
50751	        })
50752	    ], ARModelViewerElement.prototype, "arPlacement", void 0);
50753	    __decorate$2([
50754	        n$2({
50755	            type: String,
50756	            attribute: 'ar-modes'
50757	        })
50758	    ], ARModelViewerElement.prototype, "arModes", void 0);
50759	    __decorate$2([
50760	        n$2({
50761	            type: String,
50762	            attribute: 'ios-src'
50763	        })
50764	    ], ARModelViewerElement.prototype, "iosSrc", void 0);
50765	    __decorate$2([
50766	        n$2({
50767	            type: Boolean,
50768	            attribute: 'xr-environment'
50769	        })
50770	    ], ARModelViewerElement.prototype, "xrEnvironment", void 0);
50771	    return ARModelViewerElement;
50772	};
50773
50774	var __decorate$1 = undefined && undefined.__decorate || function(decorators, target, key, desc) {
50775	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
50776	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
50777	    return c > 3 && r && Object.defineProperty(target, key, r), r;
50778	};
50779	const PROGRESS_BAR_UPDATE_THRESHOLD = 100;
50780	const DEFAULT_DRACO_DECODER_LOCATION = (window.explorexrPluginUrl || '/wp-content/plugins/explorexr/') + 'assets/vendor/draco/';
50781	const DEFAULT_KTX2_TRANSCODER_LOCATION = (window.explorexrPluginUrl || '/wp-content/plugins/explorexr/') + 'assets/vendor/basis-universal/';
50782	const DEFAULT_LOTTIE_LOADER_LOCATION = (window.explorexrPluginUrl || '/wp-content/plugins/explorexr/') + 'assets/vendor/three/LottieLoader.js';
50783	const RevealStrategy = {
50784	    AUTO: 'auto'};
50785	const LoadingStrategy = {
50786	    AUTO: 'auto',
50787	    EAGER: 'eager'
50788	};
50789	const $defaultProgressBarElement = Symbol('defaultProgressBarElement');
50790	const $posterContainerElement = Symbol('posterContainerElement');
50791	const $defaultPosterElement = Symbol('defaultPosterElement');
50792	const $shouldDismissPoster = Symbol('shouldDismissPoster');
50793	const $hidePoster = Symbol('hidePoster');
50794	const $modelIsRevealed = Symbol('modelIsRevealed');
50795	const $updateProgressBar = Symbol('updateProgressBar');
50796	const $ariaLabelCallToAction = Symbol('ariaLabelCallToAction');
50797	const $onProgress = Symbol('onProgress');
50798	 const LoadingMixin = (ModelViewerElement)=>{
50799	    var _a, _b, _c, _d, _e, _f, _g, _h;
50800	    class LoadingModelViewerElement extends ModelViewerElement {
50801	        static set dracoDecoderLocation(value) {
50802	            CachingGLTFLoader.setDRACODecoderLocation(value);
50803	        }
50804	        static get dracoDecoderLocation() {
50805	            return CachingGLTFLoader.getDRACODecoderLocation();
50806	        }
50807	        static set ktx2TranscoderLocation(value) {
50808	            CachingGLTFLoader.setKTX2TranscoderLocation(value);
50809	        }
50810	        static get ktx2TranscoderLocation() {
50811	            return CachingGLTFLoader.getKTX2TranscoderLocation();
50812	        }
50813	        static set meshoptDecoderLocation(value) {
50814	            CachingGLTFLoader.setMeshoptDecoderLocation(value);
50815	        }
50816	        static get meshoptDecoderLocation() {
50817	            return CachingGLTFLoader.getMeshoptDecoderLocation();
50818	        }
50819	        static set lottieLoaderLocation(value) {
50820	            Renderer.singleton.textureUtils.lottieLoaderUrl = value;
50821	        }
50822	        static get lottieLoaderLocation() {
50823	            return Renderer.singleton.textureUtils.lottieLoaderUrl;
50824	        }
50825	 static mapURLs(callback) {
50826	            Renderer.singleton.loader[$loader].manager.setURLModifier(callback);
50827	        }
50828	 dismissPoster() {
50829	            if (this.loaded) {
50830	                this[$hidePoster]();
50831	            } else {
50832	                this[$shouldDismissPoster] = true;
50833	                this[$updateSource]();
50834	            }
50835	        }
50836	 showPoster() {
50837	            const posterContainerElement = this[$posterContainerElement];
50838	            if (posterContainerElement.classList.contains('show')) {
50839	                return;
50840	            }
50841	            posterContainerElement.classList.add('show');
50842	            this[$userInputElement].classList.remove('show');
50843	            const defaultPosterElement = this[$defaultPosterElement];
50844	            defaultPosterElement.removeAttribute('tabindex');
50845	            defaultPosterElement.removeAttribute('aria-hidden');
50846	            const oldVisibility = this.modelIsVisible;
50847	            this[$modelIsRevealed] = false;
50848	            this[$announceModelVisibility](oldVisibility);
50849	        }
50850	 getDimensions() {
50851	            return toVector3D(this[$scene].size);
50852	        }
50853	        getBoundingBoxCenter() {
50854	            return toVector3D(this[$scene].boundingBox.getCenter(new Vector3()));
50855	        }
50856	        connectedCallback() {
50857	            super.connectedCallback();
50858	            if (!this.loaded) {
50859	                this.showPoster();
50860	            }
50861	            this[$progressTracker].addEventListener('progress', this[$onProgress]);
50862	        }
50863	        disconnectedCallback() {
50864	            super.disconnectedCallback();
50865	            this[$progressTracker].removeEventListener('progress', this[$onProgress]);
50866	        }
50867	        async updated(changedProperties) {
50868	            super.updated(changedProperties);
50869	            if (changedProperties.has('poster') && this.poster != null) {
50870	                this[$defaultPosterElement].style.backgroundImage = `url(${this.poster})`;
50871	            }
50872	            if (changedProperties.has('alt')) {
50873	                this[$defaultPosterElement].setAttribute('aria-label', this[$altDefaulted]);
50874	            }
50875	            if (changedProperties.has('reveal') || changedProperties.has('loading')) {
50876	                this[$updateSource]();
50877	            }
50878	        }
50879	        [(_a = $modelIsRevealed, _b = $shouldDismissPoster, _c = $posterContainerElement, _d = $defaultPosterElement, _e = $defaultProgressBarElement, _f = $ariaLabelCallToAction, _g = $updateProgressBar, _h = $onProgress, $shouldAttemptPreload)]() {
50880	            return !!this.src && (this[$shouldDismissPoster] || this.loading === LoadingStrategy.EAGE
vendor: 8,863 bytes, lines 50880-51086
50880R || this.reveal === RevealStrategy.AUTO && this[$isElementInViewport]);
50881	        }
50882	        [$hidePoster]() {
50883	            this[$shouldDismissPoster] = false;
50884	            const posterContainerElement = this[$posterContainerElement];
50885	            if (!posterContainerElement.classList.contains('show')) {
50886	                return;
50887	            }
50888	            posterContainerElement.classList.remove('show');
50889	            this[$userInputElement].classList.add('show');
50890	            const oldVisibility = this.modelIsVisible;
50891	            this[$modelIsRevealed] = true;
50892	            this[$announceModelVisibility](oldVisibility);
50893	            const root = this.getRootNode();
50894	            if (root && root.activeElement === this) {
50895	                this[$userInputElement].focus();
50896	            }
50897	            const defaultPosterElement = this[$defaultPosterElement];
50898	            defaultPosterElement.setAttribute('aria-hidden', 'true');
50899	            defaultPosterElement.tabIndex = -1;
50900	            this.dispatchEvent(new CustomEvent('poster-dismissed'));
50901	        }
50902	        [$getModelIsVisible]() {
50903	            return super[$getModelIsVisible]() && this[$modelIsRevealed];
50904	        }
50905	        constructor(...args){
50906	            super(...args);
50907	 this.poster = null;
50908	 this.reveal = RevealStrategy.AUTO;
50909	 this.loading = LoadingStrategy.AUTO;
50910	            this[_a] = false;
50911	            this[_b] = false;
50912	            this[_c] = this.shadowRoot.querySelector('.slot.poster');
50913	            this[_d] = this.shadowRoot.querySelector('#default-poster');
50914	            this[_e] = this.shadowRoot.querySelector('#default-progress-bar > .bar');
50915	            this[_f] = this[$defaultPosterElement].getAttribute('aria-label');
50916	            this[_g] = throttle((progress)=>{
50917	                const parentNode = this[$defaultProgressBarElement].parentNode;
50918	                requestAnimationFrame(()=>{
50919	                    this[$defaultProgressBarElement].style.transform = `scaleX(${progress})`;
50920	                    if (progress === 0) {
50921	                        parentNode.removeChild(this[$defaultProgressBarElement]);
50922	                        parentNode.appendChild(this[$defaultProgressBarElement]);
50923	                    }
50924	                    this[$defaultProgressBarElement].classList.toggle('hide', progress === 1.0);
50925	                });
50926	            }, PROGRESS_BAR_UPDATE_THRESHOLD);
50927	            this[_h] = (event)=>{
50928	                const progress = event.detail.totalProgress;
50929	                const reason = event.detail.reason;
50930	                if (progress === 1.0) {
50931	                    this[$updateProgressBar].flush();
50932	                    if (this.loaded && (this[$shouldDismissPoster] || this.reveal === RevealStrategy.AUTO)) {
50933	                        this[$hidePoster]();
50934	                    }
50935	                }
50936	                this[$updateProgressBar](progress);
50937	                this.dispatchEvent(new CustomEvent('progress', {
50938	                    detail: {
50939	                        totalProgress: progress,
50940	                        reason
50941	                    }
50942	                }));
50943	            };
50944	            const ModelViewerElement = self.ModelViewerElement || {};
50945	            const dracoDecoderLocation = ModelViewerElement.dracoDecoderLocation || DEFAULT_DRACO_DECODER_LOCATION;
50946	            CachingGLTFLoader.setDRACODecoderLocation(dracoDecoderLocation);
50947	            const ktx2TranscoderLocation = ModelViewerElement.ktx2TranscoderLocation || DEFAULT_KTX2_TRANSCODER_LOCATION;
50948	            CachingGLTFLoader.setKTX2TranscoderLocation(ktx2TranscoderLocation);
50949	            if (ModelViewerElement.meshoptDecoderLocation) {
50950	                CachingGLTFLoader.setMeshoptDecoderLocation(ModelViewerElement.meshoptDecoderLocation);
50951	            }
50952	            const lottieLoaderLocation = ModelViewerElement.lottieLoaderLocation || DEFAULT_LOTTIE_LOADER_LOCATION;
50953	            Renderer.singleton.textureUtils.lottieLoaderUrl = lottieLoaderLocation;
50954	        }
50955	    }
50956	    __decorate$1([
50957	        n$2({
50958	            type: String
50959	        })
50960	    ], LoadingModelViewerElement.prototype, "poster", void 0);
50961	    __decorate$1([
50962	        n$2({
50963	            type: String
50964	        })
50965	    ], LoadingModelViewerElement.prototype, "reveal", void 0);
50966	    __decorate$1([
50967	        n$2({
50968	            type: String
50969	        })
50970	    ], LoadingModelViewerElement.prototype, "loading", void 0);
50971	    return LoadingModelViewerElement;
50972	};
50973
50974	var __decorate = undefined && undefined.__decorate || function(decorators, target, key, desc) {
50975	    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
50976	    for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
50977	    return c > 3 && r && Object.defineProperty(target, key, r), r;
50978	};
50979	const DEFAULT_ROTATION_SPEED = Math.PI / 32;
50980	const AUTO_ROTATE_DELAY_DEFAULT = 3000;
50981	const rotationRateIntrinsics = {
50982	    basis: [
50983	        degreesToRadians(numberNode(DEFAULT_ROTATION_SPEED, 'rad'))
50984	    ],
50985	    keywords: {
50986	        auto: [
50987	            null
50988	        ]
50989	    }
50990	};
50991	const $autoRotateStartTime = Symbol('autoRotateStartTime');
50992	const $radiansPerSecond = Symbol('radiansPerSecond');
50993	const $syncRotationRate = Symbol('syncRotationRate');
50994	const $onCameraChange = Symbol('onCameraChange');
50995	const StagingMixin = (ModelViewerElement)=>{
50996	    var _a, _b, _c;
50997	    class StagingModelViewerElement extends ModelViewerElement {
50998	        connectedCallback() {
50999	            super.connectedCallback();
51000	            this.addEventListener('camera-change', this[$onCameraChange]);
51001	            this[$autoRotateStartTime] = performance.now();
51002	        }
51003	        disconnectedCallback() {
51004	            super.disconnectedCallback();
51005	            this.removeEventListener('camera-change', this[$onCameraChange]);
51006	            this[$autoRotateStartTime] = performance.now();
51007	        }
51008	        updated(changedProperties) {
51009	            super.updated(changedProperties);
51010	            if (changedProperties.has('autoRotate')) {
51011	                this[$autoRotateStartTime] = performance.now();
51012	            }
51013	        }
51014	        [(_a = $autoRotateStartTime, _b = $radiansPerSecond, $syncRotationRate)](style) {
51015	            this[$radiansPerSecond] = style[0];
51016	        }
51017	        [$tick](time, delta) {
51018	            super[$tick](time, delta);
51019	            if (!this.autoRotate || !this[$getModelIsVisible]() || this[$renderer].isPresenting) {
51020	                return;
51021	            }
51022	            const rotationDelta = Math.min(delta, time - this[$autoRotateStartTime] - this.autoRotateDelay);
51023	            if (rotationDelta > 0) {
51024	                this[$scene].yaw = this.turntableRotation + this[$radiansPerSecond] * rotationDelta * 0.001;
51025	            }
51026	        }
51027	        get turntableRotation() {
51028	            return this[$scene].yaw;
51029	        }
51030	        resetTurntableRotation(theta = 0) {
51031	            this[$scene].yaw = theta;
51032	        }
51033	        constructor(){
51034	            super(...arguments);
51035	            this.autoRotate = false;
51036	            this.autoRotateDelay = AUTO_ROTATE_DELAY_DEFAULT;
51037	            this.rotationPerSecond = 'auto';
51038	            this[_a] = performance.now();
51039	            this[_b] = 0;
51040	            this[_c] = (event)=>{
51041	                if (!this.autoRotate) {
51042	                    return;
51043	                }
51044	                if (event.detail.source === 'user-interaction') {
51045	                    this[$autoRotateStartTime] = performance.now();
51046	                }
51047	            };
51048	        }
51049	    }
51050	    _c = $onCameraChange;
51051	    __decorate([
51052	        n$2({
51053	            type: Boolean,
51054	            attribute: 'auto-rotate'
51055	        })
51056	    ], StagingModelViewerElement.prototype, "autoRotate", void 0);
51057	    __decorate([
51058	        n$2({
51059	            type: Number,
51060	            attribute: 'auto-rotate-delay'
51061	        })
51062	    ], StagingModelViewerElement.prototype, "autoRotateDelay", void 0);
51063	    __decorate([
51064	        style({
51065	            intrinsics: rotationRateIntrinsics,
51066	            updateHandler: $syncRotationRate
51067	        }),
51068	        n$2({
51069	            type: String,
51070	            attribute: 'rotation-per-second'
51071	        })
51072	    ], StagingModelViewerElement.prototype, "rotationPerSecond", void 0);
51073	    return StagingModelViewerElement;
51074	};
51075
51076	const ModelViewerElement = AnnotationMixin(SceneGraphMixin(StagingMixin(EnvironmentMixin(ControlsMixin(ARMixin(LoadingMixin(AnimationMixin(ModelViewerElementBase))))))));
51077	customElements.define('model-viewer', ModelViewerElement);
51078
51079	exports.CanvasTexture = CanvasTexture;
51080	exports.FileLoader = FileLoader;
51081	exports.Loader = Loader;
51082	exports.ModelViewerElement = ModelViewerElement;
51083	exports.NearestFilter = NearestFilter;
51084
51085}));
51086//# sourceMappingURL=model-viewer-umd.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.