PageSourceSearch

https://www.vzome.com/modules/chunk-6JQSYMRV.js

js vzome.com collected 2026-10-02 07:04:48 UTC 298,004 bytes, 8,360 lines download raw bytes

1import {
2  ACESFilmicToneMapping,
3  AnimationClip,
4  BasicShadowMap,
5  Bone,
6  Box3,
7  BoxGeometry,
8  BufferAttribute,
9  BufferGeometry,
10  Camera,
11  ClampToEdgeWrapping,
12  Clock,
13  Color,
14  CompressedTexture,
15  DirectionalLight,
16  DoubleSide,
17  DynamicDrawUsage,
18  FileLoader,
19  FrontSide,
20  Group,
21  ImageBitmapLoader,
22  InstancedBufferAttribute,
23  InstancedMesh,
24  InterleavedBuffer,
25  InterleavedBufferAttribute,
26  Interpolant,
27  InterpolateDiscrete,
28  InterpolateLinear,
29  Line,
30  LineBasicMaterial,
31  LineLoop,
32  LineSegments,
33  LinearFilter,
34  LinearMipmapLinearFilter,
35  LinearMipmapNearestFilter,
36  LinearSRGBColorSpace,
37  Loader,
38  LoaderUtils,
39  MOUSE,
40  Material,
41  MathUtils,
42  Matrix4,
43  Mesh,
44  MeshBasicMaterial,
45  MeshPhysicalMaterial,
46  MeshStandardMaterial,
47  MirroredRepeatWrapping,
48  NearestFilter,
49  NearestMipmapLinearFilter,
50  NearestMipmapNearestFilter,
51  NoToneMapping,
52  NumberKeyframeTrack,
53  Object3D,
54  OrthographicCamera,
55  PCFShadowMap,
56  PCFSoftShadowMap,
57  PerspectiveCamera,
58  PlaneGeometry,
59  PointLight,
60  Points,
61  PointsMaterial,
62  PropertyBinding,
63  Quaternion,
64  QuaternionKeyframeTrack,
65  REVISION,
66  RGBAFormat,
67  Raycaster,
68  RepeatWrapping,
69  SRGBColorSpace,
70  Scene,
71  ShaderMaterial,
72  Show,
73  Skeleton,
74  SkinnedMesh,
75  Sphere,
76  SphereGeometry,
77  SpotLight,
78  Texture,
79  TextureLoader,
80  TriangleFanDrawMode,
81  TriangleStripDrawMode,
82  TrianglesDrawMode,
83  Uniform,
84  UnsignedByteType,
85  VSMShadowMap,
86  Vector2,
87  Vector3,
88  VectorKeyframeTrack,
89  WebGLRenderer,
90  children,
91  className,
92  createComponent,
93  createComputed,
94  createContext,
95  createEffect,
96  createMemo,
97  createRenderEffect,
98  createResource,
99  createRoot,
100  createSignal,
101  getOwner,
102  isServer,
103  mapArray,
104  memo,
105  mergeProps,
106  onCleanup,
107  onMount,
108  splitProps,
109  style,
110  template,
111  untrack,
112  use,
113  useContext
114} from "./chunk-47C2ISC4.js";
115
vendor: 1,053 bytes, lines 116-153
116// node_modules/solid-three/node_modules/@solid-primitives/utils/dist/index.js
117var noop = (() => void 0);
118var isNonNullable = (i) => i != null;
119var filterNonNullable = (arr) => arr.filter(isNonNullable);
120var access = (v) => typeof v === "function" && !v.length ? v() : v;
121var asArray = (value) => Array.isArray(value) ? value : value ? [value] : [];
122function handleDiffArray(current, prev, handleAdded, handleRemoved) {
123  const currLength = current.length;
124  const prevLength = prev.length;
125  let i = 0;
126  if (!prevLength) {
127    for (; i < currLength; i++)
128      handleAdded(current[i]);
129    return;
130  }
131  if (!currLength) {
132    for (; i < prevLength; i++)
133      handleRemoved(prev[i]);
134    return;
135  }
136  for (; i < prevLength; i++) {
137    if (prev[i] !== current[i])
138      break;
139  }
140  let prevEl;
141  let currEl;
142  prev = prev.slice(i);
143  current = current.slice(i);
144  for (prevEl of prev) {
145    if (!current.includes(prevEl))
146      handleRemoved(prevEl);
147  }
148  for (currEl of current) {
149    if (!prev.includes(currEl))
150      handleAdded(currEl);
151  }
152}
153
vendor: 1,202 bytes, lines 154-184
154// node_modules/solid-three/node_modules/@solid-primitives/resize-observer/dist/index.js
155function makeResizeObserver(callback, options) {
156  if (isServer) {
157    return { observe: noop, unobserve: noop };
158  }
159  const observer = new ResizeObserver(callback);
160  onCleanup(observer.disconnect.bind(observer));
161  return {
162    observe: (ref) => observer.observe(ref, options),
163    unobserve: observer.unobserve.bind(observer)
164  };
165}
166function createResizeObserver(targets, onResize, options) {
167  if (isServer)
168    return;
169  const previousMap = /* @__PURE__ */ new WeakMap(), { observe, unobserve } = makeResizeObserver((entries) => {
170    for (const entry of entries) {
171      const { contentRect, target } = entry, width = Math.round(contentRect.width), height = Math.round(contentRect.height), previous = previousMap.get(target);
172      if (!previous || previous.width !== width || previous.height !== height) {
173        onResize(contentRect, target, entry);
174        previousMap.set(target, { width, height });
175      }
176    }
177  }, options);
178  createEffect((prev) => {
179    const refs = filterNonNullable(asArray(access(targets)));
180    handleDiffArray(refs, prev, observe, unobserve);
181    return refs;
182  }, []);
183}
184
vendor: 785 bytes, lines 185-209
185// node_modules/@bigmistqke/solid-whenever/dist/index.js
186function resolve(value) {
187  return typeof value !== "function" ? value : value();
188}
189var check = (accessor, callback, fallback) => {
190  const value = resolve(accessor);
191  return value ? callback(value) : fallback ? fallback() : void 0;
192};
193var when = (accessor, callback, fallback) => {
194  return (...args) => check(
195    accessor,
196    (value) => callback(value, ...args),
197    fallback ? () => fallback(...args) : void 0
198  );
199};
200function whenify(fn) {
201  return function(accessor, callback, fallback) {
202    return fn(when(accessor, callback, fallback));
203  };
204}
205var whenMemo = whenify(createMemo);
206var whenEffect = whenify(createEffect);
207var whenRenderEffect = whenify(createRenderEffect);
208var whenComputed = whenify(createComputed);
209
vendor: 53,852 bytes, lines 210-1971
210// node_modules/solid-three/dist/index.js
211var $S3C = /* @__PURE__ */ Symbol("solid-three");
212function isRecord(value) {
213  return !Array.isArray(value) && typeof value === "object";
214}
215var isOrthographicCamera = (def) => "isOrthographicCamera" in def && !!def.isOrthographicCamera;
216var isVector3 = (def) => "isVector3" in def && !!def.isVector3;
217function autodispose(object) {
218  if (object.dispose) {
219    onCleanup(() => object.dispose?.());
220  }
221  return object;
222}
223function meta(instance, augmentation = { props: {} }) {
224  if (hasMeta(instance)) {
225    return instance;
226  }
227  const _instance = instance;
228  _instance[$S3C] = mergeProps(
229    { children: /* @__PURE__ */ new Set(), parent: void 0 },
230    augmentation
231  );
232  return _instance;
233}
234function getMeta(value) {
235  return hasMeta(value) ? value[$S3C] : void 0;
236}
237function hasMeta(element) {
238  return typeof element === "object" && element && $S3C in element;
239}
240async function awaitMapObject(object, callback) {
241  const result = {};
242  for (const key in object) {
243    result[key] = await callback(object[key], key);
244  }
245  return result;
246}
247function bubbleUp(node, callback) {
248  let current = node;
249  while (current) {
250    callback(current);
251    current = "parent" in current ? current.parent : void 0;
252  }
253}
254function defaultProps(props, defaults) {
255  return mergeProps(defaults, props);
256}
257var hasColorSpace = (object) => "colorSpace" in object || "outputColorSpace" in object;
258function isConstructor(value) {
259  return typeof value === "function" && value.prototype !== void 0;
260}
261function isMaterial(value) {
262  return !!value && value.isMaterial === true;
263}
264function isBufferGeometry(value) {
265  return !!value && value.isBufferGeometry === true;
266}
267function isFog(value) {
268  return !!value && value.isFog === true;
269}
270function isObject3D(value) {
271  return !!value && value.isObject3D === true;
272}
273function isWritable(object, propertyName) {
274  return Object.getOwnPropertyDescriptor(object, propertyName)?.writable;
275}
276function isRenderer(value) {
277  return typeof value === "object" && value !== null && typeof value.render === "function" && typeof value.setSize === "function";
278}
279function isWebGLShadowMap(value) {
280  return !!value && "needsUpdate" in value;
281}
282function getPendingInit(renderer) {
283  const init = renderer.init;
284  const hasInitialized = renderer.hasInitialized;
285  if (typeof init !== "function") return void 0;
286  if (hasInitialized?.call(renderer)) return void 0;
287  return () => init.call(renderer);
288}
289var removeElementFromArray = (array, value) => {
290  const index = array.indexOf(value);
291  if (index !== -1) array.splice(index, 1);
292  return array;
293};
294function resolve2(child, recursive = false) {
295  if (isConstructor(child)) {
296    return child;
297  }
298  if (typeof child === "function") {
299    const value = child();
300    if (recursive) {
301      return resolve2(value);
302    }
303    return value;
304  }
305  return child;
306}
307function withMultiContexts(children3, values) {
308  let result;
309  values.reduce((acc, [context, value], index) => {
310    return () => context.Provider({
311      value,
312      children: () => {
313        if (index === 0) result = acc();
314        else acc();
315      }
316    });
317  }, children3)();
318  return result;
319}
320async function load(loader, input) {
321  if (isRecord(input)) {
322    return await awaitMapObject(input, (path) => load(loader, path));
323  }
324  return new Promise((resolve22, reject) => loader.load(input, resolve22, void 0, reject));
325}
326function useRef(props, value) {
327  createRenderEffect(() => {
328    const result = typeof value === "function" ? (
329      // @ts-expect-error — T may itself be callable; the Accessor branch is intended
330      value()
331    ) : value;
332    if (typeof props.ref === "function") {
333      const cleanup = props.ref(result);
334      if (typeof cleanup === "function") onCleanup(cleanup);
335    } else {
336      props.ref = result;
337    }
338  });
339}
340var tempTarget = new Vector3();
341var position = new Vector3();
342function getCurrentViewport(_camera, target, { width, height, top, left }) {
343  const aspect = width / height;
344  if (isVector3(target)) {
345    tempTarget.copy(target);
346  } else {
347    tempTarget.set(...target);
348  }
349  const distance = _camera.getWorldPosition(position).distanceTo(tempTarget);
350  if (isOrthographicCamera(_camera)) {
351    return {
352      width: width / _camera.zoom,
353      height: height / _camera.zoom,
354      top,
355      left,
356      factor: 1,
357      distance,
358      aspect
359    };
360  }
361  const fov = _camera.fov * Math.PI / 180;
362  const h = 2 * Math.tan(fov / 2) * distance;
363  const w = h * (width / height);
364  return { width: w, height: h, top, left, factor: width / w, distance, aspect };
365}
366function binarySearch(array, target) {
367  let left = 0;
368  let right = array.length;
369  while (left < right) {
370    const mid = Math.floor((left + right) / 2);
371    if (array[mid] < target) {
372      left = mid + 1;
373    } else {
374      right = mid;
375    }
376  }
377  return left;
378}
379var eventNameMap = {
380  onClick: "click",
381  onContextMenu: "contextmenu",
382  onDoubleClick: "dblclick",
383  onMouseDown: "mousedown",
384  onMouseMove: "mousemove",
385  onMouseUp: "mouseup",
386  onMouseLeave: "mouseleave",
387  onPointerUp: "pointerup",
388  onPointerDown: "pointerdown",
389  onPointerMove: "pointermove",
390  onPointerLeave: "pointerleave",
391  onWheel: "wheel"
392};
393function createRegistry() {
394  const array = [];
395  return {
396    array,
397    add(instance) {
398      array.push(instance);
399      return () => {
400        array.splice(
401          array.findIndex((_instance) => _instance === instance),
402          1
403        );
404      };
405    }
406  };
407}
408var isEventType = (type) => /^on(Pointer|Click|DoubleClick|ContextMenu|Wheel|Mouse)/.test(type);
409function createThreeEvent(nativeEvent, { stoppable = true, intersections } = {}) {
410  const event = stoppable ? {
411    nativeEvent,
412    stopped: false,
413    stopPropagation() {
414      event.stopped = true;
415    }
416  } : { nativeEvent };
417  if (intersections) {
418    event.intersections = intersections;
419    event.intersection = intersections[0];
420  }
421  return event;
422}
423function raycast(context, registry, event) {
424  if ("update" in context.raycaster) {
425    context.raycaster.update(event, context);
426  }
427  const nodeSet = /* @__PURE__ */ new Set();
428  const visitedSet = /* @__PURE__ */ new Set();
429  const stack = [...registry];
430  for (const object of stack) {
431    if (visitedSet.has(object)) continue;
432    visitedSet.add(object);
433    const meta2 = getMeta(object);
434    if (meta2 && meta2.props.raycastable !== false) {
435      nodeSet.add(object);
436    }
437    stack.push(...object.children);
438  }
439  return context.raycaster.intersectObjects(Array.from(nodeSet), false);
440}
441function createMissableEventRegistry(type, context) {
442  const registry = createRegistry();
443  context.canvas.addEventListener(eventNameMap[type], (nativeEvent) => {
444    const missedType = `${type}Missed`;
445    if (registry.array.length === 0 && !context.props[type] && !context.props[missedType]) return;
446    const missedObjects = new Set(registry.array);
447    const visitedObjects = /* @__PURE__ */ new Set();
448    const intersections = raycast(context, registry.array, nativeEvent);
449    const stoppableEvent = createThreeEvent(nativeEvent, { intersections });
450    for (const intersection of intersections) {
451      stoppableEvent.currentIntersection = intersection;
452      let node = intersection.object;
453      while (node && !stoppableEvent.stopped && !visitedObjects.has(node)) {
454        missedObjects.delete(node);
455        visitedObjects.add(node);
456        getMeta(node)?.props[type]?.(
457          // @ts-expect-error TODO: fix type-error
458          stoppableEvent
459        );
460        node = node.parent;
461      }
462    }
463    if (!stoppableEvent.stopped) {
464      delete stoppableEvent.currentIntersection;
465      context.props[type]?.(stoppableEvent);
466    }
467    for (const remainingObject of missedObjects) {
468      const intersections2 = context.raycaster.intersectObject(remainingObject, true);
469      for (const { object } of intersections2) {
470        let node = object;
471        while (node && !visitedObjects.has(node)) {
472          missedObjects.delete(node);
473          visitedObjects.add(node);
474          node = node.parent;
475        }
476      }
477    }
478    const missedEvent = createThreeEvent(nativeEvent, { stoppable: false });
479    for (const object of missedObjects) {
480      getMeta(object)?.props[missedType]?.(missedEvent);
481    }
482    if (intersections.length === 0) {
483      context.props[`${type}Missed`]?.(missedEvent);
484    }
485  });
486  return registry;
487}
488function createHoverEventRegistry(type, context) {
489  const registry = createRegistry();
490  let hoveredSet = /* @__PURE__ */ new Set();
491  let intersections = [];
492  let hoveredCanvas = false;
493  context.canvas.addEventListener(eventNameMap[`on${type}Move`], (nativeEvent) => {
494    intersections = raycast(context, registry.array, nativeEvent);
495    const enterEvent = createThreeEvent(nativeEvent, { stoppable: false, intersections });
496    const enterSet = /* @__PURE__ */ new Set();
497    for (const intersection of intersections) {
498      enterEvent.currentIntersection = intersection;
499      let current = intersection.object;
500      while (current && !enterSet.has(current)) {
501        enterSet.add(current);
502        if (!hoveredSet.has(current)) {
503          getMeta(current)?.props[`on${type}Enter`]?.(
504            // @ts-expect-error TODO: fix type-error
505            enterEvent
506          );
507        }
508        current = current.parent;
509      }
510    }
511    if (hoveredCanvas === false) {
512      context.props[`on${type}Enter`]?.(
513        // @ts-expect-error TODO: fix type-error
514        enterEvent
515      );
516      hoveredCanvas = true;
517    }
518    const moveEvent = createThreeEvent(nativeEvent, { intersections });
519    const moveSet = /* @__PURE__ */ new Set();
520    for (const intersection of intersections) {
521      moveEvent.currentIntersection = intersection;
522      let current = intersection.object;
523      while (current && !moveSet.has(current)) {
524        moveSet.add(current);
525        const meta2 = getMeta(current);
526        if (meta2) {
527          meta2.props[`on${type}Move`]?.(
528            // @ts-expect-error TODO: fix type-error
529            moveEvent
530          );
531          if (moveEvent.stopped) {
532            break;
533          }
534        }
535        current = current.parent;
536      }
537    }
538    if (!moveEvent.stopped) {
539      delete moveEvent.currentIntersection;
540      context.props[`on${type}Move`]?.(
541        // @ts-expect-error TODO: fix type-error
542        moveEvent
543      );
544    }
545    const leaveEvent = createThreeEvent(nativeEvent, { intersections, stoppable: false });
546    const prevHoveredSet = hoveredSet;
547    hoveredSet = enterSet;
548    for (const object of prevHoveredSet) {
549      if (enterSet.has(object)) continue;
550      getMeta(object)?.props[`on${type}Leave`]?.(
551        // @ts-expect-error TODO: fix type-error
552        leaveEvent
553      );
554    }
555  });
556  context.canvas.addEventListener(eventNameMap[`on${type}Leave`], (nativeEvent) => {
557    const leaveEvent = createThreeEvent(nativeEvent, { stoppable: false });
558    context.props[`on${type}Leave`]?.(leaveEvent);
559    hoveredCanvas = false;
560    for (const object of hoveredSet) {
561      getMeta(object)?.props[`on${type}Leave`]?.(
562        // @ts-expect-error TODO: fix type-error
563        leaveEvent
564      );
565    }
566    hoveredSet.clear();
567  });
568  return registry;
569}
570function createDefaultEventRegistry(type, context, options) {
571  const registry = createRegistry();
572  context.canvas.addEventListener(
573    eventNameMap[type],
574    (nativeEvent) => {
575      const intersections = raycast(context, registry.array, nativeEvent);
576      const event = createThreeEvent(nativeEvent, { intersections });
577      for (const intersection of intersections) {
578        event.currentIntersection = intersection;
579        let node = intersection.object;
580        while (node && !event.stopped) {
581          getMeta(node)?.props[type]?.(
582            // @ts-expect-error TODO: fix type-error
583            event
584          );
585          node = node.parent;
586        }
587      }
588      if (!event.stopped) {
589        delete event.currentIntersection;
590        context.props[type]?.(event);
591      }
592    },
593    options
594  );
595  return registry;
596}
597function createEvents(context) {
598  const hoverMouseRegistry = createHoverEventRegistry("Mouse", context);
599  const hoverPointerRegistry = createHoverEventRegistry("Pointer", context);
600  const missableClickRegistry = createMissableEventRegistry("onClick", context);
601  const missableContextMenuRegistry = createMissableEventRegistry("onContextMenu", context);
602  const missableDoubleClickRegistry = createMissableEventRegistry("onDoubleClick", context);
603  const mouseDownRegistry = createDefaultEventRegistry("onMouseDown", context);
604  const mouseUpRegistry = createDefaultEventRegistry("onMouseUp", context);
605  const pointerDownRegistry = createDefaultEventRegistry("onPointerDown", context);
606  const pointerUpRegistry = createDefaultEventRegistry("onPointerUp", context);
607  const wheelRegistry = createDefaultEventRegistry("onWheel", context, { passive: true });
608  return {
609    /**
610     * Registers an `AugmentedElement<Object3D>` with the event handling system.
611     *
612     * @param object - The 3D object to register.
613     * @param type - The type of event the object should listen for.
614     */
615    addEventListener(object, type) {
616      switch (type) {
617        // Missable Events
618        case "onClick":
619        case "onClickMissed":
620          return missableClickRegistry.add(object);
621        case "onContextMenu":
622        case "onContextMenuMissed":
623          return missableContextMenuRegistry.add(object);
624        case "onDoubleClick":
625        case "onDoubleClickMissed":
626          return missableDoubleClickRegistry.add(object);
627        // Hover Events
628        case "onMouseEnter":
629        case "onMouseLeave":
630        case "onMouseMove":
631          return hoverMouseRegistry.add(object);
632        case "onPointerEnter":
633        case "onPointerLeave":
634        case "onPointerMove":
635          return hoverPointerRegistry.add(object);
636        // Default Events
637        case "onMouseDown":
638          return mouseDownRegistry.add(object);
639        case "onMouseUp":
640          return mouseUpRegistry.add(object);
641        case "onPointerDown":
642          return pointerDownRegistry.add(object);
643        case "onPointerUp":
644          return pointerUpRegistry.add(object);
645        case "onWheel":
646          return wheelRegistry.add(object);
647      }
648    }
649  };
650}
651var Stack = class {
652  constructor(name = "") {
653    this.name = name;
654    [this.#array, this.#setArray] = createSignal([], {
655      equals: false
656    });
657  }
658  name;
659  #array;
660  #setArray;
661  /**
662   * Returns the complete stack.
663   * @returns Returns the complete stack.
664   */
665  all() {
666    return this.#array();
667  }
668  /**
669   * Returns the top element of the stack without removing it.
670   * @returns The top element of the stack.
671   */
672  peek() {
673    const array = this.#array();
674    const top = array[array.length - 1];
675    return typeof top === "function" ? top() : top;
676  }
677  /**
678   * Adds a value `T` or `Accessor<T>` to the stack.
679   * Value is automatically removed from stack on cleanup.
680   * @param value - The value to add to the stack.
681   * @returns A cleanup function to remove the value from the stack.
682   */
683  push(value) {
684    this.#setArray((array) => {
685      const index = array.indexOf(value);
686      if (index !== -1) array.splice(index, 1);
687      array.push(value);
688      return array;
689    });
690    onCleanup(() => this.remove(value));
691    return () => this.remove(value);
692  }
693  /**
694   * Removes a value from the stack.
695   * @private
696   * @param value - The value to remove from the stack.
697   */
698  remove(value) {
699    this.#setArray((array) => {
700      const index = array.indexOf(value);
701      if (index === -1) return array;
702      array.splice(index, 1);
703      return array;
704    });
705  }
706};
707var TreeNode = class {
708  constructor(key, parent) {
709    this.key = key;
710    this.parent = parent;
711  }
712  key;
713  parent;
714  children = /* @__PURE__ */ new Map();
715  count = 0;
716  data;
717  delete() {
718    this.parent.children.delete(this.key);
719  }
720};
721var TreeRegistry = class _TreeRegistry {
722  /** Map of child nodes at the root level */
723  children = /* @__PURE__ */ new Map();
724  /** Count of data nodes in this tree */
725  count = 0;
726  #resolve(input, autocreate) {
727    const paths = Array.isArray(input) ? input : [input];
728    let current = this;
729    for (let i = 0; i < paths.length; i++) {
730      let node = current.children.get(paths[i]);
731      if (!node) {
732        if (!autocreate) {
733          return void 0;
734        }
735        node = new TreeNode(paths[i], current);
736        current.children.set(paths[i], node);
737      }
738      current = node;
739    }
740    if (current instanceof _TreeRegistry) {
741      throw new Error(`Invalid resolution: ${paths}`);
742    }
743    return current;
744  }
745  /**
746   * Retrieves data stored at the specified path.
747   * @param input Path as a string or array of strings
748   * @returns The data stored at the path, or undefined if not found
749   */
750  get(input, warn = true) {
751    const node = this.#resolve(input, false);
752    if (!node) {
753      return void 0;
754    }
755    return node.data;
756  }
757  /**
758   * Stores data at the specified path, creating nodes as needed.
759   * Automatically increments reference counts up the tree when storing new data.
760   * @param input Path as a string or array of strings
761   * @param data The data to store
762   */
763  set(input, data) {
764    const node = this.#resolve(input, true);
765    if (!node.data) {
766      bubbleUp(node, (node2) => node2.count++);
767    }
768    node.data = data;
769  }
770  /**
771   * Deletes data at the specified path and cleans up empty branches.
772   * Automatically decrements reference counts and removes nodes with zero references.
773   * @param input Path as a string or array of strings
774   */
775  delete(input) {
776    const node = this.#resolve(input, false);
777    if (!node) {
778      return;
779    }
780    bubbleUp(node, (node2) => {
781      node2.count--;
782      if (node2 instanceof TreeNode && node2.count === 0) {
783        node2.delete();
784      }
785    });
786  }
787};
788var LoaderCache = class {
789  /** Map of loader instances to their respective tree registries */
790  #treeRegistryMap = /* @__PURE__ */ new Map();
791  /** Weak map for reverse lookup from data to cache nodes */
792  #dataMap = /* @__PURE__ */ new WeakMap();
793  /** Set of resources that do not have active references and can be safely cleaned up. */
794  freeList = /* @__PURE__ */ new Set();
795  /**
796   * Gets or creates a tree registry for a specific loader.
797   * @param loader The Three.js loader instance
798   * @returns The tree registry for this loader
799   * @private
800   */
801  #registry(loader) {
802    let registry = this.#treeRegistryMap.get(loader);
803    if (!registry) {
804      this.#treeRegistryMap.set(
805        loader,
806        registry = new TreeRegistry()
807      );
808    }
809    return registry;
810  }
811  /**
812   * Deletes a cache node and its associated resource.
813   * @param node The cache node to delete
814   * @param options.force Force deletion even if not in free list
815   * @private
816   */
817  #delete(node, { force } = {}) {
818    if (!force && !this.freeList.has(node.data)) {
819      return;
820    }
821    node.dispose();
822  }
823  /**
824   * Disposes all resources in the free list.
825   * Should be called periodically to clean up unused resources.
826   */
827  disposeFreeList() {
828    this.freeList.forEach((resource) => this.#dataMap.get(resource)?.dispose());
829  }
830  /**
831   * Manually deletes a specific resource from the cache.
832   * @param resource The resource object to delete
833   * @param options.force Force deletion even if resource has active references
834   */
835  disposeResource(resource, options) {
836    const node = this.#dataMap.get(resource);
837    if (!node) {
838      return;
839    }
840    this.#delete(node, options);
841  }
842  /**
843   * Removes a resource from a specific loader's cache at the given path.
844   * @param loader The Three.js loader instance
845   * @param url The URL or path to the resource
846   * @param options.force Force deletion even if resource has active references
847   */
848  delete(loader, url, options) {
849    const node = this.#registry(loader).get(url);
850    if (!node) {
851      return;
852    }
853    this.#delete(node, options);
854  }
855  /**
856   * Retrieves a resource from the cache and tracks its usage.
857   * Automatically integrates with Solid.js cleanup for reference counting.
858   * @param loader The Three.js loader instance
859   * @param url The URL or path to the resource
860   * @returns The resource promise, resolved data, or undefined if not found
861   */
862  get(loader, url, warn) {
863    const node = this.#registry(loader).get(url, warn);
864    if (!node) return void 0;
865    return node.data;
866  }
867  /**
868   * Stores a resource in the cache at the specified path.
869   * @param loader The Three.js loader instance
870   * @param path The URL or path to store the resource at
871   * @param data The resource promise to cache
872   * @param options.force Force update even if resource already exists
873   * @returns The stored promise
874   */
875  set(loader, path, data, options) {
876    const registry = this.#registry(loader);
877    let node = registry.get(path, false);
878    if (node) {
879      node.update(data, options);
880    } else {
881      node = new CacheNode(this.freeList, registry, path, data);
882      this.#dataMap.set(data, node);
883      registry.set(path, node);
884    }
885    return data;
886  }
887};
888var CacheNode = class {
889  /**
890   * Creates a new cache node.
891   * @param free The global free list for deferred disposal
892   * @param registry The tree registry containing this node
893   * @param path The path where this resource is stored
894   * @param promise The resource promise to cache
895   */
896  constructor(free, registry, path, promise) {
897    this.free = free;
898    this.registry = registry;
899    this.path = path;
900    this.data = promise;
901    this.#set(promise);
902  }
903  free;
904  registry;
905  path;
906  /** Reference count for this resource */
907  count = 0;
908  /** The cached resource (promise or resolved value) */
909  data;
910  /**
911   * Sets the promise and handles resolution.
912   * @param promise The resource promise
913   * @private
914   */
915  #set(promise) {
916    this.data = promise;
917    Promise.resolve(promise).then((value) => {
918      if (this.data === promise) {
919        this.data = value;
920      }
921    });
922  }
923  /**
924   * Disposes the Three.js resource if it has a dispose method.
925   * @private
926   */
927  #dispose() {
928    if (isRecord(this.data) && "dispose" in this.data && typeof this.data.dispose === "function") {
929      this.data.dispose();
930    }
931  }
932  /**
933   * Deletes this node and disposes its resource.
934   */
935  dispose() {
936    this.#dispose();
937    this.registry.delete(this.path);
938  }
939  /**
940   * Tracks usage of this resource within a Solid.js reactive context.
941   * Automatically increments reference count and schedules cleanup on component unmount.
942   */
943  track() {
944    if (this.count === 0) {
945      this.free.delete(this.data);
946    }
947    this.count++;
948    if (!getOwner()) ;
949    else {
950      onCleanup(() => {
951        this.count -= 1;
952        if (this.count <= 0) {
953          this.free.add(this.data);
954        }
955      });
956    }
957  }
958  /**
959   * Updates the cached resource with new data.
960   * @param data The new resource promise
961   * @param options.force Force update and dispose current resource (default: true)
962   */
963  update(data, { force = true } = {}) {
964    if (this.data !== data && !force) ;
965    else {
966      this.#dispose();
967      this.#set(data);
968      this.registry.set(this.path, this);
969    }
970  }
971};
972var frameContext = createContext();
973var useFrame = (callback, options) => {
974  const addFrameListener = useContext(frameContext);
975  if (!addFrameListener) {
976    throw new Error("S3: Hooks can only be used within the Canvas component!");
977  }
978  return addFrameListener(callback, options);
979};
980var threeContext = createContext(null);
981function useThree(callback) {
982  const store = useContext(threeContext);
983  if (!store) {
984    throw new Error("S3: Hooks can only be used within the Canvas component!");
985  }
986  if (callback) return () => callback(store);
987  return store;
988}
989var LOADER_CACHE = /* @__PURE__ */ new Map();
990function resolveUrls(base, url) {
991  if (Array.isArray(url)) {
992    return url.map((url2) => new URL(url2, base).href);
993  } else if (isRecord(url)) {
994    return Object.fromEntries(
995      Object.entries(url).map(([key, url2]) => [key, resolveUrls(base, url2)])
996    );
997  } else if (typeof url === "string") {
998    return new URL(url, base).href;
999  }
1000  throw new Error("Unexpected type");
1001}
1002function useLoader(constructor, url, options) {
1003  const config = mergeProps({ cache: true }, options);
1004  const loader = createMemo(() => {
1005    const _constructor = resolve2(constructor);
1006    let loader2 = LOADER_CACHE.get(_constructor);
1007    if (!loader2) {
1008      LOADER_CACHE.set(_constructor, loader2 = new _constructor());
1009    }
1010    return loader2;
1011  });
1012  function getOrInsert(registry, loader2, input) {
1013    if (isRecord(input)) {
1014      return awaitMapObject(input, async (value) => getOrInsert(registry, loader2, value));
1015    } else {
1016      const _input = input;
1017      const cachedPromise = registry.get(loader2, _input, false);
1018      if (cachedPromise) {
1019        return cachedPromise;
1020      }
1021      const promise = load(loader2, _input);
1022      registry.set(loader2, _input, promise);
1023      return promise;
1024    }
1025  }
1026  function loadUrl(url2) {
1027    if (config.cache === true) {
1028      if (!useLoader.cache) {
1029        return load(loader(), url2);
1030      }
1031      return getOrInsert(useLoader.cache, loader(), url2);
1032    }
1033    if (config.cache) {
1034      return getOrInsert(config.cache, loader(), url2);
1035    }
1036    return load(loader(), url2);
1037  }
1038  const [resource] = createResource(
1039    () => [resolve2(url), options?.base, loader()],
1040    async ([url2, base, loader2]) => {
1041      config.onBeforeLoad?.(loader2);
1042      url2 = base ? resolveUrls(base, url2) : url2;
1043      const result = await loadUrl(url2);
1044      config.onLoad?.(result);
1045      return result;
1046    }
1047  );
1048  return resource;
1049}
1050useLoader.cache = new LoaderCache();
1051var addToEventListeners = (object, type) => {
1052  const addToEventListeners2 = useContext(eventContext);
1053  if (!addToEventListeners2) {
1054    throw new Error("S3: Hooks can only be used within the Canvas component!");
1055  }
1056  return addToEventListeners2(object, type);
1057};
1058var eventContext = createContext();
1059createContext();
1060function applySceneGraph(parent, child) {
1061  const parentMeta = getMeta(parent);
1062  if (parentMeta) {
1063    parentMeta.children.add(child);
1064    onCleanup(() => parentMeta.children.delete(child));
1065  }
1066  const childMeta = getMeta(child);
1067  if (childMeta) {
1068    childMeta.parent = parent;
1069    onCleanup(() => childMeta.parent = void 0);
1070  }
1071  let attachProp = childMeta?.props.attach;
1072  if (typeof attachProp === "function") {
1073    const cleanup = attachProp(parent, child);
1074    onCleanup(cleanup);
1075    return;
1076  }
1077  if (!attachProp) {
1078    if (isMaterial(child)) attachProp = "material";
1079    else if (isBufferGeometry(child)) attachProp = "geometry";
1080    else if (isFog(child)) attachProp = "fog";
1081  }
1082  if (attachProp) {
1083    let target = parent;
1084    let property;
1085    const path = attachProp.split("-");
1086    while (property = path.shift()) {
1087      if (path.length === 0) {
1088        target[property] = child;
1089        onCleanup(() => target[property] = void 0);
1090        break;
1091      } else {
1092        target = target[property];
1093      }
1094    }
1095    return;
1096  }
1097  if (isObject3D(child) && isObject3D(parent)) return;
1098}
1099var useSceneGraph = (_parent, props) => {
1100  const c = children(() => props.children);
1101  createComputed(
1102    mapArray(
1103      () => c.toArray(),
1104      (_child) => createComputed(() => {
1105        const parent = resolve2(_parent);
1106        if (!parent) return;
1107        const child = resolve2(_child);
1108        if (!child) return;
1109        applySceneGraph(parent, child);
1110        props.onUpdate?.(parent);
1111      })
1112    )
1113  );
1114  createComputed((previousManagedChildren) => {
1115    const parent = resolve2(_parent);
1116    if (!isObject3D(parent)) {
1117      return previousManagedChildren;
1118    }
1119    const childArray = c.toArray();
1120    const managedChildren = /* @__PURE__ */ new Set();
1121    for (const child of childArray) {
1122      if (!isObject3D(child) || getMeta(child)?.props.attach) continue;
1123      managedChildren.add(child);
1124      if (child.parent !== parent) {
1125        parent.add(child);
1126      }
1127    }
1128    for (const child of previousManagedChildren) {
1129      if (!managedChildren.has(child)) {
1130        parent.remove(child);
1131      }
1132    }
1133    let childArrayIndex = 0;
1134    for (let i = 0; i < parent.children.length; i++) {
1135      if (!managedChildren.has(parent.children[i])) {
1136        continue;
1137      }
1138      while (childArrayIndex < childArray.length) {
1139        const child = childArray[childArrayIndex++];
1140        if (isObject3D(child) && !getMeta(child)?.props.attach) {
1141          parent.children[i] = child;
1142          break;
1143        }
1144      }
1145    }
1146    return managedChildren;
1147  }, /* @__PURE__ */ new Set());
1148};
1149var NEEDS_UPDATE = [
1150  "map",
1151  "envMap",
1152  "bumpMap",
1153  "normalMap",
1154  "transparent",
1155  "morphTargets",
1156  "skinning",
1157  "alphaTest",
1158  "useVertexColors",
1159  "flatShading"
1160];
1161function applyProp(context, source, type, value) {
1162  if (!source) {
1163    return;
1164  }
1165  if (value === void 0) return;
1166  if (type.indexOf("-") > -1) {
1167    const [property, ...rest] = type.split("-");
1168    applyProp(context, source[property], rest.join("-"), value);
1169    return;
1170  }
1171  if (NEEDS_UPDATE.includes(type) && (!source[type] && value || source[type] && !value)) {
1172    source.needsUpdate = true;
1173  }
1174  if (hasColorSpace(source)) {
1175    const sRGBEncoding2 = 3001;
1176    const SRGBColorSpace22 = "srgb";
1177    const LinearSRGBColorSpace22 = "srgb-linear";
1178    if (type === "encoding") {
1179      type = "colorSpace";
1180      value = value === sRGBEncoding2 ? SRGBColorSpace22 : LinearSRGBColorSpace22;
1181    } else if (type === "outputEncoding") {
1182      type = "outputColorSpace";
1183      value = value === sRGBEncoding2 ? SRGBColorSpace22 : LinearSRGBColorSpace22;
1184    }
1185  }
1186  if (isEventType(type)) {
1187    if (isObject3D(source) && hasMeta(source)) {
1188      const cleanup = addToEventListeners(source, type);
1189      onCleanup(cleanup);
1190    }
1191    return;
1192  }
1193  const target = source[type];
1194  try {
1195    if (target?.copy && target?.constructor === value?.constructor && !isWritable(source, type)) {
1196      target.copy(value);
1197    } else if (target?.set && Array.isArray(value)) {
1198      if (target.fromArray) target.fromArray(value);
1199      else target.set(...value);
1200    } else if (target?.set && typeof value !== "object") {
1201      const isColor = target instanceof Color;
1202      if (!isColor && target.setScalar && typeof value === "number") {
1203        target.setScalar(value);
1204      } else if (value !== void 0) {
1205        target.set(value);
1206      }
1207    } else {
1208      source[type] = value;
1209      if (source[type] instanceof Texture && // sRGB textures must be RGBA8 since r137 https://github.com/mrdoob/three.js/pull/23129
1210      source[type].format === RGBAFormat && source[type].type === UnsignedByteType) {
1211        createRenderEffect(() => {
1212          context.props.linear;
1213          context.props.flat;
1214          const texture = source[type];
1215          if (hasColorSpace(texture) && hasColorSpace(context.gl)) {
1216            texture.colorSpace = context.gl.outputColorSpace;
1217          } else {
1218            texture.encoding = context.gl.outputEncoding;
1219          }
1220        });
1221      }
1222    }
1223  } finally {
1224    if ("needsUpdate" in source) {
1225      source.needsUpdate = true;
1226    }
1227    if (context.props.frameloop === "demand") {
1228      context.requestRender();
1229    }
1230  }
1231}
1232function useProps(accessor, props, context = useThree()) {
1233  const [local, instanceProps] = splitProps(props, ["ref", "args", "object", "attach", "children"]);
1234  useSceneGraph(accessor, props);
1235  createRenderEffect(() => {
1236    const object = resolve2(accessor);
1237    if (!object) return;
1238    createRenderEffect(() => {
1239      if (local.ref instanceof Function) local.ref(object);
1240      else local.ref = object;
1241    });
1242    createRenderEffect(() => {
1243      const keys2 = Object.keys(instanceProps);
1244      for (const key of keys2) {
1245        const subKeys = keys2.filter((_key) => key !== _key && _key.includes(key));
1246        createRenderEffect(() => {
1247          applyProp(context, object, key, props[key]);
1248          for (const subKey of subKeys) {
1249            applyProp(context, object, subKey, props[subKey]);
1250          }
1251        });
1252      }
1253      untrack(() => props.onUpdate)?.(object);
1254    });
1255  });
1256}
1257var CursorRaycaster = class extends Raycaster {
1258  pointer = new Vector2();
1259  update(event, context) {
1260    this.pointer.x = event.offsetX / context.bounds.width * 2 - 1;
1261    this.pointer.y = -(event.offsetY / context.bounds.height) * 2 + 1;
1262    this.setFromCamera(this.pointer, context.camera);
1263  }
1264};
1265function debounce(callback, wait = 100, options = {}) {
1266  if (typeof callback !== "function") {
1267    throw new TypeError(
1268      `Expected the first parameter to be a function, got \`${typeof callback}\`.`
1269    );
1270  }
1271  if (wait < 0) {
1272    throw new RangeError("`wait` must not be negative.");
1273  }
1274  const { immediate } = options;
1275  let storedContext;
1276  let storedArguments;
1277  let timeoutId;
1278  let timestamp;
1279  let result;
1280  function run() {
1281    const callContext = storedContext;
1282    const callArguments = storedArguments;
1283    storedContext = void 0;
1284    storedArguments = void 0;
1285    result = callback.apply(callContext, callArguments);
1286    return result;
1287  }
1288  function later() {
1289    const last = Date.now() - timestamp;
1290    if (last < wait && last >= 0) {
1291      timeoutId = setTimeout(later, wait - last);
1292    } else {
1293      timeoutId = void 0;
1294      if (!immediate) {
1295        result = run();
1296      }
1297    }
1298  }
1299  function debounced(...args) {
1300    if (storedContext && this !== storedContext) {
1301      throw new Error("Debounced method called with different contexts.");
1302    }
1303    storedContext = this;
1304    storedArguments = args;
1305    timestamp = Date.now();
1306    const callNow = immediate && !timeoutId;
1307    if (!timeoutId) {
1308      timeoutId = setTimeout(later, wait);
1309    }
1310    if (callNow) {
1311      result = run();
1312    }
1313    return result;
1314  }
1315  debounced.clear = () => {
1316    if (!timeoutId) return;
1317    clearTimeout(timeoutId);
1318    timeoutId = void 0;
1319  };
1320  debounced.flush = () => {
1321    if (!timeoutId) return;
1322    debounced.trigger();
1323  };
1324  debounced.trigger = () => {
1325    result = run();
1326    debounced.clear();
1327  };
1328  return debounced;
1329}
1330function useMeasure(options) {
1331  const config = mergeProps(
1332    {
1333      debounce: 0,
1334      scroll: false,
1335      offsetSize: false
1336    },
1337    options
1338  );
1339  const ResizeObserver2 = config.polyfill || (typeof globalThis === "undefined" ? class ResizeObserver {
1340  } : globalThis.ResizeObserver);
1341  if (!ResizeObserver2) {
1342    throw new Error(
1343      "This browser does not support ResizeObserver out of the box. See: https://github.com/react-spring/react-use-measure/#resize-observer-polyfills"
1344    );
1345  }
1346  const [element, setElement] = createSignal(null);
1347  const [bounds, setBounds] = createSignal({
1348    left: 0,
1349    top: 0,
1350    width: 0,
1351    height: 0,
1352    bottom: 0,
1353    right: 0,
1354    x: 0,
1355    y: 0
1356  });
1357  const scrollContainers = createMemo(() => findScrollContainers(element()));
1358  let lastBounds;
1359  const getDebounce = (type) => {
1360    const debounce2 = config.debounce ? typeof config.debounce === "number" ? config.debounce : config.debounce[type] : null;
1361    if (debounce2) return debounce(forceRefresh, debounce2);
1362    return forceRefresh;
1363  };
1364  const forceRefresh = when(element, (element2) => {
1365    const { left, top, width, height, bottom, right, x, y } = element2.getBoundingClientRect();
1366    const bounds2 = {
1367      left,
1368      top,
1369      width,
1370      height,
1371      bottom,
1372      right,
1373      x,
1374      y
1375    };
1376    if (element2 instanceof HTMLElement && config.offsetSize) {
1377      bounds2.height = element2.offsetHeight;
1378      bounds2.width = element2.offsetWidth;
1379    }
1380    Object.freeze(bounds2);
1381    if (!lastBounds || !areBoundsEqual(lastBounds, bounds2)) {
1382      lastBounds = bounds2;
1383      setBounds(bounds2);
1384    }
1385  });
1386  createEffect(() => {
1387    const onScroll = getDebounce("scroll");
1388    createEffect(() => {
1389      if (!config.scroll) return;
1390      globalThis.addEventListener("scroll", onScroll, { capture: true, passive: true });
1391      onCleanup(() => globalThis.removeEventListener("scroll", onScroll, true));
1392    });
1393    whenEffect(scrollContainers, (scrollContainers2) => {
1394      if (!config.scroll) return;
1395      scrollContainers2.forEach(
1396        (scrollContainer) => scrollContainer.addEventListener("scroll", onScroll, {
1397          capture: true,
1398          passive: true
1399        })
1400      );
1401      onCleanup(() => {
1402        scrollContainers2.forEach((element2) => {
1403          element2.removeEventListener("scroll", onScroll, true);
1404        });
1405      });
1406    });
1407  });
1408  createEffect(() => {
1409    const onResize = getDebounce("resize");
1410    globalThis.addEventListener("resize", onResize);
1411    onCleanup(() => globalThis.removeEventListener("resize", onResize));
1412    whenEffect(element, (element2) => {
1413      const observer = new ResizeObserver2(onResize);
1414      observer.observe(element2);
1415      onCleanup(() => observer.disconnect());
1416    });
1417  });
1418  return {
1419    setElement: (source) => {
1420      if (!source || source === element()) return;
1421      setElement(source);
1422      forceRefresh();
1423    },
1424    bounds,
1425    forceRefresh
1426  };
1427}
1428function findScrollContainers(element) {
1429  const result = [];
1430  if (!element || element === document.body) return result;
1431  const { overflow, overflowX, overflowY } = globalThis.getComputedStyle(element);
1432  if ([overflow, overflowX, overflowY].some((prop) => prop === "auto" || prop === "scroll"))
1433    result.push(element);
1434  return [...result, ...findScrollContainers(element.parentElement)];
1435}
1436var keys = ["x", "y", "top", "bottom", "left", "right", "width", "height"];
1437var areBoundsEqual = (a, b) => keys.every((key) => a[key] === b[key]);
1438function createThree(canvas, props) {
1439  const canvasProps = defaultProps(props, {
1440    frameloop: "always"
1441  });
1442  const frameListeners = {
1443    before: {
1444      map: /* @__PURE__ */ new Map(),
1445      priorities: []
1446      // Keep this sorted
1447    },
1448    after: {
1449      map: /* @__PURE__ */ new Map(),
1450      priorities: []
1451    }
1452  };
1453  const addFrameListener = (callback, options) => {
1454    return createRoot((dispose) => {
1455      createRenderEffect(() => {
1456        const {
1457          stage = "before",
1458          priority = 0
1459        } = options ?? {};
1460        const listeners = frameListeners[stage];
1461        let array = listeners.map.get(priority);
1462        if (!array) {
1463          array = [];
1464          listeners.map.set(priority, array);
1465          const index = binarySearch(listeners.priorities, priority);
1466          listeners.priorities.splice(index, 0, priority);
1467        }
1468        array.push(callback);
1469        onCleanup(() => {
1470          removeElementFromArray(array, callback);
1471          if (array.length === 0) {
1472            listeners.map.delete(priority);
1473            listeners.priorities.splice(listeners.priorities.indexOf(priority), 1);
1474          }
1475        });
1476      });
1477      return dispose;
1478    });
1479  };
1480  function updateFrameListeners(stage, delta, frame) {
1481    for (const priority of frameListeners[stage].priorities) {
1482      const callbacks = frameListeners[stage].map.get(priority);
1483      for (const callback of callbacks) {
1484        callback(context, delta, frame);
1485      }
1486    }
1487  }
1488  let pendingRenderRequest;
1489  const isPresenting = () => !!context.gl?.xr?.isPresenting;
1490  function render(timestamp, frame) {
1491    if (!context.gl || rendererReady.state !== "ready") {
1492      return;
1493    }
1494    if (props.frameloop === "never") {
1495      context.clock.elapsedTime = timestamp;
1496    }
1497    pendingRenderRequest = void 0;
1498    const delta = context.clock.getDelta();
1499    updateFrameListeners("before", delta, frame);
1500    context.gl.render(context.scene, context.camera);
1501    updateFrameListeners("after", delta, frame);
1502  }
1503  function requestRender() {
1504    if (isPresenting()) return;
1505    if (pendingRenderRequest) return;
1506    pendingRenderRequest = requestAnimationFrame(render);
1507  }
1508  onCleanup(() => pendingRenderRequest && cancelAnimationFrame(pendingRenderRequest));
1509  const cameraIsInstance = createMemo(() => props.camera instanceof Camera);
1510  const orthographicFlag = createMemo(() => !!props.orthographic);
1511  const sceneIsInstance = createMemo(() => props.scene instanceof Scene);
1512  const raycasterIsInstance = createMemo(() => props.raycaster instanceof Raycaster);
1513  const glKind = createMemo(() => {
1514    const _propsGl = props.gl;
1515    if (typeof _propsGl === "function") return "factory";
1516    if (isRenderer(_propsGl)) return "instance";
1517    return "default";
1518  });
1519  const WEBGL_CONSTRUCTOR_KEYS = ["alpha", "antialias", "depth", "failIfMajorPerformanceCaveat", "logarithmicDepthBuffer", "powerPreference", "precision", "premultipliedAlpha", "preserveDrawingBuffer", "reversedDepthBuffer", "stencil"];
1520  const camera = createMemo(() => {
1521    if (cameraIsInstance()) {
1522      return meta(props.camera, {
1523        get props() {
1524          return props.camera || {};
1525        }
1526      });
1527    }
1528    return meta(orthographicFlag() ? new OrthographicCamera() : new PerspectiveCamera(), {
1529      get props() {
1530        return props.camera || {};
1531      }
1532    });
1533  });
1534  const cameraStack = new Stack("camera");
1535  const scene = createMemo(() => {
1536    if (sceneIsInstance()) {
1537      return meta(props.scene, {
1538        get props() {
1539          return props.scene || {};
1540        }
1541      });
1542    }
1543    return meta(new Scene(), {
1544      get props() {
1545        return props.scene || {};
1546      }
1547    });
1548  });
1549  const raycaster = createMemo(() => {
1550    if (raycasterIsInstance()) {
1551      return meta(props.raycaster, {
1552        get props() {
1553          return props.raycaster || {};
1554        }
1555      });
1556    }
1557    return meta(new CursorRaycaster(), {
1558      get props() {
1559        return props.raycaster || {};
1560      }
1561    });
1562  });
1563  const raycasterStack = new Stack("raycaster");
1564  let ownsCurrentRenderer = false;
1565  let initialConstructorArgs = {};
1566  const gl = createMemo((previous) => {
1567    if (previous && ownsCurrentRenderer) {
1568      const old = previous;
1569      old.dispose?.();
1570      if ("forceContextLoss" in old) old.forceContextLoss();
1571    }
1572    const kind = glKind();
1573    let _gl;
1574    if (kind === "factory") {
1575      _gl = props.gl(canvas);
1576      ownsCurrentRenderer = false;
1577    } else if (kind === "instance") {
1578      _gl = props.gl;
1579      ownsCurrentRenderer = false;
1580    } else {
1581      const flat = untrack(() => props.gl ?? {});
1582      const constructorArgs = {};
1583      for (const key of WEBGL_CONSTRUCTOR_KEYS) {
1584        if (key in flat) constructorArgs[key] = flat[key];
1585      }
1586      initialConstructorArgs = constructorArgs;
1587      _gl = new WebGLRenderer({
1588        alpha: true,
1589        ...constructorArgs,
1590        canvas
1591      });
1592      ownsCurrentRenderer = true;
1593    }
1594    return meta(_gl, {
1595      get props() {
1596        return props.gl || {};
1597      }
1598    });
1599  });
1600  const [rendererReady] = createResource(() => gl(), (renderer) => {
1601    const init = getPendingInit(renderer);
1602    if (!init) return true;
1603    const rect = canvas.getBoundingClientRect();
1604    const ratio = globalThis.devicePixelRatio || 1;
1605    if (rect.width > 0 && rect.height > 0) {
1606      canvas.width = rect.width * ratio;
1607      canvas.height = rect.height * ratio;
1608    }
1609    return init().then(() => true);
1610  });
1611  const measure = useMeasure();
1612  measure.setElement(canvas);
1613  const defaultTarget = new Vector3();
1614  const viewport = createMemo(() => getCurrentViewport(camera(), defaultTarget, measure.bounds()));
1615  const clock = new Clock();
1616  clock.start();
1617  const context = {
1618    get bounds() {
1619      return measure.bounds();
1620    },
1621    canvas,
1622    clock,
1623    get dpr() {
1624      return this.gl.getPixelRatio?.() ?? 1;
1625    },
1626    props,
1627    render,
1628    requestRender,
1629    get viewport() {
1630      return viewport();
1631    },
1632    // elements
1633    get camera() {
1634      return cameraStack.peek() ?? camera();
1635    },
1636    setCamera(camera2) {
1637      return cameraStack.push(camera2);
1638    },
1639    get scene() {
1640      return scene();
1641    },
1642    get raycaster() {
1643      return raycasterStack.peek() || raycaster();
1644    },
1645    setRaycaster(raycaster2) {
1646      return raycasterStack.push(raycaster2);
1647    },
1648    get gl() {
1649      return gl();
1650    }
1651  };
1652  withMultiContexts(() => {
1653    createRenderEffect(() => {
1654      if (props.frameloop === "never") {
1655        context.clock.stop();
1656        context.clock.elapsedTime = 0;
1657      } else {
1658        context.clock.start();
1659      }
1660    });
1661    createRenderEffect(() => {
1662      if (cameraStack.peek()) return;
1663      if (!props.camera || props.camera instanceof Camera) return;
1664      useProps(camera, props.camera);
1665      camera().updateMatrixWorld(true);
1666    });
1667    createRenderEffect(() => {
1668      if (!props.scene || props.scene instanceof Scene) return;
1669      useProps(scene, props.scene);
1670    });
1671    createRenderEffect(() => {
1672      if (!props.raycaster || props.raycaster instanceof Raycaster) return;
1673      useProps(raycaster, props.raycaster);
1674    });
1675    createRenderEffect(() => {
1676      createRenderEffect(() => {
1677        const shadowMap = gl().shadowMap;
1678        if (!shadowMap) return;
1679        const oldEnabled = shadowMap.enabled;
1680        const oldType = shadowMap.type;
1681        shadowMap.enabled = !!props.shadows;
1682        if (typeof props.shadows === "boolean") {
1683          shadowMap.type = PCFSoftShadowMap;
1684        } else if (typeof props.shadows === "string") {
1685          const types = {
1686            basic: BasicShadowMap,
1687            percentage: PCFShadowMap,
1688            soft: PCFSoftShadowMap,
1689            variance: VSMShadowMap
1690          };
1691          shadowMap.type = types[props.shadows] ?? PCFSoftShadowMap;
1692        } else if (typeof props.shadows === "object") {
1693          Object.assign(shadowMap, props.shadows);
1694        }
1695        if (isWebGLShadowMap(shadowMap) && (oldEnabled !== shadowMap.enabled || oldType !== shadowMap.type)) {
1696          shadowMap.needsUpdate = true;
1697        }
1698      });
1699      const _gl = gl();
1700      if ("outputColorSpace" in _gl) {
1701        useProps(gl, {
1702          get outputColorSpace() {
1703            return props.linear ? LinearSRGBColorSpace : SRGBColorSpace;
1704          }
1705        });
1706      }
1707      if ("toneMapping" in _gl) {
1708        useProps(gl, {
1709          get toneMapping() {
1710            return props.flat ? NoToneMapping : ACESFilmicToneMapping;
1711          }
1712        });
1713      }
1714      const _propsGl = props.gl;
1715      if (_propsGl && typeof _propsGl !== "function" && !isRenderer(_propsGl)) {
1716        useProps(gl, _propsGl);
1717      }
1718      let warnedCtorKeys = false;
1719      createEffect(() => {
1720        if (warnedCtorKeys) return;
1721        const flat = props.gl ?? {};
1722        for (const key of WEBGL_CONSTRUCTOR_KEYS) {
1723          if (key in flat && flat[key] !== initialConstructorArgs[key]) {
1724            warnedCtorKeys = true;
1725            return;
1726          }
1727        }
1728      });
1729    });
1730  }, [[threeContext, context]]);
1731  let pendingLoopRequest;
1732  function loop(value) {
1733    if (isPresenting()) {
1734      pendingLoopRequest = void 0;
1735      return;
1736    }
1737    pendingLoopRequest = requestAnimationFrame(loop);
1738    context.render(value);
1739  }
1740  createRenderEffect(() => {
1741    if (canvasProps.frameloop === "always") {
1742      pendingLoopRequest = requestAnimationFrame(loop);
1743    }
1744    onCleanup(() => pendingLoopRequest && cancelAnimationFrame(pendingLoopRequest));
1745  });
1746  createRenderEffect(() => {
1747    const _gl = gl();
1748    const xr = _gl.xr;
1749    if (!xr || typeof xr.addEventListener !== "function") return;
1750    const resume = () => {
1751      if (canvasProps.frameloop === "always") {
1752        if (!pendingLoopRequest) pendingLoopRequest = requestAnimationFrame(loop);
1753      } else if (canvasProps.frameloop === "demand") {
1754        requestRender();
1755      }
1756    };
1757    xr.addEventListener("sessionend", resume);
1758    onCleanup(() => xr.removeEventListener("sessionend", resume));
1759  });
1760  const {
1761    addEventListener
1762  } = createEvents(context);
1763  const c = children(() => createComponent(eventContext.Provider, {
1764    value: addEventListener,
1765    get children() {
1766      return createComponent(frameContext.Provider, {
1767        value: addFrameListener,
1768        get children() {
1769          return createComponent(threeContext.Provider, {
1770            value: context,
1771            get children() {
1772              return canvasProps.children;
1773            }
1774          });
1775        }
1776      });
1777    }
1778  }));
1779  useSceneGraph(context.scene, {
1780    get children() {
1781      return c();
1782    }
1783  });
1784  withMultiContexts(() => useRef(props, context), [[threeContext, context], [frameContext, addFrameListener]]);
1785  return mergeProps(context, {
1786    addFrameListener
1787  });
1788}
1789var _tmpl$ = /* @__PURE__ */ template(`<div style=position:relative;width:100%;height:100%;overflow:hidden;contain:strict;display:flex><canvas>`);
1790function Canvas(props) {
1791  let canvas;
1792  let container;
1793  onMount(() => {
1794    if (!canvas || !container) return;
1795    const context = createThree(canvas, props);
1796    createResizeObserver(container, function onResize() {
1797      const {
1798        width,
1799        height
1800      } = container.getBoundingClientRect();
1801      context.gl.setSize(width, height);
1802      context.gl.setPixelRatio?.(globalThis.devicePixelRatio);
1803      if (context.camera instanceof OrthographicCamera) {
1804        context.camera.left = width / -2;
1805        context.camera.right = width / 2;
1806        context.camera.top = height / 2;
1807        context.camera.bottom = height / -2;
1808      } else {
1809        context.camera.aspect = width / height;
1810      }
1811      context.camera.updateProjectionMatrix();
1812      if (!context.gl?.xr?.isPresenting) context.render(performance.now());
1813    });
1814  });
1815  return (() => {
1816    var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
1817    var _ref$ = container;
1818    typeof _ref$ === "function" ? use(_ref$, _el$) : container = _el$;
1819    var _ref$2 = canvas;
1820    typeof _ref$2 === "function" ? use(_ref$2, _el$2) : canvas = _el$2;
1821    createRenderEffect((_p$) => {
1822      var _v$ = {
1823        ...props.style
1824      }, _v$2 = props.class;
1825      _p$.e = style(_el$, _v$, _p$.e);
1826      _v$2 !== _p$.t && className(_el$, _p$.t = _v$2);
1827      return _p$;
1828    }, {
1829      e: void 0,
1830      t: void 0
1831    });
1832    return _el$;
1833  })();
1834}
1835function Resource(props) {
1836  const [options, config, rest] = splitProps(props, ["base", "cache", "onBeforeLoad", "onLoad"], ["loader", "url", "children"]);
1837  const resource = useLoader(() => config.loader, () => config.url, options);
1838  const tagged = createMemo(() => {
1839    const value = resource();
1840    if (!value || typeof value !== "object") return value;
1841    return hasMeta(value) ? value : meta(value, {
1842      props
1843    });
1844  });
1845  useProps(tagged, rest);
1846  return createComponent(Show, {
1847    get when() {
1848      return memo(() => "children" in config)() && tagged();
1849    },
1850    get fallback() {
1851      return tagged();
1852    },
1853    children: (value) => props.children?.(value)
1854  });
1855}
1856function createT(catalogue) {
1857  const cache = /* @__PURE__ */ new Map();
1858  return new Proxy({}, {
1859    get: (_, name) => {
1860      if (!cache.has(name)) {
1861        const constructor = catalogue[name];
1862        if (!constructor) return void 0;
1863        cache.set(name, createEntity(constructor));
1864      }
1865      return cache.get(name);
1866    }
1867  });
1868}
1869function createEntity(Constructor) {
1870  return (props) => {
1871    const memo2 = createMemo(() => {
1872      props.key;
1873      try {
1874        return meta(autodispose(new Constructor(...props.args ?? [])), {
1875          props
1876        });
1877      } catch (e) {
1878        throw new Error("");
1879      }
1880    });
1881    useProps(memo2, props);
1882    return memo2;
1883  };
1884}
1885var xrContext = createContext();
1886function useXR() {
1887  const state = useContext(xrContext);
1888  if (!state) {
1889    throw new Error("S3: useXR must be used within <xr.Provider> (from createXR())");
1890  }
1891  return state;
1892}
1893function createXR() {
1894  const [context, setContext] = createSignal();
1895  const [presenting, setPresenting] = createSignal(false);
1896  const [session, setSession] = createSignal();
1897  createRenderEffect(() => {
1898    const ctx = context();
1899    const gl = ctx ? ctx.gl : void 0;
1900    const xr = gl?.xr;
1901    if (!gl || !xr || typeof xr.addEventListener !== "function") return;
1902    const onStart = () => setPresenting(true);
1903    const onEnd = () => {
1904      setPresenting(false);
1905      setSession(void 0);
1906      gl.setAnimationLoop(null);
1907      gl.xr.enabled = false;
1908    };
1909    xr.addEventListener("sessionstart", onStart);
1910    xr.addEventListener("sessionend", onEnd);
1911    onCleanup(() => {
1912      xr.removeEventListener("sessionstart", onStart);
1913      xr.removeEventListener("sessionend", onEnd);
1914    });
1915  });
1916  function connect(value) {
1917    setContext(value);
1918    return () => setContext(void 0);
1919  }
1920  function requestSession(mode, init) {
1921    if (!navigator.xr) {
1922      throw new Error("S3: WebXR unavailable (navigator.xr is undefined)");
1923    }
1924    return navigator.xr.requestSession(mode, init);
1925  }
1926  async function enter(arg, init) {
1927    const ctx = context();
1928    if (!ctx) {
1929      throw new Error("S3: createXR().enter() called before <Canvas ref={xr.connect}> connected");
1930    }
1931    const gl = ctx.gl;
1932    if (!gl.xr) {
1933      throw new Error("S3: the active renderer has no xr manager");
1934    }
1935    const xrSession = typeof arg === "string" ? await requestSession(arg, init) : arg;
1936    gl.setAnimationLoop(ctx.render);
1937    gl.xr.enabled = true;
1938    await gl.xr.setSession(xrSession);
1939    setSession(xrSession);
1940    return xrSession;
1941  }
1942  async function exit() {
1943    await session()?.end();
1944  }
1945  function isSupported(mode) {
1946    return navigator.xr?.isSessionSupported(mode) ?? Promise.resolve(false);
1947  }
1948  const state = {
1949    isPresenting: presenting,
1950    session,
1951    exit
1952  };
1953  function Provider(props) {
1954    return createComponent(xrContext.Provider, {
1955      value: state,
1956      get children() {
1957        return props.children;
1958      }
1959    });
1960  }
1961  return {
1962    connect,
1963    enter,
1964    exit,
1965    isSupported,
1966    isPresenting: presenting,
1967    session,
1968    Provider
1969  };
1970}
1971
vendor: 2,132 bytes, lines 1972-2031
1972// node_modules/three-stdlib/utils/BufferGeometryUtils.js
1973function toTrianglesDrawMode(geometry, drawMode) {
1974  if (drawMode === TrianglesDrawMode) {
1975    console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles.");
1976    return geometry;
1977  }
1978  if (drawMode === TriangleFanDrawMode || drawMode === TriangleStripDrawMode) {
1979    let index = geometry.getIndex();
1980    if (index === null) {
1981      const indices = [];
1982      const position2 = geometry.getAttribute("position");
1983      if (position2 !== void 0) {
1984        for (let i = 0; i < position2.count; i++) {
1985          indices.push(i);
1986        }
1987        geometry.setIndex(indices);
1988        index = geometry.getIndex();
1989      } else {
1990        console.error(
1991          "THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."
1992        );
1993        return geometry;
1994      }
1995    }
1996    const numberOfTriangles = index.count - 2;
1997    const newIndices = [];
1998    if (index) {
1999      if (drawMode === TriangleFanDrawMode) {
2000        for (let i = 1; i <= numberOfTriangles; i++) {
2001          newIndices.push(index.getX(0));
2002          newIndices.push(index.getX(i));
2003          newIndices.push(index.getX(i + 1));
2004        }
2005      } else {
2006        for (let i = 0; i < numberOfTriangles; i++) {
2007          if (i % 2 === 0) {
2008            newIndices.push(index.getX(i));
2009            newIndices.push(index.getX(i + 1));
2010            newIndices.push(index.getX(i + 2));
2011          } else {
2012            newIndices.push(index.getX(i + 2));
2013            newIndices.push(index.getX(i + 1));
2014            newIndices.push(index.getX(i));
2015          }
2016        }
2017      }
2018    }
2019    if (newIndices.length / 3 !== numberOfTriangles) {
2020      console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");
2021    }
2022    const newGeometry = geometry.clone();
2023    newGeometry.setIndex(newIndices);
2024    newGeometry.clearGroups();
2025    return newGeometry;
2026  } else {
2027    console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:", drawMode);
2028    return geometry;
2029  }
2030}
2031
vendor: 133 bytes, lines 2032-2034
2032// node_modules/three-stdlib/_polyfill/constants.js
2033var version = /* @__PURE__ */ (() => parseInt(REVISION.replace(/\D+/g, "")))();
2034
vendor: 372 bytes, lines 2035-2050
2035// node_modules/three-stdlib/_polyfill/LoaderUtils.js
2036function decodeText(array) {
2037  if (typeof TextDecoder !== "undefined") {
2038    return new TextDecoder().decode(array);
2039  }
2040  let s = "";
2041  for (let i = 0, il = array.length; i < il; i++) {
2042    s += String.fromCharCode(array[i]);
2043  }
2044  try {
2045    return decodeURIComponent(escape(s));
2046  } catch (e) {
2047    return s;
2048  }
2049}
2050
vendor: 98,781 bytes, lines 2051-4669
2051// node_modules/three-stdlib/loaders/GLTFLoader.js
2052var SRGBColorSpace2 = "srgb";
2053var LinearSRGBColorSpace2 = "srgb-linear";
2054var sRGBEncoding = 3001;
2055var LinearEncoding = 3e3;
2056var GLTFLoader = class extends Loader {
2057  constructor(manager) {
2058    super(manager);
2059    this.dracoLoader = null;
2060    this.ktx2Loader = null;
2061    this.meshoptDecoder = null;
2062    this.pluginCallbacks = [];
2063    this.register(function(parser) {
2064      return new GLTFMaterialsClearcoatExtension(parser);
2065    });
2066    this.register(function(parser) {
2067      return new GLTFMaterialsDispersionExtension(parser);
2068    });
2069    this.register(function(parser) {
2070      return new GLTFTextureBasisUExtension(parser);
2071    });
2072    this.register(function(parser) {
2073      return new GLTFTextureWebPExtension(parser);
2074    });
2075    this.register(function(parser) {
2076      return new GLTFTextureAVIFExtension(parser);
2077    });
2078    this.register(function(parser) {
2079      return new GLTFMaterialsSheenExtension(parser);
2080    });
2081    this.register(function(parser) {
2082      return new GLTFMaterialsTransmissionExtension(parser);
2083    });
2084    this.register(function(parser) {
2085      return new GLTFMaterialsVolumeExtension(parser);
2086    });
2087    this.register(function(parser) {
2088      return new GLTFMaterialsIorExtension(parser);
2089    });
2090    this.register(function(parser) {
2091      return new GLTFMaterialsEmissiveStrengthExtension(parser);
2092    });
2093    this.register(function(parser) {
2094      return new GLTFMaterialsSpecularExtension(parser);
2095    });
2096    this.register(function(parser) {
2097      return new GLTFMaterialsIridescenceExtension(parser);
2098    });
2099    this.register(function(parser) {
2100      return new GLTFMaterialsAnisotropyExtension(parser);
2101    });
2102    this.register(function(parser) {
2103      return new GLTFMaterialsBumpExtension(parser);
2104    });
2105    this.register(function(parser) {
2106      return new GLTFLightsExtension(parser);
2107    });
2108    this.register(function(parser) {
2109      return new GLTFMeshoptCompression(parser);
2110    });
2111    this.register(function(parser) {
2112      return new GLTFMeshGpuInstancing(parser);
2113    });
2114  }
2115  load(url, onLoad, onProgress, onError) {
2116    const scope = this;
2117    let resourcePath;
2118    if (this.resourcePath !== "") {
2119      resourcePath = this.resourcePath;
2120    } else if (this.path !== "") {
2121      const relativeUrl = LoaderUtils.extractUrlBase(url);
2122      resourcePath = LoaderUtils.resolveURL(relativeUrl, this.path);
2123    } else {
2124      resourcePath = LoaderUtils.extractUrlBase(url);
2125    }
2126    this.manager.itemStart(url);
2127    const _onError = function(e) {
2128      if (onError) {
2129        onError(e);
2130      } else {
2131        console.error(e);
2132      }
2133      scope.manager.itemError(url);
2134      scope.manager.itemEnd(url);
2135    };
2136    const loader = new FileLoader(this.manager);
2137    loader.setPath(this.path);
2138    loader.setResponseType("arraybuffer");
2139    loader.setRequestHeader(this.requestHeader);
2140    loader.setWithCredentials(this.withCredentials);
2141    loader.load(
2142      url,
2143      function(data) {
2144        try {
2145          scope.parse(
2146            data,
2147            resourcePath,
2148            function(gltf) {
2149              onLoad(gltf);
2150              scope.manager.itemEnd(url);
2151            },
2152            _onError
2153          );
2154        } catch (e) {
2155          _onError(e);
2156        }
2157      },
2158      onProgress,
2159      _onError
2160    );
2161  }
2162  setDRACOLoader(dracoLoader) {
2163    this.dracoLoader = dracoLoader;
2164    return this;
2165  }
2166  setDDSLoader() {
2167    throw new Error('THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".');
2168  }
2169  setKTX2Loader(ktx2Loader) {
2170    this.ktx2Loader = ktx2Loader;
2171    return this;
2172  }
2173  setMeshoptDecoder(meshoptDecoder) {
2174    this.meshoptDecoder = meshoptDecoder;
2175    return this;
2176  }
2177  register(callback) {
2178    if (this.pluginCallbacks.indexOf(callback) === -1) {
2179      this.pluginCallbacks.push(callback);
2180    }
2181    return this;
2182  }
2183  unregister(callback) {
2184    if (this.pluginCallbacks.indexOf(callback) !== -1) {
2185      this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
2186    }
2187    return this;
2188  }
2189  parse(data, path, onLoad, onError) {
2190    let json;
2191    const extensions = {};
2192    const plugins = {};
2193    if (typeof data === "string") {
2194      json = JSON.parse(data);
2195    } else if (data instanceof ArrayBuffer) {
2196      const magic = decodeText(new Uint8Array(data.slice(0, 4)));
2197      if (magic === BINARY_EXTENSION_HEADER_MAGIC) {
2198        try {
2199          extensions[EXTENSIONS.KHR_BINARY_GLTF] = new GLTFBinaryExtension(data);
2200        } catch (error) {
2201          if (onError)
2202            onError(error);
2203          return;
2204        }
2205        json = JSON.parse(extensions[EXTENSIONS.KHR_BINARY_GLTF].content);
2206      } else {
2207        json = JSON.parse(decodeText(new Uint8Array(data)));
2208      }
2209    } else {
2210      json = data;
2211    }
2212    if (json.asset === void 0 || json.asset.version[0] < 2) {
2213      if (onError)
2214        onError(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));
2215      return;
2216    }
2217    const parser = new GLTFParser(json, {
2218      path: path || this.resourcePath || "",
2219      crossOrigin: this.crossOrigin,
2220      requestHeader: this.requestHeader,
2221      manager: this.manager,
2222      ktx2Loader: this.ktx2Loader,
2223      meshoptDecoder: this.meshoptDecoder
2224    });
2225    parser.fileLoader.setRequestHeader(this.requestHeader);
2226    for (let i = 0; i < this.pluginCallbacks.length; i++) {
2227      const plugin = this.pluginCallbacks[i](parser);
2228      if (!plugin.name)
2229        console.error("THREE.GLTFLoader: Invalid plugin found: missing name");
2230      plugins[plugin.name] = plugin;
2231      extensions[plugin.name] = true;
2232    }
2233    if (json.extensionsUsed) {
2234      for (let i = 0; i < json.extensionsUsed.length; ++i) {
2235        const extensionName = json.extensionsUsed[i];
2236        const extensionsRequired = json.extensionsRequired || [];
2237        switch (extensionName) {
2238          case EXTENSIONS.KHR_MATERIALS_UNLIT:
2239            extensions[extensionName] = new GLTFMaterialsUnlitExtension();
2240            break;
2241          case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
2242            extensions[extensionName] = new GLTFDracoMeshCompressionExtension(json, this.dracoLoader);
2243            break;
2244          case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
2245            extensions[extensionName] = new GLTFTextureTransformExtension();
2246            break;
2247          case EXTENSIONS.KHR_MESH_QUANTIZATION:
2248            extensions[extensionName] = new GLTFMeshQuantizationExtension();
2249            break;
2250          default:
2251            if (extensionsRequired.indexOf(extensionName) >= 0 && plugins[extensionName] === void 0) {
2252              console.warn('THREE.GLTFLoader: Unknown extension "' + extensionName + '".');
2253            }
2254        }
2255      }
2256    }
2257    parser.setExtensions(extensions);
2258    parser.setPlugins(plugins);
2259    parser.parse(onLoad, onError);
2260  }
2261  parseAsync(data, path) {
2262    const scope = this;
2263    return new Promise(function(resolve3, reject) {
2264      scope.parse(data, path, resolve3, reject);
2265    });
2266  }
2267};
2268function GLTFRegistry() {
2269  let objects = {};
2270  return {
2271    get: function(key) {
2272      return objects[key];
2273    },
2274    add: function(key, object) {
2275      objects[key] = object;
2276    },
2277    remove: function(key) {
2278      delete objects[key];
2279    },
2280    removeAll: function() {
2281      objects = {};
2282    }
2283  };
2284}
2285var EXTENSIONS = {
2286  KHR_BINARY_GLTF: "KHR_binary_glTF",
2287  KHR_DRACO_MESH_COMPRESSION: "KHR_draco_mesh_compression",
2288  KHR_LIGHTS_PUNCTUAL: "KHR_lights_punctual",
2289  KHR_MATERIALS_CLEARCOAT: "KHR_materials_clearcoat",
2290  KHR_MATERIALS_DISPERSION: "KHR_materials_dispersion",
2291  KHR_MATERIALS_IOR: "KHR_materials_ior",
2292  KHR_MATERIALS_SHEEN: "KHR_materials_sheen",
2293  KHR_MATERIALS_SPECULAR: "KHR_materials_specular",
2294  KHR_MATERIALS_TRANSMISSION: "KHR_materials_transmission",
2295  KHR_MATERIALS_IRIDESCENCE: "KHR_materials_iridescence",
2296  KHR_MATERIALS_ANISOTROPY: "KHR_materials_anisotropy",
2297  KHR_MATERIALS_UNLIT: "KHR_materials_unlit",
2298  KHR_MATERIALS_VOLUME: "KHR_materials_volume",
2299  KHR_TEXTURE_BASISU: "KHR_texture_basisu",
2300  KHR_TEXTURE_TRANSFORM: "KHR_texture_transform",
2301  KHR_MESH_QUANTIZATION: "KHR_mesh_quantization",
2302  KHR_MATERIALS_EMISSIVE_STRENGTH: "KHR_materials_emissive_strength",
2303  EXT_MATERIALS_BUMP: "EXT_materials_bump",
2304  EXT_TEXTURE_WEBP: "EXT_texture_webp",
2305  EXT_TEXTURE_AVIF: "EXT_texture_avif",
2306  EXT_MESHOPT_COMPRESSION: "EXT_meshopt_compression",
2307  EXT_MESH_GPU_INSTANCING: "EXT_mesh_gpu_instancing"
2308};
2309var GLTFLightsExtension = class {
2310  constructor(parser) {
2311    this.parser = parser;
2312    this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL;
2313    this.cache = { refs: {}, uses: {} };
2314  }
2315  _markDefs() {
2316    const parser = this.parser;
2317    const nodeDefs = this.parser.json.nodes || [];
2318    for (let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++) {
2319      const nodeDef = nodeDefs[nodeIndex];
2320      if (nodeDef.extensions && nodeDef.extensions[this.name] && nodeDef.extensions[this.name].light !== void 0) {
2321        parser._addNodeRef(this.cache, nodeDef.extensions[this.name].light);
2322      }
2323    }
2324  }
2325  _loadLight(lightIndex) {
2326    const parser = this.parser;
2327    const cacheKey = "light:" + lightIndex;
2328    let dependency = parser.cache.get(cacheKey);
2329    if (dependency)
2330      return dependency;
2331    const json = parser.json;
2332    const extensions = json.extensions && json.extensions[this.name] || {};
2333    const lightDefs = extensions.lights || [];
2334    const lightDef = lightDefs[lightIndex];
2335    let lightNode;
2336    const color = new Color(16777215);
2337    if (lightDef.color !== void 0)
2338      color.setRGB(lightDef.color[0], lightDef.color[1], lightDef.color[2], LinearSRGBColorSpace2);
2339    const range = lightDef.range !== void 0 ? lightDef.range : 0;
2340    switch (lightDef.type) {
2341      case "directional":
2342        lightNode = new DirectionalLight(color);
2343        lightNode.target.position.set(0, 0, -1);
2344        lightNode.add(lightNode.target);
2345        break;
2346      case "point":
2347        lightNode = new PointLight(color);
2348        lightNode.distance = range;
2349        break;
2350      case "spot":
2351        lightNode = new SpotLight(color);
2352        lightNode.distance = range;
2353        lightDef.spot = lightDef.spot || {};
2354        lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== void 0 ? lightDef.spot.innerConeAngle : 0;
2355        lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== void 0 ? lightDef.spot.outerConeAngle : Math.PI / 4;
2356        lightNode.angle = lightDef.spot.outerConeAngle;
2357        lightNode.penumbra = 1 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
2358        lightNode.target.position.set(0, 0, -1);
2359        lightNode.add(lightNode.target);
2360        break;
2361      default:
2362        throw new Error("THREE.GLTFLoader: Unexpected light type: " + lightDef.type);
2363    }
2364    lightNode.position.set(0, 0, 0);
2365    lightNode.decay = 2;
2366    assignExtrasToUserData(lightNode, lightDef);
2367    if (lightDef.intensity !== void 0)
2368      lightNode.intensity = lightDef.intensity;
2369    lightNode.name = parser.createUniqueName(lightDef.name || "light_" + lightIndex);
2370    dependency = Promise.resolve(lightNode);
2371    parser.cache.add(cacheKey, dependency);
2372    return dependency;
2373  }
2374  getDependency(type, index) {
2375    if (type !== "light")
2376      return;
2377    return this._loadLight(index);
2378  }
2379  createNodeAttachment(nodeIndex) {
2380    const self2 = this;
2381    const parser = this.parser;
2382    const json = parser.json;
2383    const nodeDef = json.nodes[nodeIndex];
2384    const lightDef = nodeDef.extensions && nodeDef.extensions[this.name] || {};
2385    const lightIndex = lightDef.light;
2386    if (lightIndex === void 0)
2387      return null;
2388    return this._loadLight(lightIndex).then(function(light) {
2389      return parser._getNodeRef(self2.cache, lightIndex, light);
2390    });
2391  }
2392};
2393var GLTFMaterialsUnlitExtension = class {
2394  constructor() {
2395    this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;
2396  }
2397  getMaterialType() {
2398    return MeshBasicMaterial;
2399  }
2400  extendParams(materialParams, materialDef, parser) {
2401    const pending = [];
2402    materialParams.color = new Color(1, 1, 1);
2403    materialParams.opacity = 1;
2404    const metallicRoughness = materialDef.pbrMetallicRoughness;
2405    if (metallicRoughness) {
2406      if (Array.isArray(metallicRoughness.baseColorFactor)) {
2407        const array = metallicRoughness.baseColorFactor;
2408        materialParams.color.setRGB(array[0], array[1], array[2], LinearSRGBColorSpace2);
2409        materialParams.opacity = array[3];
2410      }
2411      if (metallicRoughness.baseColorTexture !== void 0) {
2412        pending.push(parser.assignTexture(materialParams, "map", metallicRoughness.baseColorTexture, SRGBColorSpace2));
2413      }
2414    }
2415    return Promise.all(pending);
2416  }
2417};
2418var GLTFMaterialsEmissiveStrengthExtension = class {
2419  constructor(parser) {
2420    this.parser = parser;
2421    this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH;
2422  }
2423  extendMaterialParams(materialIndex, materialParams) {
2424    const parser = this.parser;
2425    const materialDef = parser.json.materials[materialIndex];
2426    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2427      return Promise.resolve();
2428    }
2429    const emissiveStrength = materialDef.extensions[this.name].emissiveStrength;
2430    if (emissiveStrength !== void 0) {
2431      materialParams.emissiveIntensity = emissiveStrength;
2432    }
2433    return Promise.resolve();
2434  }
2435};
2436var GLTFMaterialsClearcoatExtension = class {
2437  constructor(parser) {
2438    this.parser = parser;
2439    this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
2440  }
2441  getMaterialType(materialIndex) {
2442    const parser = this.parser;
2443    const materialDef = parser.json.materials[materialIndex];
2444    if (!materialDef.extensions || !materialDef.extensions[this.name])
2445      return null;
2446    return MeshPhysicalMaterial;
2447  }
2448  extendMaterialParams(materialIndex, materialParams) {
2449    const parser = this.parser;
2450    const materialDef = parser.json.materials[materialIndex];
2451    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2452      return Promise.resolve();
2453    }
2454    const pending = [];
2455    const extension = materialDef.extensions[this.name];
2456    if (extension.clearcoatFactor !== void 0) {
2457      materialParams.clearcoat = extension.clearcoatFactor;
2458    }
2459    if (extension.clearcoatTexture !== void 0) {
2460      pending.push(parser.assignTexture(materialParams, "clearcoatMap", extension.clearcoatTexture));
2461    }
2462    if (extension.clearcoatRoughnessFactor !== void 0) {
2463      materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;
2464    }
2465    if (extension.clearcoatRoughnessTexture !== void 0) {
2466      pending.push(parser.assignTexture(materialParams, "clearcoatRoughnessMap", extension.clearcoatRoughnessTexture));
2467    }
2468    if (extension.clearcoatNormalTexture !== void 0) {
2469      pending.push(parser.assignTexture(materialParams, "clearcoatNormalMap", extension.clearcoatNormalTexture));
2470      if (extension.clearcoatNormalTexture.scale !== void 0) {
2471        const scale = extension.clearcoatNormalTexture.scale;
2472        materialParams.clearcoatNormalScale = new Vector2(scale, scale);
2473      }
2474    }
2475    return Promise.all(pending);
2476  }
2477};
2478var GLTFMaterialsDispersionExtension = class {
2479  constructor(parser) {
2480    this.parser = parser;
2481    this.name = EXTENSIONS.KHR_MATERIALS_DISPERSION;
2482  }
2483  getMaterialType(materialIndex) {
2484    const parser = this.parser;
2485    const materialDef = parser.json.materials[materialIndex];
2486    if (!materialDef.extensions || !materialDef.extensions[this.name])
2487      return null;
2488    return MeshPhysicalMaterial;
2489  }
2490  extendMaterialParams(materialIndex, materialParams) {
2491    const parser = this.parser;
2492    const materialDef = parser.json.materials[materialIndex];
2493    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2494      return Promise.resolve();
2495    }
2496    const extension = materialDef.extensions[this.name];
2497    materialParams.dispersion = extension.dispersion !== void 0 ? extension.dispersion : 0;
2498    return Promise.resolve();
2499  }
2500};
2501var GLTFMaterialsIridescenceExtension = class {
2502  constructor(parser) {
2503    this.parser = parser;
2504    this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE;
2505  }
2506  getMaterialType(materialIndex) {
2507    const parser = this.parser;
2508    const materialDef = parser.json.materials[materialIndex];
2509    if (!materialDef.extensions || !materialDef.extensions[this.name])
2510      return null;
2511    return MeshPhysicalMaterial;
2512  }
2513  extendMaterialParams(materialIndex, materialParams) {
2514    const parser = this.parser;
2515    const materialDef = parser.json.materials[materialIndex];
2516    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2517      return Promise.resolve();
2518    }
2519    const pending = [];
2520    const extension = materialDef.extensions[this.name];
2521    if (extension.iridescenceFactor !== void 0) {
2522      materialParams.iridescence = extension.iridescenceFactor;
2523    }
2524    if (extension.iridescenceTexture !== void 0) {
2525      pending.push(parser.assignTexture(materialParams, "iridescenceMap", extension.iridescenceTexture));
2526    }
2527    if (extension.iridescenceIor !== void 0) {
2528      materialParams.iridescenceIOR = extension.iridescenceIor;
2529    }
2530    if (materialParams.iridescenceThicknessRange === void 0) {
2531      materialParams.iridescenceThicknessRange = [100, 400];
2532    }
2533    if (extension.iridescenceThicknessMinimum !== void 0) {
2534      materialParams.iridescenceThicknessRange[0] = extension.iridescenceThicknessMinimum;
2535    }
2536    if (extension.iridescenceThicknessMaximum !== void 0) {
2537      materialParams.iridescenceThicknessRange[1] = extension.iridescenceThicknessMaximum;
2538    }
2539    if (extension.iridescenceThicknessTexture !== void 0) {
2540      pending.push(
2541        parser.assignTexture(materialParams, "iridescenceThicknessMap", extension.iridescenceThicknessTexture)
2542      );
2543    }
2544    return Promise.all(pending);
2545  }
2546};
2547var GLTFMaterialsSheenExtension = class {
2548  constructor(parser) {
2549    this.parser = parser;
2550    this.name = EXTENSIONS.KHR_MATERIALS_SHEEN;
2551  }
2552  getMaterialType(materialIndex) {
2553    const parser = this.parser;
2554    const materialDef = parser.json.materials[materialIndex];
2555    if (!materialDef.extensions || !materialDef.extensions[this.name])
2556      return null;
2557    return MeshPhysicalMaterial;
2558  }
2559  extendMaterialParams(materialIndex, materialParams) {
2560    const parser = this.parser;
2561    const materialDef = parser.json.materials[materialIndex];
2562    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2563      return Promise.resolve();
2564    }
2565    const pending = [];
2566    materialParams.sheenColor = new Color(0, 0, 0);
2567    materialParams.sheenRoughness = 0;
2568    materialParams.sheen = 1;
2569    const extension = materialDef.extensions[this.name];
2570    if (extension.sheenColorFactor !== void 0) {
2571      const colorFactor = extension.sheenColorFactor;
2572      materialParams.sheenColor.setRGB(colorFactor[0], colorFactor[1], colorFactor[2], LinearSRGBColorSpace2);
2573    }
2574    if (extension.sheenRoughnessFactor !== void 0) {
2575      materialParams.sheenRoughness = extension.sheenRoughnessFactor;
2576    }
2577    if (extension.sheenColorTexture !== void 0) {
2578      pending.push(parser.assignTexture(materialParams, "sheenColorMap", extension.sheenColorTexture, SRGBColorSpace2));
2579    }
2580    if (extension.sheenRoughnessTexture !== void 0) {
2581      pending.push(parser.assignTexture(materialParams, "sheenRoughnessMap", extension.sheenRoughnessTexture));
2582    }
2583    return Promise.all(pending);
2584  }
2585};
2586var GLTFMaterialsTransmissionExtension = class {
2587  constructor(parser) {
2588    this.parser = parser;
2589    this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;
2590  }
2591  getMaterialType(materialIndex) {
2592    const parser = this.parser;
2593    const materialDef = parser.json.materials[materialIndex];
2594    if (!materialDef.extensions || !materialDef.extensions[this.name])
2595      return null;
2596    return MeshPhysicalMaterial;
2597  }
2598  extendMaterialParams(materialIndex, materialParams) {
2599    const parser = this.parser;
2600    const materialDef = parser.json.materials[materialIndex];
2601    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2602      return Promise.resolve();
2603    }
2604    const pending = [];
2605    const extension = materialDef.extensions[this.name];
2606    if (extension.transmissionFactor !== void 0) {
2607      materialParams.transmission = extension.transmissionFactor;
2608    }
2609    if (extension.transmissionTexture !== void 0) {
2610      pending.push(parser.assignTexture(materialParams, "transmissionMap", extension.transmissionTexture));
2611    }
2612    return Promise.all(pending);
2613  }
2614};
2615var GLTFMaterialsVolumeExtension = class {
2616  constructor(parser) {
2617    this.parser = parser;
2618    this.name = EXTENSIONS.KHR_MATERIALS_VOLUME;
2619  }
2620  getMaterialType(materialIndex) {
2621    const parser = this.parser;
2622    const materialDef = parser.json.materials[materialIndex];
2623    if (!materialDef.extensions || !materialDef.extensions[this.name])
2624      return null;
2625    return MeshPhysicalMaterial;
2626  }
2627  extendMaterialParams(materialIndex, materialParams) {
2628    const parser = this.parser;
2629    const materialDef = parser.json.materials[materialIndex];
2630    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2631      return Promise.resolve();
2632    }
2633    const pending = [];
2634    const extension = materialDef.extensions[this.name];
2635    materialParams.thickness = extension.thicknessFactor !== void 0 ? extension.thicknessFactor : 0;
2636    if (extension.thicknessTexture !== void 0) {
2637      pending.push(parser.assignTexture(materialParams, "thicknessMap", extension.thicknessTexture));
2638    }
2639    materialParams.attenuationDistance = extension.attenuationDistance || Infinity;
2640    const colorArray = extension.attenuationColor || [1, 1, 1];
2641    materialParams.attenuationColor = new Color().setRGB(
2642      colorArray[0],
2643      colorArray[1],
2644      colorArray[2],
2645      LinearSRGBColorSpace2
2646    );
2647    return Promise.all(pending);
2648  }
2649};
2650var GLTFMaterialsIorExtension = class {
2651  constructor(parser) {
2652    this.parser = parser;
2653    this.name = EXTENSIONS.KHR_MATERIALS_IOR;
2654  }
2655  getMaterialType(materialIndex) {
2656    const parser = this.parser;
2657    const materialDef = parser.json.materials[materialIndex];
2658    if (!materialDef.extensions || !materialDef.extensions[this.name])
2659      return null;
2660    return MeshPhysicalMaterial;
2661  }
2662  extendMaterialParams(materialIndex, materialParams) {
2663    const parser = this.parser;
2664    const materialDef = parser.json.materials[materialIndex];
2665    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2666      return Promise.resolve();
2667    }
2668    const extension = materialDef.extensions[this.name];
2669    materialParams.ior = extension.ior !== void 0 ? extension.ior : 1.5;
2670    return Promise.resolve();
2671  }
2672};
2673var GLTFMaterialsSpecularExtension = class {
2674  constructor(parser) {
2675    this.parser = parser;
2676    this.name = EXTENSIONS.KHR_MATERIALS_SPECULAR;
2677  }
2678  getMaterialType(materialIndex) {
2679    const parser = this.parser;
2680    const materialDef = parser.json.materials[materialIndex];
2681    if (!materialDef.extensions || !materialDef.extensions[this.name])
2682      return null;
2683    return MeshPhysicalMaterial;
2684  }
2685  extendMaterialParams(materialIndex, materialParams) {
2686    const parser = this.parser;
2687    const materialDef = parser.json.materials[materialIndex];
2688    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2689      return Promise.resolve();
2690    }
2691    const pending = [];
2692    const extension = materialDef.extensions[this.name];
2693    materialParams.specularIntensity = extension.specularFactor !== void 0 ? extension.specularFactor : 1;
2694    if (extension.specularTexture !== void 0) {
2695      pending.push(parser.assignTexture(materialParams, "specularIntensityMap", extension.specularTexture));
2696    }
2697    const colorArray = extension.specularColorFactor || [1, 1, 1];
2698    materialParams.specularColor = new Color().setRGB(colorArray[0], colorArray[1], colorArray[2], LinearSRGBColorSpace2);
2699    if (extension.specularColorTexture !== void 0) {
2700      pending.push(
2701        parser.assignTexture(materialParams, "specularColorMap", extension.specularColorTexture, SRGBColorSpace2)
2702      );
2703    }
2704    return Promise.all(pending);
2705  }
2706};
2707var GLTFMaterialsBumpExtension = class {
2708  constructor(parser) {
2709    this.parser = parser;
2710    this.name = EXTENSIONS.EXT_MATERIALS_BUMP;
2711  }
2712  getMaterialType(materialIndex) {
2713    const parser = this.parser;
2714    const materialDef = parser.json.materials[materialIndex];
2715    if (!materialDef.extensions || !materialDef.extensions[this.name])
2716      return null;
2717    return MeshPhysicalMaterial;
2718  }
2719  extendMaterialParams(materialIndex, materialParams) {
2720    const parser = this.parser;
2721    const materialDef = parser.json.materials[materialIndex];
2722    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2723      return Promise.resolve();
2724    }
2725    const pending = [];
2726    const extension = materialDef.extensions[this.name];
2727    materialParams.bumpScale = extension.bumpFactor !== void 0 ? extension.bumpFactor : 1;
2728    if (extension.bumpTexture !== void 0) {
2729      pending.push(parser.assignTexture(materialParams, "bumpMap", extension.bumpTexture));
2730    }
2731    return Promise.all(pending);
2732  }
2733};
2734var GLTFMaterialsAnisotropyExtension = class {
2735  constructor(parser) {
2736    this.parser = parser;
2737    this.name = EXTENSIONS.KHR_MATERIALS_ANISOTROPY;
2738  }
2739  getMaterialType(materialIndex) {
2740    const parser = this.parser;
2741    const materialDef = parser.json.materials[materialIndex];
2742    if (!materialDef.extensions || !materialDef.extensions[this.name])
2743      return null;
2744    return MeshPhysicalMaterial;
2745  }
2746  extendMaterialParams(materialIndex, materialParams) {
2747    const parser = this.parser;
2748    const materialDef = parser.json.materials[materialIndex];
2749    if (!materialDef.extensions || !materialDef.extensions[this.name]) {
2750      return Promise.resolve();
2751    }
2752    const pending = [];
2753    const extension = materialDef.extensions[this.name];
2754    if (extension.anisotropyStrength !== void 0) {
2755      materialParams.anisotropy = extension.anisotropyStrength;
2756    }
2757    if (extension.anisotropyRotation !== void 0) {
2758      materialParams.anisotropyRotation = extension.anisotropyRotation;
2759    }
2760    if (extension.anisotropyTexture !== void 0) {
2761      pending.push(parser.assignTexture(materialParams, "anisotropyMap", extension.anisotropyTexture));
2762    }
2763    return Promise.all(pending);
2764  }
2765};
2766var GLTFTextureBasisUExtension = class {
2767  constructor(parser) {
2768    this.parser = parser;
2769    this.name = EXTENSIONS.KHR_TEXTURE_BASISU;
2770  }
2771  loadTexture(textureIndex) {
2772    const parser = this.parser;
2773    const json = parser.json;
2774    const textureDef = json.textures[textureIndex];
2775    if (!textureDef.extensions || !textureDef.extensions[this.name]) {
2776      return null;
2777    }
2778    const extension = textureDef.extensions[this.name];
2779    const loader = parser.options.ktx2Loader;
2780    if (!loader) {
2781      if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
2782        throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");
2783      } else {
2784        return null;
2785      }
2786    }
2787    return parser.loadTextureImage(textureIndex, extension.source, loader);
2788  }
2789};
2790var GLTFTextureWebPExtension = class {
2791  constructor(parser) {
2792    this.parser = parser;
2793    this.name = EXTENSIONS.EXT_TEXTURE_WEBP;
2794    this.isSupported = null;
2795  }
2796  loadTexture(textureIndex) {
2797    const name = this.name;
2798    const parser = this.parser;
2799    const json = parser.json;
2800    const textureDef = json.textures[textureIndex];
2801    if (!textureDef.extensions || !textureDef.extensions[name]) {
2802      return null;
2803    }
2804    const extension = textureDef.extensions[name];
2805    const source = json.images[extension.source];
2806    let loader = parser.textureLoader;
2807    if (source.uri) {
2808      const handler = parser.options.manager.getHandler(source.uri);
2809      if (handler !== null)
2810        loader = handler;
2811    }
2812    return this.detectSupport().then(function(isSupported) {
2813      if (isSupported)
2814        return parser.loadTextureImage(textureIndex, extension.source, loader);
2815      if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
2816        throw new Error("THREE.GLTFLoader: WebP required by asset but unsupported.");
2817      }
2818      return parser.loadTexture(textureIndex);
2819    });
2820  }
2821  detectSupport() {
2822    if (!this.isSupported) {
2823      this.isSupported = new Promise(function(resolve3) {
2824        const image = new Image();
2825        image.src = "data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA";
2826        image.onload = image.onerror = function() {
2827          resolve3(image.height === 1);
2828        };
2829      });
2830    }
2831    return this.isSupported;
2832  }
2833};
2834var GLTFTextureAVIFExtension = class {
2835  constructor(parser) {
2836    this.parser = parser;
2837    this.name = EXTENSIONS.EXT_TEXTURE_AVIF;
2838    this.isSupported = null;
2839  }
2840  loadTexture(textureIndex) {
2841    const name = this.name;
2842    const parser = this.parser;
2843    const json = parser.json;
2844    const textureDef = json.textures[textureIndex];
2845    if (!textureDef.extensions || !textureDef.extensions[name]) {
2846      return null;
2847    }
2848    const extension = textureDef.extensions[name];
2849    const source = json.images[extension.source];
2850    let loader = parser.textureLoader;
2851    if (source.uri) {
2852      const handler = parser.options.manager.getHandler(source.uri);
2853      if (handler !== null)
2854        loader = handler;
2855    }
2856    return this.detectSupport().then(function(isSupported) {
2857      if (isSupported)
2858        return parser.loadTextureImage(textureIndex, extension.source, loader);
2859      if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
2860        throw new Error("THREE.GLTFLoader: AVIF required by asset but unsupported.");
2861      }
2862      return parser.loadTexture(textureIndex);
2863    });
2864  }
2865  detectSupport() {
2866    if (!this.isSupported) {
2867      this.isSupported = new Promise(function(resolve3) {
2868        const image = new Image();
2869        image.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=";
2870        image.onload = image.onerror = function() {
2871          resolve3(image.height === 1);
2872        };
2873      });
2874    }
2875    return this.isSupported;
2876  }
2877};
2878var GLTFMeshoptCompression = class {
2879  constructor(parser) {
2880    this.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION;
2881    this.parser = parser;
2882  }
2883  loadBufferView(index) {
2884    const json = this.parser.json;
2885    const bufferView = json.bufferViews[index];
2886    if (bufferView.extensions && bufferView.extensions[this.name]) {
2887      const extensionDef = bufferView.extensions[this.name];
2888      const buffer = this.parser.getDependency("buffer", extensionDef.buffer);
2889      const decoder = this.parser.options.meshoptDecoder;
2890      if (!decoder || !decoder.supported) {
2891        if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
2892          throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");
2893        } else {
2894          return null;
2895        }
2896      }
2897      return buffer.then(function(res) {
2898        const byteOffset = extensionDef.byteOffset || 0;
2899        const byteLength = extensionDef.byteLength || 0;
2900        const count = extensionDef.count;
2901        const stride = extensionDef.byteStride;
2902        const source = new Uint8Array(res, byteOffset, byteLength);
2903        if (decoder.decodeGltfBufferAsync) {
2904          return decoder.decodeGltfBufferAsync(count, stride, source, extensionDef.mode, extensionDef.filter).then(function(res2) {
2905            return res2.buffer;
2906          });
2907        } else {
2908          return decoder.ready.then(function() {
2909            const result = new ArrayBuffer(count * stride);
2910            decoder.decodeGltfBuffer(
2911              new Uint8Array(result),
2912              count,
2913              stride,
2914              source,
2915              extensionDef.mode,
2916              extensionDef.filter
2917            );
2918            return result;
2919          });
2920        }
2921      });
2922    } else {
2923      return null;
2924    }
2925  }
2926};
2927var GLTFMeshGpuInstancing = class {
2928  constructor(parser) {
2929    this.name = EXTENSIONS.EXT_MESH_GPU_INSTANCING;
2930    this.parser = parser;
2931  }
2932  createNodeMesh(nodeIndex) {
2933    const json = this.parser.json;
2934    const nodeDef = json.nodes[nodeIndex];
2935    if (!nodeDef.extensions || !nodeDef.extensions[this.name] || nodeDef.mesh === void 0) {
2936      return null;
2937    }
2938    const meshDef = json.meshes[nodeDef.mesh];
2939    for (const primitive of meshDef.primitives) {
2940      if (primitive.mode !== WEBGL_CONSTANTS.TRIANGLES && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_STRIP && primitive.mode !== WEBGL_CONSTANTS.TRIANGLE_FAN && primitive.mode !== void 0) {
2941        return null;
2942      }
2943    }
2944    const extensionDef = nodeDef.extensions[this.name];
2945    const attributesDef = extensionDef.attributes;
2946    const pending = [];
2947    const attributes = {};
2948    for (const key in attributesDef) {
2949      pending.push(
2950        this.parser.getDependency("accessor", attributesDef[key]).then((accessor) => {
2951          attributes[key] = accessor;
2952          return attributes[key];
2953        })
2954      );
2955    }
2956    if (pending.length < 1) {
2957      return null;
2958    }
2959    pending.push(this.parser.createNodeMesh(nodeIndex));
2960    return Promise.all(pending).then((results) => {
2961      const nodeObject = results.pop();
2962      const meshes = nodeObject.isGroup ? nodeObject.children : [nodeObject];
2963      const count = results[0].count;
2964      const instancedMeshes = [];
2965      for (const mesh of meshes) {
2966        const m = new Matrix4();
2967        const p = new Vector3();
2968        const q = new Quaternion();
2969        const s = new Vector3(1, 1, 1);
2970        const instancedMesh = new InstancedMesh(mesh.geometry, mesh.material, count);
2971        for (let i = 0; i < count; i++) {
2972          if (attributes.TRANSLATION) {
2973            p.fromBufferAttribute(attributes.TRANSLATION, i);
2974          }
2975          if (attributes.ROTATION) {
2976            q.fromBufferAttribute(attributes.ROTATION, i);
2977          }
2978          if (attributes.SCALE) {
2979            s.fromBufferAttribute(attributes.SCALE, i);
2980          }
2981          instancedMesh.setMatrixAt(i, m.compose(p, q, s));
2982        }
2983        for (const attributeName in attributes) {
2984          if (attributeName === "_COLOR_0") {
2985            const attr = attributes[attributeName];
2986            instancedMesh.instanceColor = new InstancedBufferAttribute(attr.array, attr.itemSize, attr.normalized);
2987          } else if (attributeName !== "TRANSLATION" && attributeName !== "ROTATION" && attributeName !== "SCALE") {
2988            mesh.geometry.setAttribute(attributeName, attributes[attributeName]);
2989          }
2990        }
2991        Object3D.prototype.copy.call(instancedMesh, mesh);
2992        this.parser.assignFinalMaterial(instancedMesh);
2993        instancedMeshes.push(instancedMesh);
2994      }
2995      if (nodeObject.isGroup) {
2996        nodeObject.clear();
2997        nodeObject.add(...instancedMeshes);
2998        return nodeObject;
2999      }
3000      return instancedMeshes[0];
3001    });
3002  }
3003};
3004var BINARY_EXTENSION_HEADER_MAGIC = "glTF";
3005var BINARY_EXTENSION_HEADER_LENGTH = 12;
3006var BINARY_EXTENSION_CHUNK_TYPES = { JSON: 1313821514, BIN: 5130562 };
3007var GLTFBinaryExtension = class {
3008  constructor(data) {
3009    this.name = EXTENSIONS.KHR_BINARY_GLTF;
3010    this.content = null;
3011    this.body = null;
3012    const headerView = new DataView(data, 0, BINARY_EXTENSION_HEADER_LENGTH);
3013    this.header = {
3014      magic: decodeText(new Uint8Array(data.slice(0, 4))),
3015      version: headerView.getUint32(4, true),
3016      length: headerView.getUint32(8, true)
3017    };
3018    if (this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC) {
3019      throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");
3020    } else if (this.header.version < 2) {
3021      throw new Error("THREE.GLTFLoader: Legacy binary file detected.");
3022    }
3023    const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;
3024    const chunkView = new DataView(data, BINARY_EXTENSION_HEADER_LENGTH);
3025    let chunkIndex = 0;
3026    while (chunkIndex < chunkContentsLength) {
3027      const chunkLength = chunkView.getUint32(chunkIndex, true);
3028      chunkIndex += 4;
3029      const chunkType = chunkView.getUint32(chunkIndex, true);
3030      chunkIndex += 4;
3031      if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON) {
3032        const contentArray = new Uint8Array(data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength);
3033        this.content = decodeText(contentArray);
3034      } else if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN) {
3035        const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
3036        this.body = data.slice(byteOffset, byteOffset + chunkLength);
3037      }
3038      chunkIndex += chunkLength;
3039    }
3040    if (this.content === null) {
3041      throw new Error("THREE.GLTFLoader: JSON content not found.");
3042    }
3043  }
3044};
3045var GLTFDracoMeshCompressionExtension = class {
3046  constructor(json, dracoLoader) {
3047    if (!dracoLoader) {
3048      throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");
3049    }
3050    this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
3051    this.json = json;
3052    this.dracoLoader = dracoLoader;
3053    this.dracoLoader.preload();
3054  }
3055  decodePrimitive(primitive, parser) {
3056    const json = this.json;
3057    const dracoLoader = this.dracoLoader;
3058    const bufferViewIndex = primitive.extensions[this.name].bufferView;
3059    const gltfAttributeMap = primitive.extensions[this.name].attributes;
3060    const threeAttributeMap = {};
3061    const attributeNormalizedMap = {};
3062    const attributeTypeMap = {};
3063    for (const attributeName in gltfAttributeMap) {
3064      const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase();
3065      threeAttributeMap[threeAttributeName] = gltfAttributeMap[attributeName];
3066    }
3067    for (const attributeName in primitive.attributes) {
3068      const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase();
3069      if (gltfAttributeMap[attributeName] !== void 0) {
3070        const accessorDef = json.accessors[primitive.attributes[attributeName]];
3071        const componentType = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
3072        attributeTypeMap[threeAttributeName] = componentType.name;
3073        attributeNormalizedMap[threeAttributeName] = accessorDef.normalized === true;
3074      }
3075    }
3076    return parser.getDependency("bufferView", bufferViewIndex).then(function(bufferView) {
3077      return new Promise(function(resolve3, reject) {
3078        dracoLoader.decodeDracoFile(
3079          bufferView,
3080          function(geometry) {
3081            for (const attributeName in geometry.attributes) {
3082              const attribute = geometry.attributes[attributeName];
3083              const normalized = attributeNormalizedMap[attributeName];
3084              if (normalized !== void 0)
3085                attribute.normalized = normalized;
3086            }
3087            resolve3(geometry);
3088          },
3089          threeAttributeMap,
3090          attributeTypeMap,
3091          LinearSRGBColorSpace2,
3092          reject
3093        );
3094      });
3095    });
3096  }
3097};
3098var GLTFTextureTransformExtension = class {
3099  constructor() {
3100    this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;
3101  }
3102  extendTexture(texture, transform) {
3103    if ((transform.texCoord === void 0 || transform.texCoord === texture.channel) && transform.offset === void 0 && transform.rotation === void 0 && transform.scale === void 0) {
3104      return texture;
3105    }
3106    texture = texture.clone();
3107    if (transform.texCoord !== void 0) {
3108      texture.channel = transform.texCoord;
3109    }
3110    if (transform.offset !== void 0) {
3111      texture.offset.fromArray(transform.offset);
3112    }
3113    if (transform.rotation !== void 0) {
3114      texture.rotation = transform.rotation;
3115    }
3116    if (transform.scale !== void 0) {
3117      texture.repeat.fromArray(transform.scale);
3118    }
3119    texture.needsUpdate = true;
3120    return texture;
3121  }
3122};
3123var GLTFMeshQuantizationExtension = class {
3124  constructor() {
3125    this.name = EXTENSIONS.KHR_MESH_QUANTIZATION;
3126  }
3127};
3128var GLTFCubicSplineInterpolant = class extends Interpolant {
3129  constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
3130    super(parameterPositions, sampleValues, sampleSize, resultBuffer);
3131  }
3132  copySampleValue_(index) {
3133    const result = this.resultBuffer, values = this.sampleValues, valueSize = this.valueSize, offset = index * valueSize * 3 + valueSize;
3134    for (let i = 0; i !== valueSize; i++) {
3135      result[i] = values[offset + i];
3136    }
3137    return result;
3138  }
3139  interpolate_(i1, t0, t, t1) {
3140    const result = this.resultBuffer;
3141    const values = this.sampleValues;
3142    const stride = this.valueSize;
3143    const stride2 = stride * 2;
3144    const stride3 = stride * 3;
3145    const td = t1 - t0;
3146    const p = (t - t0) / td;
3147    const pp = p * p;
3148    const ppp = pp * p;
3149    const offset1 = i1 * stride3;
3150    const offset0 = offset1 - stride3;
3151    const s2 = -2 * ppp + 3 * pp;
3152    const s3 = ppp - pp;
3153    const s0 = 1 - s2;
3154    const s1 = s3 - pp + p;
3155    for (let i = 0; i !== stride; i++) {
3156      const p0 = values[offset0 + i + stride];
3157      const m0 = values[offset0 + i + stride2] * td;
3158      const p1 = values[offset1 + i + stride];
3159      const m1 = values[offset1 + i] * td;
3160      result[i] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
3161    }
3162    return result;
3163  }
3164};
3165var _q = /* @__PURE__ */ new Quaternion();
3166var GLTFCubicSplineQuaternionInterpolant = class extends GLTFCubicSplineInterpolant {
3167  interpolate_(i1, t0, t, t1) {
3168    const result = super.interpolate_(i1, t0, t, t1);
3169    _q.fromArray(result).normalize().toArray(result);
3170    return result;
3171  }
3172};
3173var WEBGL_CONSTANTS = {
3174  FLOAT: 5126,
3175  //FLOAT_MAT2: 35674,
3176  FLOAT_MAT3: 35675,
3177  FLOAT_MAT4: 35676,
3178  FLOAT_VEC2: 35664,
3179  FLOAT_VEC3: 35665,
3180  FLOAT_VEC4: 35666,
3181  LINEAR: 9729,
3182  REPEAT: 10497,
3183  SAMPLER_2D: 35678,
3184  POINTS: 0,
3185  LINES: 1,
3186  LINE_LOOP: 2,
3187  LINE_STRIP: 3,
3188  TRIANGLES: 4,
3189  TRIANGLE_STRIP: 5,
3190  TRIANGLE_FAN: 6,
3191  UNSIGNED_BYTE: 5121,
3192  UNSIGNED_SHORT: 5123
3193};
3194var WEBGL_COMPONENT_TYPES = {
3195  5120: Int8Array,
3196  5121: Uint8Array,
3197  5122: Int16Array,
3198  5123: Uint16Array,
3199  5125: Uint32Array,
3200  5126: Float32Array
3201};
3202var WEBGL_FILTERS = {
3203  9728: NearestFilter,
3204  9729: LinearFilter,
3205  9984: NearestMipmapNearestFilter,
3206  9985: LinearMipmapNearestFilter,
3207  9986: NearestMipmapLinearFilter,
3208  9987: LinearMipmapLinearFilter
3209};
3210var WEBGL_WRAPPINGS = {
3211  33071: ClampToEdgeWrapping,
3212  33648: MirroredRepeatWrapping,
3213  10497: RepeatWrapping
3214};
3215var WEBGL_TYPE_SIZES = {
3216  SCALAR: 1,
3217  VEC2: 2,
3218  VEC3: 3,
3219  VEC4: 4,
3220  MAT2: 4,
3221  MAT3: 9,
3222  MAT4: 16
3223};
3224var ATTRIBUTES = {
3225  POSITION: "position",
3226  NORMAL: "normal",
3227  TANGENT: "tangent",
3228  // uv => uv1, 4 uv channels
3229  // https://github.com/mrdoob/three.js/pull/25943
3230  // https://github.com/mrdoob/three.js/pull/25788
3231  ...version >= 152 ? {
3232    TEXCOORD_0: "uv",
3233    TEXCOORD_1: "uv1",
3234    TEXCOORD_2: "uv2",
3235    TEXCOORD_3: "uv3"
3236  } : {
3237    TEXCOORD_0: "uv",
3238    TEXCOORD_1: "uv2"
3239  },
3240  COLOR_0: "color",
3241  WEIGHTS_0: "skinWeight",
3242  JOINTS_0: "skinIndex"
3243};
3244var PATH_PROPERTIES = {
3245  scale: "scale",
3246  translation: "position",
3247  rotation: "quaternion",
3248  weights: "morphTargetInfluences"
3249};
3250var INTERPOLATION = {
3251  CUBICSPLINE: void 0,
3252  // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
3253  // keyframe track will be initialized with a default interpolation type, then modified.
3254  LINEAR: InterpolateLinear,
3255  STEP: InterpolateDiscrete
3256};
3257var ALPHA_MODES = {
3258  OPAQUE: "OPAQUE",
3259  MASK: "MASK",
3260  BLEND: "BLEND"
3261};
3262function createDefaultMaterial(cache) {
3263  if (cache["DefaultMaterial"] === void 0) {
3264    cache["DefaultMaterial"] = new MeshStandardMaterial({
3265      color: 16777215,
3266      emissive: 0,
3267      metalness: 1,
3268      roughness: 1,
3269      transparent: false,
3270      depthTest: true,
3271      side: FrontSide
3272    });
3273  }
3274  return cache["DefaultMaterial"];
3275}
3276function addUnknownExtensionsToUserData(knownExtensions, object, objectDef) {
3277  for (const name in objectDef.extensions) {
3278    if (knownExtensions[name] === void 0) {
3279      object.userData.gltfExtensions = object.userData.gltfExtensions || {};
3280      object.userData.gltfExtensions[name] = objectDef.extensions[name];
3281    }
3282  }
3283}
3284function assignExtrasToUserData(object, gltfDef) {
3285  if (gltfDef.extras !== void 0) {
3286    if (typeof gltfDef.extras === "object") {
3287      Object.assign(object.userData, gltfDef.extras);
3288    } else {
3289      console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, " + gltfDef.extras);
3290    }
3291  }
3292}
3293function addMorphTargets(geometry, targets, parser) {
3294  let hasMorphPosition = false;
3295  let hasMorphNormal = false;
3296  let hasMorphColor = false;
3297  for (let i = 0, il = targets.length; i < il; i++) {
3298    const target = targets[i];
3299    if (target.POSITION !== void 0)
3300      hasMorphPosition = true;
3301    if (target.NORMAL !== void 0)
3302      hasMorphNormal = true;
3303    if (target.COLOR_0 !== void 0)
3304      hasMorphColor = true;
3305    if (hasMorphPosition && hasMorphNormal && hasMorphColor)
3306      break;
3307  }
3308  if (!hasMorphPosition && !hasMorphNormal && !hasMorphColor)
3309    return Promise.resolve(geometry);
3310  const pendingPositionAccessors = [];
3311  const pendingNormalAccessors = [];
3312  const pendingColorAccessors = [];
3313  for (let i = 0, il = targets.length; i < il; i++) {
3314    const target = targets[i];
3315    if (hasMorphPosition) {
3316      const pendingAccessor = target.POSITION !== void 0 ? parser.getDependency("accessor", target.POSITION) : geometry.attributes.position;
3317      pendingPositionAccessors.push(pendingAccessor);
3318    }
3319    if (hasMorphNormal) {
3320      const pendingAccessor = target.NORMAL !== void 0 ? parser.getDependency("accessor", target.NORMAL) : geometry.attributes.normal;
3321      pendingNormalAccessors.push(pendingAccessor);
3322    }
3323    if (hasMorphColor) {
3324      const pendingAccessor = target.COLOR_0 !== void 0 ? parser.getDependency("accessor", target.COLOR_0) : geometry.attributes.color;
3325      pendingColorAccessors.push(pendingAccessor);
3326    }
3327  }
3328  return Promise.all([
3329    Promise.all(pendingPositionAccessors),
3330    Promise.all(pendingNormalAccessors),
3331    Promise.all(pendingColorAccessors)
3332  ]).then(function(accessors) {
3333    const morphPositions = accessors[0];
3334    const morphNormals = accessors[1];
3335    const morphColors = accessors[2];
3336    if (hasMorphPosition)
3337      geometry.morphAttributes.position = morphPositions;
3338    if (hasMorphNormal)
3339      geometry.morphAttributes.normal = morphNormals;
3340    if (hasMorphColor)
3341      geometry.morphAttributes.color = morphColors;
3342    geometry.morphTargetsRelative = true;
3343    return geometry;
3344  });
3345}
3346function updateMorphTargets(mesh, meshDef) {
3347  mesh.updateMorphTargets();
3348  if (meshDef.weights !== void 0) {
3349    for (let i = 0, il = meshDef.weights.length; i < il; i++) {
3350      mesh.morphTargetInfluences[i] = meshDef.weights[i];
3351    }
3352  }
3353  if (meshDef.extras && Array.isArray(meshDef.extras.targetNames)) {
3354    const targetNames = meshDef.extras.targetNames;
3355    if (mesh.morphTargetInfluences.length === targetNames.length) {
3356      mesh.morphTargetDictionary = {};
3357      for (let i = 0, il = targetNames.length; i < il; i++) {
3358        mesh.morphTargetDictionary[targetNames[i]] = i;
3359      }
3360    } else {
3361      console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.");
3362    }
3363  }
3364}
3365function createPrimitiveKey(primitiveDef) {
3366  let geometryKey;
3367  const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION];
3368  if (dracoExtension) {
3369    geometryKey = "draco:" + dracoExtension.bufferView + ":" + dracoExtension.indices + ":" + createAttributesKey(dracoExtension.attributes);
3370  } else {
3371    geometryKey = primitiveDef.indices + ":" + createAttributesKey(primitiveDef.attributes) + ":" + primitiveDef.mode;
3372  }
3373  if (primitiveDef.targets !== void 0) {
3374    for (let i = 0, il = primitiveDef.targets.length; i < il; i++) {
3375      geometryKey += ":" + createAttributesKey(primitiveDef.targets[i]);
3376    }
3377  }
3378  return geometryKey;
3379}
3380function createAttributesKey(attributes) {
3381  let attributesKey = "";
3382  const keys2 = Object.keys(attributes).sort();
3383  for (let i = 0, il = keys2.length; i < il; i++) {
3384    attributesKey += keys2[i] + ":" + attributes[keys2[i]] + ";";
3385  }
3386  return attributesKey;
3387}
3388function getNormalizedComponentScale(constructor) {
3389  switch (constructor) {
3390    case Int8Array:
3391      return 1 / 127;
3392    case Uint8Array:
3393      return 1 / 255;
3394    case Int16Array:
3395      return 1 / 32767;
3396    case Uint16Array:
3397      return 1 / 65535;
3398    default:
3399      throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.");
3400  }
3401}
3402function getImageURIMimeType(uri) {
3403  if (uri.search(/\.jpe?g($|\?)/i) > 0 || uri.search(/^data\:image\/jpeg/) === 0)
3404    return "image/jpeg";
3405  if (uri.search(/\.webp($|\?)/i) > 0 || uri.search(/^data\:image\/webp/) === 0)
3406    return "image/webp";
3407  return "image/png";
3408}
3409var _identityMatrix = /* @__PURE__ */ new Matrix4();
3410var GLTFParser = class {
3411  constructor(json = {}, options = {}) {
3412    this.json = json;
3413    this.extensions = {};
3414    this.plugins = {};
3415    this.options = options;
3416    this.cache = new GLTFRegistry();
3417    this.associations = /* @__PURE__ */ new Map();
3418    this.primitiveCache = {};
3419    this.nodeCache = {};
3420    this.meshCache = { refs: {}, uses: {} };
3421    this.cameraCache = { refs: {}, uses: {} };
3422    this.lightCache = { refs: {}, uses: {} };
3423    this.sourceCache = {};
3424    this.textureCache = {};
3425    this.nodeNamesUsed = {};
3426    let isSafari = false;
3427    let isFirefox = false;
3428    let firefoxVersion = -1;
3429    if (typeof navigator !== "undefined" && typeof navigator.userAgent !== "undefined") {
3430      isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) === true;
3431      isFirefox = navigator.userAgent.indexOf("Firefox") > -1;
3432      firefoxVersion = isFirefox ? navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1] : -1;
3433    }
3434    if (typeof createImageBitmap === "undefined" || isSafari || isFirefox && firefoxVersion < 98) {
3435      this.textureLoader = new TextureLoader(this.options.manager);
3436    } else {
3437      this.textureLoader = new ImageBitmapLoader(this.options.manager);
3438    }
3439    this.textureLoader.setCrossOrigin(this.options.crossOrigin);
3440    this.textureLoader.setRequestHeader(this.options.requestHeader);
3441    this.fileLoader = new FileLoader(this.options.manager);
3442    this.fileLoader.setResponseType("arraybuffer");
3443    if (this.options.crossOrigin === "use-credentials") {
3444      this.fileLoader.setWithCredentials(true);
3445    }
3446  }
3447  setExtensions(extensions) {
3448    this.extensions = extensions;
3449  }
3450  setPlugins(plugins) {
3451    this.plugins = plugins;
3452  }
3453  parse(onLoad, onError) {
3454    const parser = this;
3455    const json = this.json;
3456    const extensions = this.extensions;
3457    this.cache.removeAll();
3458    this.nodeCache = {};
3459    this._invokeAll(function(ext) {
3460      return ext._markDefs && ext._markDefs();
3461    });
3462    Promise.all(
3463      this._invokeAll(function(ext) {
3464        return ext.beforeRoot && ext.beforeRoot();
3465      })
3466    ).then(function() {
3467      return Promise.all([
3468        parser.getDependencies("scene"),
3469        parser.getDependencies("animation"),
3470        parser.getDependencies("camera")
3471      ]);
3472    }).then(function(dependencies) {
3473      const result = {
3474        scene: dependencies[0][json.scene || 0],
3475        scenes: dependencies[0],
3476        animations: dependencies[1],
3477        cameras: dependencies[2],
3478        asset: json.asset,
3479        parser,
3480        userData: {}
3481      };
3482      addUnknownExtensionsToUserData(extensions, result, json);
3483      assignExtrasToUserData(result, json);
3484      return Promise.all(
3485        parser._invokeAll(function(ext) {
3486          return ext.afterRoot && ext.afterRoot(result);
3487        })
3488      ).then(function() {
3489        for (const scene of result.scenes) {
3490          scene.updateMatrixWorld();
3491        }
3492        onLoad(result);
3493      });
3494    }).catch(onError);
3495  }
3496  /**
3497   * Marks the special nodes/meshes in json for efficient parse.
3498   */
3499  _markDefs() {
3500    const nodeDefs = this.json.nodes || [];
3501    const skinDefs = this.json.skins || [];
3502    const meshDefs = this.json.meshes || [];
3503    for (let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex++) {
3504      const joints = skinDefs[skinIndex].joints;
3505      for (let i = 0, il = joints.length; i < il; i++) {
3506        nodeDefs[joints[i]].isBone = true;
3507      }
3508    }
3509    for (let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++) {
3510      const nodeDef = nodeDefs[nodeIndex];
3511      if (nodeDef.mesh !== void 0) {
3512        this._addNodeRef(this.meshCache, nodeDef.mesh);
3513        if (nodeDef.skin !== void 0) {
3514          meshDefs[nodeDef.mesh].isSkinnedMesh = true;
3515        }
3516      }
3517      if (nodeDef.camera !== void 0) {
3518        this._addNodeRef(this.cameraCache, nodeDef.camera);
3519      }
3520    }
3521  }
3522  /**
3523   * Counts references to shared node / Object3D resources. These resources
3524   * can be reused, or "instantiated", at multiple nodes in the scene
3525   * hierarchy. Mesh, Camera, and Light instances are instantiated and must
3526   * be marked. Non-scenegraph resources (like Materials, Geometries, and
3527   * Textures) can be reused directly and are not marked here.
3528   *
3529   * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
3530   */
3531  _addNodeRef(cache, index) {
3532    if (index === void 0)
3533      return;
3534    if (cache.refs[index] === void 0) {
3535      cache.refs[index] = cache.uses[index] = 0;
3536    }
3537    cache.refs[index]++;
3538  }
3539  /** Returns a reference to a shared resource, cloning it if necessary. */
3540  _getNodeRef(cache, index, object) {
3541    if (cache.refs[index] <= 1)
3542      return object;
3543    const ref = object.clone();
3544    const updateMappings = (original, clone) => {
3545      const mappings = this.associations.get(original);
3546      if (mappings != null) {
3547        this.associations.set(clone, mappings);
3548      }
3549      for (const [i, child] of original.children.entries()) {
3550        updateMappings(child, clone.children[i]);
3551      }
3552    };
3553    updateMappings(object, ref);
3554    ref.name += "_instance_" + cache.uses[index]++;
3555    return ref;
3556  }
3557  _invokeOne(func) {
3558    const extensions = Object.values(this.plugins);
3559    extensions.push(this);
3560    for (let i = 0; i < extensions.length; i++) {
3561      const result = func(extensions[i]);
3562      if (result)
3563        return result;
3564    }
3565    return null;
3566  }
3567  _invokeAll(func) {
3568    const extensions = Object.values(this.plugins);
3569    extensions.unshift(this);
3570    const pending = [];
3571    for (let i = 0; i < extensions.length; i++) {
3572      const result = func(extensions[i]);
3573      if (result)
3574        pending.push(result);
3575    }
3576    return pending;
3577  }
3578  /**
3579   * Requests the specified dependency asynchronously, with caching.
3580   * @param {string} type
3581   * @param {number} index
3582   * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
3583   */
3584  getDependency(type, index) {
3585    const cacheKey = type + ":" + index;
3586    let dependency = this.cache.get(cacheKey);
3587    if (!dependency) {
3588      switch (type) {
3589        case "scene":
3590          dependency = this.loadScene(index);
3591          break;
3592        case "node":
3593          dependency = this._invokeOne(function(ext) {
3594            return ext.loadNode && ext.loadNode(index);
3595          });
3596          break;
3597        case "mesh":
3598          dependency = this._invokeOne(function(ext) {
3599            return ext.loadMesh && ext.loadMesh(index);
3600          });
3601          break;
3602        case "accessor":
3603          dependency = this.loadAccessor(index);
3604          break;
3605        case "bufferView":
3606          dependency = this._invokeOne(function(ext) {
3607            return ext.loadBufferView && ext.loadBufferView(index);
3608          });
3609          break;
3610        case "buffer":
3611          dependency = this.loadBuffer(index);
3612          break;
3613        case "material":
3614          dependency = this._invokeOne(function(ext) {
3615            return ext.loadMaterial && ext.loadMaterial(index);
3616          });
3617          break;
3618        case "texture":
3619          dependency = this._invokeOne(function(ext) {
3620            return ext.loadTexture && ext.loadTexture(index);
3621          });
3622          break;
3623        case "skin":
3624          dependency = this.loadSkin(index);
3625          break;
3626        case "animation":
3627          dependency = this._invokeOne(function(ext) {
3628            return ext.loadAnimation && ext.loadAnimation(index);
3629          });
3630          break;
3631        case "camera":
3632          dependency = this.loadCamera(index);
3633          break;
3634        default:
3635          dependency = this._invokeOne(function(ext) {
3636            return ext != this && ext.getDependency && ext.getDependency(type, index);
3637          });
3638          if (!dependency) {
3639            throw new Error("Unknown type: " + type);
3640          }
3641          break;
3642      }
3643      this.cache.add(cacheKey, dependency);
3644    }
3645    return dependency;
3646  }
3647  /**
3648   * Requests all dependencies of the specified type asynchronously, with caching.
3649   * @param {string} type
3650   * @return {Promise<Array<Object>>}
3651   */
3652  getDependencies(type) {
3653    let dependencies = this.cache.get(type);
3654    if (!dependencies) {
3655      const parser = this;
3656      const defs = this.json[type + (type === "mesh" ? "es" : "s")] || [];
3657      dependencies = Promise.all(
3658        defs.map(function(def, index) {
3659          return parser.getDependency(type, index);
3660        })
3661      );
3662      this.cache.add(type, dependencies);
3663    }
3664    return dependencies;
3665  }
3666  /**
3667   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
3668   * @param {number} bufferIndex
3669   * @return {Promise<ArrayBuffer>}
3670   */
3671  loadBuffer(bufferIndex) {
3672    const bufferDef = this.json.buffers[bufferIndex];
3673    const loader = this.fileLoader;
3674    if (bufferDef.type && bufferDef.type !== "arraybuffer") {
3675      throw new Error("THREE.GLTFLoader: " + bufferDef.type + " buffer type is not supported.");
3676    }
3677    if (bufferDef.uri === void 0 && bufferIndex === 0) {
3678      return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body);
3679    }
3680    const options = this.options;
3681    return new Promise(function(resolve3, reject) {
3682      loader.load(LoaderUtils.resolveURL(bufferDef.uri, options.path), resolve3, void 0, function() {
3683        reject(new Error('THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".'));
3684      });
3685    });
3686  }
3687  /**
3688   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
3689   * @param {number} bufferViewIndex
3690   * @return {Promise<ArrayBuffer>}
3691   */
3692  loadBufferView(bufferViewIndex) {
3693    const bufferViewDef = this.json.bufferViews[bufferViewIndex];
3694    return this.getDependency("buffer", bufferViewDef.buffer).then(function(buffer) {
3695      const byteLength = bufferViewDef.byteLength || 0;
3696      const byteOffset = bufferViewDef.byteOffset || 0;
3697      return buffer.slice(byteOffset, byteOffset + byteLength);
3698    });
3699  }
3700  /**
3701   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
3702   * @param {number} accessorIndex
3703   * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
3704   */
3705  loadAccessor(accessorIndex) {
3706    const parser = this;
3707    const json = this.json;
3708    const accessorDef = this.json.accessors[accessorIndex];
3709    if (accessorDef.bufferView === void 0 && accessorDef.sparse === void 0) {
3710      const itemSize = WEBGL_TYPE_SIZES[accessorDef.type];
3711      const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
3712      const normalized = accessorDef.normalized === true;
3713      const array = new TypedArray(accessorDef.count * itemSize);
3714      return Promise.resolve(new BufferAttribute(array, itemSize, normalized));
3715    }
3716    const pendingBufferViews = [];
3717    if (accessorDef.bufferView !== void 0) {
3718      pendingBufferViews.push(this.getDependency("bufferView", accessorDef.bufferView));
3719    } else {
3720      pendingBufferViews.push(null);
3721    }
3722    if (accessorDef.sparse !== void 0) {
3723      pendingBufferViews.push(this.getDependency("bufferView", accessorDef.sparse.indices.bufferView));
3724      pendingBufferViews.push(this.getDependency("bufferView", accessorDef.sparse.values.bufferView));
3725    }
3726    return Promise.all(pendingBufferViews).then(function(bufferViews) {
3727      const bufferView = bufferViews[0];
3728      const itemSize = WEBGL_TYPE_SIZES[accessorDef.type];
3729      const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType];
3730      const elementBytes = TypedArray.BYTES_PER_ELEMENT;
3731      const itemBytes = elementBytes * itemSize;
3732      const byteOffset = accessorDef.byteOffset || 0;
3733      const byteStride = accessorDef.bufferView !== void 0 ? json.bufferViews[accessorDef.bufferView].byteStride : void 0;
3734      const normalized = accessorDef.normalized === true;
3735      let array, bufferAttribute;
3736      if (byteStride && byteStride !== itemBytes) {
3737        const ibSlice = Math.floor(byteOffset / byteStride);
3738        const ibCacheKey = "InterleavedBuffer:" + accessorDef.bufferView + ":" + accessorDef.componentType + ":" + ibSlice + ":" + accessorDef.count;
3739        let ib = parser.cache.get(ibCacheKey);
3740        if (!ib) {
3741          array = new TypedArray(bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes);
3742          ib = new InterleavedBuffer(array, byteStride / elementBytes);
3743          parser.cache.add(ibCacheKey, ib);
3744        }
3745        bufferAttribute = new InterleavedBufferAttribute(
3746          ib,
3747          itemSize,
3748          byteOffset % byteStride / elementBytes,
3749          normalized
3750        );
3751      } else {
3752        if (bufferView === null) {
3753          array = new TypedArray(accessorDef.count * itemSize);
3754        } else {
3755          array = new TypedArray(bufferView, byteOffset, accessorDef.count * itemSize);
3756        }
3757        bufferAttribute = new BufferAttribute(array, itemSize, normalized);
3758      }
3759      if (accessorDef.sparse !== void 0) {
3760        const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;
3761        const TypedArrayIndices = WEBGL_COMPONENT_TYPES[accessorDef.sparse.indices.componentType];
3762        const byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;
3763        const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;
3764        const sparseIndices = new TypedArrayIndices(
3765          bufferViews[1],
3766          byteOffsetIndices,
3767          accessorDef.sparse.count * itemSizeIndices
3768        );
3769        const sparseValues = new TypedArray(bufferViews[2], byteOffsetValues, accessorDef.sparse.count * itemSize);
3770        if (bufferView !== null) {
3771          bufferAttribute = new BufferAttribute(
3772            bufferAttribute.array.slice(),
3773            bufferAttribute.itemSize,
3774            bufferAttribute.normalized
3775          );
3776        }
3777        for (let i = 0, il = sparseIndices.length; i < il; i++) {
3778          const index = sparseIndices[i];
3779          bufferAttribute.setX(index, sparseValues[i * itemSize]);
3780          if (itemSize >= 2)
3781            bufferAttribute.setY(index, sparseValues[i * itemSize + 1]);
3782          if (itemSize >= 3)
3783            bufferAttribute.setZ(index, sparseValues[i * itemSize + 2]);
3784          if (itemSize >= 4)
3785            bufferAttribute.setW(index, sparseValues[i * itemSize + 3]);
3786          if (itemSize >= 5)
3787            throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.");
3788        }
3789      }
3790      return bufferAttribute;
3791    });
3792  }
3793  /**
3794   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
3795   * @param {number} textureIndex
3796   * @return {Promise<THREE.Texture|null>}
3797   */
3798  loadTexture(textureIndex) {
3799    const json = this.json;
3800    const options = this.options;
3801    const textureDef = json.textures[textureIndex];
3802    const sourceIndex = textureDef.source;
3803    const sourceDef = json.images[sourceIndex];
3804    let loader = this.textureLoader;
3805    if (sourceDef.uri) {
3806      const handler = options.manager.getHandler(sourceDef.uri);
3807      if (handler !== null)
3808        loader = handler;
3809    }
3810    return this.loadTextureImage(textureIndex, sourceIndex, loader);
3811  }
3812  loadTextureImage(textureIndex, sourceIndex, loader) {
3813    const parser = this;
3814    const json = this.json;
3815    const textureDef = json.textures[textureIndex];
3816    const sourceDef = json.images[sourceIndex];
3817    const cacheKey = (sourceDef.uri || sourceDef.bufferView) + ":" + textureDef.sampler;
3818    if (this.textureCache[cacheKey]) {
3819      return this.textureCache[cacheKey];
3820    }
3821    const promise = this.loadImageSource(sourceIndex, loader).then(function(texture) {
3822      texture.flipY = false;
3823      texture.name = textureDef.name || sourceDef.name || "";
3824      if (texture.name === "" && typeof sourceDef.uri === "string" && sourceDef.uri.startsWith("data:image/") === false) {
3825        texture.name = sourceDef.uri;
3826      }
3827      const samplers = json.samplers || {};
3828      const sampler = samplers[textureDef.sampler] || {};
3829      texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || LinearFilter;
3830      texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || LinearMipmapLinearFilter;
3831      texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || RepeatWrapping;
3832      texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || RepeatWrapping;
3833      parser.associations.set(texture, { textures: textureIndex });
3834      return texture;
3835    }).catch(function() {
3836      return null;
3837    });
3838    this.textureCache[cacheKey] = promise;
3839    return promise;
3840  }
3841  loadImageSource(sourceIndex, loader) {
3842    const parser = this;
3843    const json = this.json;
3844    const options = this.options;
3845    if (this.sourceCache[sourceIndex] !== void 0) {
3846      return this.sourceCache[sourceIndex].then((texture) => texture.clone());
3847    }
3848    const sourceDef = json.images[sourceIndex];
3849    const URL2 = self.URL || self.webkitURL;
3850    let sourceURI = sourceDef.uri || "";
3851    let isObjectURL = false;
3852    if (sourceDef.bufferView !== void 0) {
3853      sourceURI = parser.getDependency("bufferView", sourceDef.bufferView).then(function(bufferView) {
3854        isObjectURL = true;
3855        const blob = new Blob([bufferView], { type: sourceDef.mimeType });
3856        sourceURI = URL2.createObjectURL(blob);
3857        return sourceURI;
3858      });
3859    } else if (sourceDef.uri === void 0) {
3860      throw new Error("THREE.GLTFLoader: Image " + sourceIndex + " is missing URI and bufferView");
3861    }
3862    const promise = Promise.resolve(sourceURI).then(function(sourceURI2) {
3863      return new Promise(function(resolve3, reject) {
3864        let onLoad = resolve3;
3865        if (loader.isImageBitmapLoader === true) {
3866          onLoad = function(imageBitmap) {
3867            const texture = new Texture(imageBitmap);
3868            texture.needsUpdate = true;
3869            resolve3(texture);
3870          };
3871        }
3872        loader.load(LoaderUtils.resolveURL(sourceURI2, options.path), onLoad, void 0, reject);
3873      });
3874    }).then(function(texture) {
3875      if (isObjectURL === true) {
3876        URL2.revokeObjectURL(sourceURI);
3877      }
3878      assignExtrasToUserData(texture, sourceDef);
3879      texture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType(sourceDef.uri);
3880      return texture;
3881    }).catch(function(error) {
3882      console.error("THREE.GLTFLoader: Couldn't load texture", sourceURI);
3883      throw error;
3884    });
3885    this.sourceCache[sourceIndex] = promise;
3886    return promise;
3887  }
3888  /**
3889   * Asynchronously assigns a texture to the given material parameters.
3890   * @param {Object} materialParams
3891   * @param {string} mapName
3892   * @param {Object} mapDef
3893   * @return {Promise<Texture>}
3894   */
3895  assignTexture(materialParams, mapName, mapDef, colorSpace) {
3896    const parser = this;
3897    return this.getDependency("texture", mapDef.index).then(function(texture) {
3898      if (!texture)
3899        return null;
3900      if (mapDef.texCoord !== void 0 && mapDef.texCoord > 0) {
3901        texture = texture.clone();
3902        texture.channel = mapDef.texCoord;
3903      }
3904      if (parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]) {
3905        const transform = mapDef.extensions !== void 0 ? mapDef.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM] : void 0;
3906        if (transform) {
3907          const gltfReference = parser.associations.get(texture);
3908          texture = parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM].extendTexture(texture, transform);
3909          parser.associations.set(texture, gltfReference);
3910        }
3911      }
3912      if (colorSpace !== void 0) {
3913        if (typeof colorSpace === "number")
3914          colorSpace = colorSpace === sRGBEncoding ? SRGBColorSpace2 : LinearSRGBColorSpace2;
3915        if ("colorSpace" in texture)
3916          texture.colorSpace = colorSpace;
3917        else
3918          texture.encoding = colorSpace === SRGBColorSpace2 ? sRGBEncoding : LinearEncoding;
3919      }
3920      materialParams[mapName] = texture;
3921      return texture;
3922    });
3923  }
3924  /**
3925   * Assigns final material to a Mesh, Line, or Points instance. The instance
3926   * already has a material (generated from the glTF material options alone)
3927   * but reuse of the same glTF material may require multiple threejs materials
3928   * to accommodate different primitive types, defines, etc. New materials will
3929   * be created if necessary, and reused from a cache.
3930   * @param  {Object3D} mesh Mesh, Line, or Points instance.
3931   */
3932  assignFinalMaterial(mesh) {
3933    const geometry = mesh.geometry;
3934    let material = mesh.material;
3935    const useDerivativeTangents = geometry.attributes.tangent === void 0;
3936    const useVertexColors = geometry.attributes.color !== void 0;
3937    const useFlatShading = geometry.attributes.normal === void 0;
3938    if (mesh.isPoints) {
3939      const cacheKey = "PointsMaterial:" + material.uuid;
3940      let pointsMaterial = this.cache.get(cacheKey);
3941      if (!pointsMaterial) {
3942        pointsMaterial = new PointsMaterial();
3943        Material.prototype.copy.call(pointsMaterial, material);
3944        pointsMaterial.color.copy(material.color);
3945        pointsMaterial.map = material.map;
3946        pointsMaterial.sizeAttenuation = false;
3947        this.cache.add(cacheKey, pointsMaterial);
3948      }
3949      material = pointsMaterial;
3950    } else if (mesh.isLine) {
3951      const cacheKey = "LineBasicMaterial:" + material.uuid;
3952      let lineMaterial = this.cache.get(cacheKey);
3953      if (!lineMaterial) {
3954        lineMaterial = new LineBasicMaterial();
3955        Material.prototype.copy.call(lineMaterial, material);
3956        lineMaterial.color.copy(material.color);
3957        lineMaterial.map = material.map;
3958        this.cache.add(cacheKey, lineMaterial);
3959      }
3960      material = lineMaterial;
3961    }
3962    if (useDerivativeTangents || useVertexColors || useFlatShading) {
3963      let cacheKey = "ClonedMaterial:" + material.uuid + ":";
3964      if (useDerivativeTangents)
3965        cacheKey += "derivative-tangents:";
3966      if (useVertexColors)
3967        cacheKey += "vertex-colors:";
3968      if (useFlatShading)
3969        cacheKey += "flat-shading:";
3970      let cachedMaterial = this.cache.get(cacheKey);
3971      if (!cachedMaterial) {
3972        cachedMaterial = material.clone();
3973        if (useVertexColors)
3974          cachedMaterial.vertexColors = true;
3975        if (useFlatShading)
3976          cachedMaterial.flatShading = true;
3977        if (useDerivativeTangents) {
3978          if (cachedMaterial.normalScale)
3979            cachedMaterial.normalScale.y *= -1;
3980          if (cachedMaterial.clearcoatNormalScale)
3981            cachedMaterial.clearcoatNormalScale.y *= -1;
3982        }
3983        this.cache.add(cacheKey, cachedMaterial);
3984        this.associations.set(cachedMaterial, this.associations.get(material));
3985      }
3986      material = cachedMaterial;
3987    }
3988    mesh.material = material;
3989  }
3990  getMaterialType() {
3991    return MeshStandardMaterial;
3992  }
3993  /**
3994   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
3995   * @param {number} materialIndex
3996   * @return {Promise<Material>}
3997   */
3998  loadMaterial(materialIndex) {
3999    const parser = this;
4000    const json = this.json;
4001    const extensions = this.extensions;
4002    const materialDef = json.materials[materialIndex];
4003    let materialType;
4004    const materialParams = {};
4005    const materialExtensions = materialDef.extensions || {};
4006    const pending = [];
4007    if (materialExtensions[EXTENSIONS.KHR_MATERIALS_UNLIT]) {
4008      const kmuExtension = extensions[EXTENSIONS.KHR_MATERIALS_UNLIT];
4009      materialType = kmuExtension.getMaterialType();
4010      pending.push(kmuExtension.extendParams(materialParams, materialDef, parser));
4011    } else {
4012      const metallicRoughness = materialDef.pbrMetallicRoughness || {};
4013      materialParams.color = new Color(1, 1, 1);
4014      materialParams.opacity = 1;
4015      if (Array.isArray(metallicRoughness.baseColorFactor)) {
4016        const array = metallicRoughness.baseColorFactor;
4017        materialParams.color.setRGB(array[0], array[1], array[2], LinearSRGBColorSpace2);
4018        materialParams.opacity = array[3];
4019      }
4020      if (metallicRoughness.baseColorTexture !== void 0) {
4021        pending.push(parser.assignTexture(materialParams, "map", metallicRoughness.baseColorTexture, SRGBColorSpace2));
4022      }
4023      materialParams.metalness = metallicRoughness.metallicFactor !== void 0 ? metallicRoughness.metallicFactor : 1;
4024      materialParams.roughness = metallicRoughness.roughnessFactor !== void 0 ? metallicRoughness.roughnessFactor : 1;
4025      if (metallicRoughness.metallicRoughnessTexture !== void 0) {
4026        pending.push(parser.assignTexture(materialParams, "metalnessMap", metallicRoughness.metallicRoughnessTexture));
4027        pending.push(parser.assignTexture(materialParams, "roughnessMap", metallicRoughness.metallicRoughnessTexture));
4028      }
4029      materialType = this._invokeOne(function(ext) {
4030        return ext.getMaterialType && ext.getMaterialType(materialIndex);
4031      });
4032      pending.push(
4033        Promise.all(
4034          this._invokeAll(function(ext) {
4035            return ext.extendMaterialParams && ext.extendMaterialParams(materialIndex, materialParams);
4036          })
4037        )
4038      );
4039    }
4040    if (materialDef.doubleSided === true) {
4041      materialParams.side = DoubleSide;
4042    }
4043    const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;
4044    if (alphaMode === ALPHA_MODES.BLEND) {
4045      materialParams.transparent = true;
4046      materialParams.depthWrite = false;
4047    } else {
4048      materialParams.transparent = false;
4049      if (alphaMode === ALPHA_MODES.MASK) {
4050        materialParams.alphaTest = materialDef.alphaCutoff !== void 0 ? materialDef.alphaCutoff : 0.5;
4051      }
4052    }
4053    if (materialDef.normalTexture !== void 0 && materialType !== MeshBasicMaterial) {
4054      pending.push(parser.assignTexture(materialParams, "normalMap", materialDef.normalTexture));
4055      materialParams.normalScale = new Vector2(1, 1);
4056      if (materialDef.normalTexture.scale !== void 0) {
4057        const scale = materialDef.normalTexture.scale;
4058        materialParams.normalScale.set(scale, scale);
4059      }
4060    }
4061    if (materialDef.occlusionTexture !== void 0 && materialType !== MeshBasicMaterial) {
4062      pending.push(parser.assignTexture(materialParams, "aoMap", materialDef.occlusionTexture));
4063      if (materialDef.occlusionTexture.strength !== void 0) {
4064        materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;
4065      }
4066    }
4067    if (materialDef.emissiveFactor !== void 0 && materialType !== MeshBasicMaterial) {
4068      const emissiveFactor = materialDef.emissiveFactor;
4069      materialParams.emissive = new Color().setRGB(
4070        emissiveFactor[0],
4071        emissiveFactor[1],
4072        emissiveFactor[2],
4073        LinearSRGBColorSpace2
4074      );
4075    }
4076    if (materialDef.emissiveTexture !== void 0 && materialType !== MeshBasicMaterial) {
4077      pending.push(parser.assignTexture(materialParams, "emissiveMap", materialDef.emissiveTexture, SRGBColorSpace2));
4078    }
4079    return Promise.all(pending).then(function() {
4080      const material = new materialType(materialParams);
4081      if (materialDef.name)
4082        material.name = materialDef.name;
4083      assignExtrasToUserData(material, materialDef);
4084      parser.associations.set(material, { materials: materialIndex });
4085      if (materialDef.extensions)
4086        addUnknownExtensionsToUserData(extensions, material, materialDef);
4087      return material;
4088    });
4089  }
4090  /** When Object3D instances are targeted by animation, they need unique names. */
4091  createUniqueName(originalName) {
4092    const sanitizedName = PropertyBinding.sanitizeNodeName(originalName || "");
4093    if (sanitizedName in this.nodeNamesUsed) {
4094      return sanitizedName + "_" + ++this.nodeNamesUsed[sanitizedName];
4095    } else {
4096      this.nodeNamesUsed[sanitizedName] = 0;
4097      return sanitizedName;
4098    }
4099  }
4100  /**
4101   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
4102   *
4103   * Creates BufferGeometries from primitives.
4104   *
4105   * @param {Array<GLTF.Primitive>} primitives
4106   * @return {Promise<Array<BufferGeometry>>}
4107   */
4108  loadGeometries(primitives) {
4109    const parser = this;
4110    const extensions = this.extensions;
4111    const cache = this.primitiveCache;
4112    function createDracoPrimitive(primitive) {
4113      return extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(primitive, parser).then(function(geometry) {
4114        return addPrimitiveAttributes(geometry, primitive, parser);
4115      });
4116    }
4117    const pending = [];
4118    for (let i = 0, il = primitives.length; i < il; i++) {
4119      const primitive = primitives[i];
4120      const cacheKey = createPrimitiveKey(primitive);
4121      const cached = cache[cacheKey];
4122      if (cached) {
4123        pending.push(cached.promise);
4124      } else {
4125        let geometryPromise;
4126        if (primitive.extensions && primitive.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]) {
4127          geometryPromise = createDracoPrimitive(primitive);
4128        } else {
4129          geometryPromise = addPrimitiveAttributes(new BufferGeometry(), primitive, parser);
4130        }
4131        cache[cacheKey] = { primitive, promise: geometryPromise };
4132        pending.push(geometryPromise);
4133      }
4134    }
4135    return Promise.all(pending);
4136  }
4137  /**
4138   * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
4139   * @param {number} meshIndex
4140   * @return {Promise<Group|Mesh|SkinnedMesh>}
4141   */
4142  loadMesh(meshIndex) {
4143    const parser = this;
4144    const json = this.json;
4145    const extensions = this.extensions;
4146    const meshDef = json.meshes[meshIndex];
4147    const primitives = meshDef.primitives;
4148    const pending = [];
4149    for (let i = 0, il = primitives.length; i < il; i++) {
4150      const material = primitives[i].material === void 0 ? createDefaultMaterial(this.cache) : this.getDependency("material", primitives[i].material);
4151      pending.push(material);
4152    }
4153    pending.push(parser.loadGeometries(primitives));
4154    return Promise.all(pending).then(function(results) {
4155      const materials = results.slice(0, results.length - 1);
4156      const geometries = results[results.length - 1];
4157      const meshes = [];
4158      for (let i = 0, il = geometries.length; i < il; i++) {
4159        const geometry = geometries[i];
4160        const primitive = primitives[i];
4161        let mesh;
4162        const material = materials[i];
4163        if (primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || primitive.mode === void 0) {
4164          mesh = meshDef.isSkinnedMesh === true ? new SkinnedMesh(geometry, material) : new Mesh(geometry, material);
4165          if (mesh.isSkinnedMesh === true) {
4166            mesh.normalizeSkinWeights();
4167          }
4168          if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP) {
4169            mesh.geometry = toTrianglesDrawMode(mesh.geometry, TriangleStripDrawMode);
4170          } else if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN) {
4171            mesh.geometry = toTrianglesDrawMode(mesh.geometry, TriangleFanDrawMode);
4172          }
4173        } else if (primitive.mode === WEBGL_CONSTANTS.LINES) {
4174          mesh = new LineSegments(geometry, material);
4175        } else if (primitive.mode === WEBGL_CONSTANTS.LINE_STRIP) {
4176          mesh = new Line(geometry, material);
4177        } else if (primitive.mode === WEBGL_CONSTANTS.LINE_LOOP) {
4178          mesh = new LineLoop(geometry, material);
4179        } else if (primitive.mode === WEBGL_CONSTANTS.POINTS) {
4180          mesh = new Points(geometry, material);
4181        } else {
4182          throw new Error("THREE.GLTFLoader: Primitive mode unsupported: " + primitive.mode);
4183        }
4184        if (Object.keys(mesh.geometry.morphAttributes).length > 0) {
4185          updateMorphTargets(mesh, meshDef);
4186        }
4187        mesh.name = parser.createUniqueName(meshDef.name || "mesh_" + meshIndex);
4188        assignExtrasToUserData(mesh, meshDef);
4189        if (primitive.extensions)
4190          addUnknownExtensionsToUserData(extensions, mesh, primitive);
4191        parser.assignFinalMaterial(mesh);
4192        meshes.push(mesh);
4193      }
4194      for (let i = 0, il = meshes.length; i < il; i++) {
4195        parser.associations.set(meshes[i], {
4196          meshes: meshIndex,
4197          primitives: i
4198        });
4199      }
4200      if (meshes.length === 1) {
4201        if (meshDef.extensions)
4202          addUnknownExtensionsToUserData(extensions, meshes[0], meshDef);
4203        return meshes[0];
4204      }
4205      const group = new Group();
4206      if (meshDef.extensions)
4207        addUnknownExtensionsToUserData(extensions, group, meshDef);
4208      parser.associations.set(group, { meshes: meshIndex });
4209      for (let i = 0, il = meshes.length; i < il; i++) {
4210        group.add(meshes[i]);
4211      }
4212      return group;
4213    });
4214  }
4215  /**
4216   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
4217   * @param {number} cameraIndex
4218   * @return {Promise<THREE.Camera>}
4219   */
4220  loadCamera(cameraIndex) {
4221    let camera;
4222    const cameraDef = this.json.cameras[cameraIndex];
4223    const params = cameraDef[cameraDef.type];
4224    if (!params) {
4225      console.warn("THREE.GLTFLoader: Missing camera parameters.");
4226      return;
4227    }
4228    if (cameraDef.type === "perspective") {
4229      camera = new PerspectiveCamera(
4230        MathUtils.radToDeg(params.yfov),
4231        params.aspectRatio || 1,
4232        params.znear || 1,
4233        params.zfar || 2e6
4234      );
4235    } else if (cameraDef.type === "orthographic") {
4236      camera = new OrthographicCamera(-params.xmag, params.xmag, params.ymag, -params.ymag, params.znear, params.zfar);
4237    }
4238    if (cameraDef.name)
4239      camera.name = this.createUniqueName(cameraDef.name);
4240    assignExtrasToUserData(camera, cameraDef);
4241    return Promise.resolve(camera);
4242  }
4243  /**
4244   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
4245   * @param {number} skinIndex
4246   * @return {Promise<Skeleton>}
4247   */
4248  loadSkin(skinIndex) {
4249    const skinDef = this.json.skins[skinIndex];
4250    const pending = [];
4251    for (let i = 0, il = skinDef.joints.length; i < il; i++) {
4252      pending.push(this._loadNodeShallow(skinDef.joints[i]));
4253    }
4254    if (skinDef.inverseBindMatrices !== void 0) {
4255      pending.push(this.getDependency("accessor", skinDef.inverseBindMatrices));
4256    } else {
4257      pending.push(null);
4258    }
4259    return Promise.all(pending).then(function(results) {
4260      const inverseBindMatrices = results.pop();
4261      const jointNodes = results;
4262      const bones = [];
4263      const boneInverses = [];
4264      for (let i = 0, il = jointNodes.length; i < il; i++) {
4265        const jointNode = jointNodes[i];
4266        if (jointNode) {
4267          bones.push(jointNode);
4268          const mat = new Matrix4();
4269          if (inverseBindMatrices !== null) {
4270            mat.fromArray(inverseBindMatrices.array, i * 16);
4271          }
4272          boneInverses.push(mat);
4273        } else {
4274          console.warn('THREE.GLTFLoader: Joint "%s" could not be found.', skinDef.joints[i]);
4275        }
4276      }
4277      return new Skeleton(bones, boneInverses);
4278    });
4279  }
4280  /**
4281   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
4282   * @param {number} animationIndex
4283   * @return {Promise<AnimationClip>}
4284   */
4285  loadAnimation(animationIndex) {
4286    const json = this.json;
4287    const parser = this;
4288    const animationDef = json.animations[animationIndex];
4289    const animationName = animationDef.name ? animationDef.name : "animation_" + animationIndex;
4290    const pendingNodes = [];
4291    const pendingInputAccessors = [];
4292    const pendingOutputAccessors = [];
4293    const pendingSamplers = [];
4294    const pendingTargets = [];
4295    for (let i = 0, il = animationDef.channels.length; i < il; i++) {
4296      const channel = animationDef.channels[i];
4297      const sampler = animationDef.samplers[channel.sampler];
4298      const target = channel.target;
4299      const name = target.node;
4300      const input = animationDef.parameters !== void 0 ? animationDef.parameters[sampler.input] : sampler.input;
4301      const output = animationDef.parameters !== void 0 ? animationDef.parameters[sampler.output] : sampler.output;
4302      if (target.node === void 0)
4303        continue;
4304      pendingNodes.push(this.getDependency("node", name));
4305      pendingInputAccessors.push(this.getDependency("accessor", input));
4306      pendingOutputAccessors.push(this.getDependency("accessor", output));
4307      pendingSamplers.push(sampler);
4308      pendingTargets.push(target);
4309    }
4310    return Promise.all([
4311      Promise.all(pendingNodes),
4312      Promise.all(pendingInputAccessors),
4313      Promise.all(pendingOutputAccessors),
4314      Promise.all(pendingSamplers),
4315      Promise.all(pendingTargets)
4316    ]).then(function(dependencies) {
4317      const nodes = dependencies[0];
4318      const inputAccessors = dependencies[1];
4319      const outputAccessors = dependencies[2];
4320      const samplers = dependencies[3];
4321      const targets = dependencies[4];
4322      const tracks = [];
4323      for (let i = 0, il = nodes.length; i < il; i++) {
4324        const node = nodes[i];
4325        const inputAccessor = inputAccessors[i];
4326        const outputAccessor = outputAccessors[i];
4327        const sampler = samplers[i];
4328        const target = targets[i];
4329        if (node === void 0)
4330          continue;
4331        if (node.updateMatrix) {
4332          node.updateMatrix();
4333        }
4334        const createdTracks = parser._createAnimationTracks(node, inputAccessor, outputAccessor, sampler, target);
4335        if (createdTracks) {
4336          for (let k = 0; k < createdTracks.length; k++) {
4337            tracks.push(createdTracks[k]);
4338          }
4339        }
4340      }
4341      return new AnimationClip(animationName, void 0, tracks);
4342    });
4343  }
4344  createNodeMesh(nodeIndex) {
4345    const json = this.json;
4346    const parser = this;
4347    const nodeDef = json.nodes[nodeIndex];
4348    if (nodeDef.mesh === void 0)
4349      return null;
4350    return parser.getDependency("mesh", nodeDef.mesh).then(function(mesh) {
4351      const node = parser._getNodeRef(parser.meshCache, nodeDef.mesh, mesh);
4352      if (nodeDef.weights !== void 0) {
4353        node.traverse(function(o) {
4354          if (!o.isMesh)
4355            return;
4356          for (let i = 0, il = nodeDef.weights.length; i < il; i++) {
4357            o.morphTargetInfluences[i] = nodeDef.weights[i];
4358          }
4359        });
4360      }
4361      return node;
4362    });
4363  }
4364  /**
4365   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
4366   * @param {number} nodeIndex
4367   * @return {Promise<Object3D>}
4368   */
4369  loadNode(nodeIndex) {
4370    const json = this.json;
4371    const parser = this;
4372    const nodeDef = json.nodes[nodeIndex];
4373    const nodePending = parser._loadNodeShallow(nodeIndex);
4374    const childPending = [];
4375    const childrenDef = nodeDef.children || [];
4376    for (let i = 0, il = childrenDef.length; i < il; i++) {
4377      childPending.push(parser.getDependency("node", childrenDef[i]));
4378    }
4379    const skeletonPending = nodeDef.skin === void 0 ? Promise.resolve(null) : parser.getDependency("skin", nodeDef.skin);
4380    return Promise.all([nodePending, Promise.all(childPending), skeletonPending]).then(function(results) {
4381      const node = results[0];
4382      const children2 = results[1];
4383      const skeleton = results[2];
4384      if (skeleton !== null) {
4385        node.traverse(function(mesh) {
4386          if (!mesh.isSkinnedMesh)
4387            return;
4388          mesh.bind(skeleton, _identityMatrix);
4389        });
4390      }
4391      for (let i = 0, il = children2.length; i < il; i++) {
4392        node.add(children2[i]);
4393      }
4394      return node;
4395    });
4396  }
4397  // ._loadNodeShallow() parses a single node.
4398  // skin and child nodes are created and added in .loadNode() (no '_' prefix).
4399  _loadNodeShallow(nodeIndex) {
4400    const json = this.json;
4401    const extensions = this.extensions;
4402    const parser = this;
4403    if (this.nodeCache[nodeIndex] !== void 0) {
4404      return this.nodeCache[nodeIndex];
4405    }
4406    const nodeDef = json.nodes[nodeIndex];
4407    const nodeName = nodeDef.name ? parser.createUniqueName(nodeDef.name) : "";
4408    const pending = [];
4409    const meshPromise = parser._invokeOne(function(ext) {
4410      return ext.createNodeMesh && ext.createNodeMesh(nodeIndex);
4411    });
4412    if (meshPromise) {
4413      pending.push(meshPromise);
4414    }
4415    if (nodeDef.camera !== void 0) {
4416      pending.push(
4417        parser.getDependency("camera", nodeDef.camera).then(function(camera) {
4418          return parser._getNodeRef(parser.cameraCache, nodeDef.camera, camera);
4419        })
4420      );
4421    }
4422    parser._invokeAll(function(ext) {
4423      return ext.createNodeAttachment && ext.createNodeAttachment(nodeIndex);
4424    }).forEach(function(promise) {
4425      pending.push(promise);
4426    });
4427    this.nodeCache[nodeIndex] = Promise.all(pending).then(function(objects) {
4428      let node;
4429      if (nodeDef.isBone === true) {
4430        node = new Bone();
4431      } else if (objects.length > 1) {
4432        node = new Group();
4433      } else if (objects.length === 1) {
4434        node = objects[0];
4435      } else {
4436        node = new Object3D();
4437      }
4438      if (node !== objects[0]) {
4439        for (let i = 0, il = objects.length; i < il; i++) {
4440          node.add(objects[i]);
4441        }
4442      }
4443      if (nodeDef.name) {
4444        node.userData.name = nodeDef.name;
4445        node.name = nodeName;
4446      }
4447      assignExtrasToUserData(node, nodeDef);
4448      if (nodeDef.extensions)
4449        addUnknownExtensionsToUserData(extensions, node, nodeDef);
4450      if (nodeDef.matrix !== void 0) {
4451        const matrix = new Matrix4();
4452        matrix.fromArray(nodeDef.matrix);
4453        node.applyMatrix4(matrix);
4454      } else {
4455        if (nodeDef.translation !== void 0) {
4456          node.position.fromArray(nodeDef.translation);
4457        }
4458        if (nodeDef.rotation !== void 0) {
4459          node.quaternion.fromArray(nodeDef.rotation);
4460        }
4461        if (nodeDef.scale !== void 0) {
4462          node.scale.fromArray(nodeDef.scale);
4463        }
4464      }
4465      if (!parser.associations.has(node)) {
4466        parser.associations.set(node, {});
4467      }
4468      parser.associations.get(node).nodes = nodeIndex;
4469      return node;
4470    });
4471    return this.nodeCache[nodeIndex];
4472  }
4473  /**
4474   * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
4475   * @param {number} sceneIndex
4476   * @return {Promise<Group>}
4477   */
4478  loadScene(sceneIndex) {
4479    const extensions = this.extensions;
4480    const sceneDef = this.json.scenes[sceneIndex];
4481    const parser = this;
4482    const scene = new Group();
4483    if (sceneDef.name)
4484      scene.name = parser.createUniqueName(sceneDef.name);
4485    assignExtrasToUserData(scene, sceneDef);
4486    if (sceneDef.extensions)
4487      addUnknownExtensionsToUserData(extensions, scene, sceneDef);
4488    const nodeIds = sceneDef.nodes || [];
4489    const pending = [];
4490    for (let i = 0, il = nodeIds.length; i < il; i++) {
4491      pending.push(parser.getDependency("node", nodeIds[i]));
4492    }
4493    return Promise.all(pending).then(function(nodes) {
4494      for (let i = 0, il = nodes.length; i < il; i++) {
4495        scene.add(nodes[i]);
4496      }
4497      const reduceAssociations = (node) => {
4498        const reducedAssociations = /* @__PURE__ */ new Map();
4499        for (const [key, value] of parser.associations) {
4500          if (key instanceof Material || key instanceof Texture) {
4501            reducedAssociations.set(key, value);
4502          }
4503        }
4504        node.traverse((node2) => {
4505          const mappings = parser.associations.get(node2);
4506          if (mappings != null) {
4507            reducedAssociations.set(node2, mappings);
4508          }
4509        });
4510        return reducedAssociations;
4511      };
4512      parser.associations = reduceAssociations(scene);
4513      return scene;
4514    });
4515  }
4516  _createAnimationTracks(node, inputAccessor, outputAccessor, sampler, target) {
4517    const tracks = [];
4518    const targetName = node.name ? node.name : node.uuid;
4519    const targetNames = [];
4520    if (PATH_PROPERTIES[target.path] === PATH_PROPERTIES.weights) {
4521      node.traverse(function(object) {
4522        if (object.morphTargetInfluences) {
4523          targetNames.push(object.name ? object.name : object.uuid);
4524        }
4525      });
4526    } else {
4527      targetNames.push(targetName);
4528    }
4529    let TypedKeyframeTrack;
4530    switch (PATH_PROPERTIES[target.path]) {
4531      case PATH_PROPERTIES.weights:
4532        TypedKeyframeTrack = NumberKeyframeTrack;
4533        break;
4534      case PATH_PROPERTIES.rotation:
4535        TypedKeyframeTrack = QuaternionKeyframeTrack;
4536        break;
4537      case PATH_PROPERTIES.position:
4538      case PATH_PROPERTIES.scale:
4539        TypedKeyframeTrack = VectorKeyframeTrack;
4540        break;
4541      default:
4542        switch (outputAccessor.itemSize) {
4543          case 1:
4544            TypedKeyframeTrack = NumberKeyframeTrack;
4545            break;
4546          case 2:
4547          case 3:
4548          default:
4549            TypedKeyframeTrack = VectorKeyframeTrack;
4550            break;
4551        }
4552        break;
4553    }
4554    const interpolation = sampler.interpolation !== void 0 ? INTERPOLATION[sampler.interpolation] : InterpolateLinear;
4555    const outputArray = this._getArrayFromAccessor(outputAccessor);
4556    for (let j = 0, jl = targetNames.length; j < jl; j++) {
4557      const track = new TypedKeyframeTrack(
4558        targetNames[j] + "." + PATH_PROPERTIES[target.path],
4559        inputAccessor.array,
4560        outputArray,
4561        interpolation
4562      );
4563      if (sampler.interpolation === "CUBICSPLINE") {
4564        this._createCubicSplineTrackInterpolant(track);
4565      }
4566      tracks.push(track);
4567    }
4568    return tracks;
4569  }
4570  _getArrayFromAccessor(accessor) {
4571    let outputArray = accessor.array;
4572    if (accessor.normalized) {
4573      const scale = getNormalizedComponentScale(outputArray.constructor);
4574      const scaled = new Float32Array(outputArray.length);
4575      for (let j = 0, jl = outputArray.length; j < jl; j++) {
4576        scaled[j] = outputArray[j] * scale;
4577      }
4578      outputArray = scaled;
4579    }
4580    return outputArray;
4581  }
4582  _createCubicSplineTrackInterpolant(track) {
4583    track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline(result) {
4584      const interpolantType = this instanceof QuaternionKeyframeTrack ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant;
4585      return new interpolantType(this.times, this.values, this.getValueSize() / 3, result);
4586    };
4587    track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
4588  }
4589};
4590function computeBounds(geometry, primitiveDef, parser) {
4591  const attributes = primitiveDef.attributes;
4592  const box = new Box3();
4593  if (attributes.POSITION !== void 0) {
4594    const accessor = parser.json.accessors[attributes.POSITION];
4595    const min = accessor.min;
4596    const max = accessor.max;
4597    if (min !== void 0 && max !== void 0) {
4598      box.set(new Vector3(min[0], min[1], min[2]), new Vector3(max[0], max[1], max[2]));
4599      if (accessor.normalized) {
4600        const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);
4601        box.min.multiplyScalar(boxScale);
4602        box.max.multiplyScalar(boxScale);
4603      }
4604    } else {
4605      console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");
4606      return;
4607    }
4608  } else {
4609    return;
4610  }
4611  const targets = primitiveDef.targets;
4612  if (targets !== void 0) {
4613    const maxDisplacement = new Vector3();
4614    const vector = new Vector3();
4615    for (let i = 0, il = targets.length; i < il; i++) {
4616      const target = targets[i];
4617      if (target.POSITION !== void 0) {
4618        const accessor = parser.json.accessors[target.POSITION];
4619        const min = accessor.min;
4620        const max = accessor.max;
4621        if (min !== void 0 && max !== void 0) {
4622          vector.setX(Math.max(Math.abs(min[0]), Math.abs(max[0])));
4623          vector.setY(Math.max(Math.abs(min[1]), Math.abs(max[1])));
4624          vector.setZ(Math.max(Math.abs(min[2]), Math.abs(max[2])));
4625          if (accessor.normalized) {
4626            const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType]);
4627            vector.multiplyScalar(boxScale);
4628          }
4629          maxDisplacement.max(vector);
4630        } else {
4631          console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");
4632        }
4633      }
4634    }
4635    box.expandByVector(maxDisplacement);
4636  }
4637  geometry.boundingBox = box;
4638  const sphere = new Sphere();
4639  box.getCenter(sphere.center);
4640  sphere.radius = box.min.distanceTo(box.max) / 2;
4641  geometry.boundingSphere = sphere;
4642}
4643function addPrimitiveAttributes(geometry, primitiveDef, parser) {
4644  const attributes = primitiveDef.attributes;
4645  const pending = [];
4646  function assignAttributeAccessor(accessorIndex, attributeName) {
4647    return parser.getDependency("accessor", accessorIndex).then(function(accessor) {
4648      geometry.setAttribute(attributeName, accessor);
4649    });
4650  }
4651  for (const gltfAttributeName in attributes) {
4652    const threeAttributeName = ATTRIBUTES[gltfAttributeName] || gltfAttributeName.toLowerCase();
4653    if (threeAttributeName in geometry.attributes)
4654      continue;
4655    pending.push(assignAttributeAccessor(attributes[gltfAttributeName], threeAttributeName));
4656  }
4657  if (primitiveDef.indices !== void 0 && !geometry.index) {
4658    const accessor = parser.getDependency("accessor", primitiveDef.indices).then(function(accessor2) {
4659      geometry.setIndex(accessor2);
4660    });
4661    pending.push(accessor);
4662  }
4663  assignExtrasToUserData(geometry, primitiveDef);
4664  computeBounds(geometry, primitiveDef, parser);
4665  return Promise.all(pending).then(function() {
4666    return primitiveDef.targets !== void 0 ? addMorphTargets(geometry, primitiveDef.targets, parser) : geometry;
4667  });
4668}
4669
vendor: 11,962 bytes, lines 4670-5008
4670// node_modules/three-stdlib/loaders/DRACOLoader.js
4671var _taskCache = /* @__PURE__ */ new WeakMap();
4672var DRACOLoader = class extends Loader {
4673  constructor(manager) {
4674    super(manager);
4675    this.decoderPath = "";
4676    this.decoderConfig = {};
4677    this.decoderBinary = null;
4678    this.decoderPending = null;
4679    this.workerLimit = 4;
4680    this.workerPool = [];
4681    this.workerNextTaskID = 1;
4682    this.workerSourceURL = "";
4683    this.defaultAttributeIDs = {
4684      position: "POSITION",
4685      normal: "NORMAL",
4686      color: "COLOR",
4687      uv: "TEX_COORD"
4688    };
4689    this.defaultAttributeTypes = {
4690      position: "Float32Array",
4691      normal: "Float32Array",
4692      color: "Float32Array",
4693      uv: "Float32Array"
4694    };
4695  }
4696  setDecoderPath(path) {
4697    this.decoderPath = path;
4698    return this;
4699  }
4700  setDecoderConfig(config) {
4701    this.decoderConfig = config;
4702    return this;
4703  }
4704  setWorkerLimit(workerLimit) {
4705    this.workerLimit = workerLimit;
4706    return this;
4707  }
4708  load(url, onLoad, onProgress, onError) {
4709    const loader = new FileLoader(this.manager);
4710    loader.setPath(this.path);
4711    loader.setResponseType("arraybuffer");
4712    loader.setRequestHeader(this.requestHeader);
4713    loader.setWithCredentials(this.withCredentials);
4714    loader.load(
4715      url,
4716      (buffer) => {
4717        const taskConfig = {
4718          attributeIDs: this.defaultAttributeIDs,
4719          attributeTypes: this.defaultAttributeTypes,
4720          useUniqueIDs: false
4721        };
4722        this.decodeGeometry(buffer, taskConfig).then(onLoad).catch(onError);
4723      },
4724      onProgress,
4725      onError
4726    );
4727  }
4728  /** @deprecated Kept for backward-compatibility with previous DRACOLoader versions. */
4729  decodeDracoFile(buffer, callback, attributeIDs, attributeTypes) {
4730    const taskConfig = {
4731      attributeIDs: attributeIDs || this.defaultAttributeIDs,
4732      attributeTypes: attributeTypes || this.defaultAttributeTypes,
4733      useUniqueIDs: !!attributeIDs
4734    };
4735    this.decodeGeometry(buffer, taskConfig).then(callback);
4736  }
4737  decodeGeometry(buffer, taskConfig) {
4738    for (const attribute in taskConfig.attributeTypes) {
4739      const type = taskConfig.attributeTypes[attribute];
4740      if (type.BYTES_PER_ELEMENT !== void 0) {
4741        taskConfig.attributeTypes[attribute] = type.name;
4742      }
4743    }
4744    const taskKey = JSON.stringify(taskConfig);
4745    if (_taskCache.has(buffer)) {
4746      const cachedTask = _taskCache.get(buffer);
4747      if (cachedTask.key === taskKey) {
4748        return cachedTask.promise;
4749      } else if (buffer.byteLength === 0) {
4750        throw new Error(
4751          "THREE.DRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred."
4752        );
4753      }
4754    }
4755    let worker;
4756    const taskID = this.workerNextTaskID++;
4757    const taskCost = buffer.byteLength;
4758    const geometryPending = this._getWorker(taskID, taskCost).then((_worker) => {
4759      worker = _worker;
4760      return new Promise((resolve3, reject) => {
4761        worker._callbacks[taskID] = { resolve: resolve3, reject };
4762        worker.postMessage({ type: "decode", id: taskID, taskConfig, buffer }, [buffer]);
4763      });
4764    }).then((message) => this._createGeometry(message.geometry));
4765    geometryPending.catch(() => true).then(() => {
4766      if (worker && taskID) {
4767        this._releaseTask(worker, taskID);
4768      }
4769    });
4770    _taskCache.set(buffer, {
4771      key: taskKey,
4772      promise: geometryPending
4773    });
4774    return geometryPending;
4775  }
4776  _createGeometry(geometryData) {
4777    const geometry = new BufferGeometry();
4778    if (geometryData.index) {
4779      geometry.setIndex(new BufferAttribute(geometryData.index.array, 1));
4780    }
4781    for (let i = 0; i < geometryData.attributes.length; i++) {
4782      const attribute = geometryData.attributes[i];
4783      const name = attribute.name;
4784      const array = attribute.array;
4785      const itemSize = attribute.itemSize;
4786      geometry.setAttribute(name, new BufferAttribute(array, itemSize));
4787    }
4788    return geometry;
4789  }
4790  _loadLibrary(url, responseType) {
4791    const loader = new FileLoader(this.manager);
4792    loader.setPath(this.decoderPath);
4793    loader.setResponseType(responseType);
4794    loader.setWithCredentials(this.withCredentials);
4795    return new Promise((resolve3, reject) => {
4796      loader.load(url, resolve3, void 0, reject);
4797    });
4798  }
4799  preload() {
4800    this._initDecoder();
4801    return this;
4802  }
4803  _initDecoder() {
4804    if (this.decoderPending)
4805      return this.decoderPending;
4806    const useJS = typeof WebAssembly !== "object" || this.decoderConfig.type === "js";
4807    const librariesPending = [];
4808    if (useJS) {
4809      librariesPending.push(this._loadLibrary("draco_decoder.js", "text"));
4810    } else {
4811      librariesPending.push(this._loadLibrary("draco_wasm_wrapper.js", "text"));
4812      librariesPending.push(this._loadLibrary("draco_decoder.wasm", "arraybuffer"));
4813    }
4814    this.decoderPending = Promise.all(librariesPending).then((libraries) => {
4815      const jsContent = libraries[0];
4816      if (!useJS) {
4817        this.decoderConfig.wasmBinary = libraries[1];
4818      }
4819      const fn = DRACOWorker.toString();
4820      const body = [
4821        "/* draco decoder */",
4822        jsContent,
4823        "",
4824        "/* worker */",
4825        fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"))
4826      ].join("\n");
4827      this.workerSourceURL = URL.createObjectURL(new Blob([body]));
4828    });
4829    return this.decoderPending;
4830  }
4831  _getWorker(taskID, taskCost) {
4832    return this._initDecoder().then(() => {
4833      if (this.workerPool.length < this.workerLimit) {
4834        const worker2 = new Worker(this.workerSourceURL);
4835        worker2._callbacks = {};
4836        worker2._taskCosts = {};
4837        worker2._taskLoad = 0;
4838        worker2.postMessage({ type: "init", decoderConfig: this.decoderConfig });
4839        worker2.onmessage = function(e) {
4840          const message = e.data;
4841          switch (message.type) {
4842            case "decode":
4843              worker2._callbacks[message.id].resolve(message);
4844              break;
4845            case "error":
4846              worker2._callbacks[message.id].reject(message);
4847              break;
4848            default:
4849              console.error('THREE.DRACOLoader: Unexpected message, "' + message.type + '"');
4850          }
4851        };
4852        this.workerPool.push(worker2);
4853      } else {
4854        this.workerPool.sort(function(a, b) {
4855          return a._taskLoad > b._taskLoad ? -1 : 1;
4856        });
4857      }
4858      const worker = this.workerPool[this.workerPool.length - 1];
4859      worker._taskCosts[taskID] = taskCost;
4860      worker._taskLoad += taskCost;
4861      return worker;
4862    });
4863  }
4864  _releaseTask(worker, taskID) {
4865    worker._taskLoad -= worker._taskCosts[taskID];
4866    delete worker._callbacks[taskID];
4867    delete worker._taskCosts[taskID];
4868  }
4869  debug() {
4870    console.log(
4871      "Task load: ",
4872      this.workerPool.map((worker) => worker._taskLoad)
4873    );
4874  }
4875  dispose() {
4876    for (let i = 0; i < this.workerPool.length; ++i) {
4877      this.workerPool[i].terminate();
4878    }
4879    this.workerPool.length = 0;
4880    return this;
4881  }
4882};
4883function DRACOWorker() {
4884  let decoderConfig;
4885  let decoderPending;
4886  onmessage = function(e) {
4887    const message = e.data;
4888    switch (message.type) {
4889      case "init":
4890        decoderConfig = message.decoderConfig;
4891        decoderPending = new Promise(function(resolve3) {
4892          decoderConfig.onModuleLoaded = function(draco) {
4893            resolve3({ draco });
4894          };
4895          DracoDecoderModule(decoderConfig);
4896        });
4897        break;
4898      case "decode":
4899        const buffer = message.buffer;
4900        const taskConfig = message.taskConfig;
4901        decoderPending.then((module) => {
4902          const draco = module.draco;
4903          const decoder = new draco.Decoder();
4904          const decoderBuffer = new draco.DecoderBuffer();
4905          decoderBuffer.Init(new Int8Array(buffer), buffer.byteLength);
4906          try {
4907            const geometry = decodeGeometry(draco, decoder, decoderBuffer, taskConfig);
4908            const buffers = geometry.attributes.map((attr) => attr.array.buffer);
4909            if (geometry.index)
4910              buffers.push(geometry.index.array.buffer);
4911            self.postMessage({ type: "decode", id: message.id, geometry }, buffers);
4912          } catch (error) {
4913            console.error(error);
4914            self.postMessage({ type: "error", id: message.id, error: error.message });
4915          } finally {
4916            draco.destroy(decoderBuffer);
4917            draco.destroy(decoder);
4918          }
4919        });
4920        break;
4921    }
4922  };
4923  function decodeGeometry(draco, decoder, decoderBuffer, taskConfig) {
4924    const attributeIDs = taskConfig.attributeIDs;
4925    const attributeTypes = taskConfig.attributeTypes;
4926    let dracoGeometry;
4927    let decodingStatus;
4928    const geometryType = decoder.GetEncodedGeometryType(decoderBuffer);
4929    if (geometryType === draco.TRIANGULAR_MESH) {
4930      dracoGeometry = new draco.Mesh();
4931      decodingStatus = decoder.DecodeBufferToMesh(decoderBuffer, dracoGeometry);
4932    } else if (geometryType === draco.POINT_CLOUD) {
4933      dracoGeometry = new draco.PointCloud();
4934      decodingStatus = decoder.DecodeBufferToPointCloud(decoderBuffer, dracoGeometry);
4935    } else {
4936      throw new Error("THREE.DRACOLoader: Unexpected geometry type.");
4937    }
4938    if (!decodingStatus.ok() || dracoGeometry.ptr === 0) {
4939      throw new Error("THREE.DRACOLoader: Decoding failed: " + decodingStatus.error_msg());
4940    }
4941    const geometry = { index: null, attributes: [] };
4942    for (const attributeName in attributeIDs) {
4943      const attributeType = self[attributeTypes[attributeName]];
4944      let attribute;
4945      let attributeID;
4946      if (taskConfig.useUniqueIDs) {
4947        attributeID = attributeIDs[attributeName];
4948        attribute = decoder.GetAttributeByUniqueId(dracoGeometry, attributeID);
4949      } else {
4950        attributeID = decoder.GetAttributeId(dracoGeometry, draco[attributeIDs[attributeName]]);
4951        if (attributeID === -1)
4952          continue;
4953        attribute = decoder.GetAttribute(dracoGeometry, attributeID);
4954      }
4955      geometry.attributes.push(decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute));
4956    }
4957    if (geometryType === draco.TRIANGULAR_MESH) {
4958      geometry.index = decodeIndex(draco, decoder, dracoGeometry);
4959    }
4960    draco.destroy(dracoGeometry);
4961    return geometry;
4962  }
4963  function decodeIndex(draco, decoder, dracoGeometry) {
4964    const numFaces = dracoGeometry.num_faces();
4965    const numIndices = numFaces * 3;
4966    const byteLength = numIndices * 4;
4967    const ptr = draco._malloc(byteLength);
4968    decoder.GetTrianglesUInt32Array(dracoGeometry, byteLength, ptr);
4969    const index = new Uint32Array(draco.HEAPF32.buffer, ptr, numIndices).slice();
4970    draco._free(ptr);
4971    return { array: index, itemSize: 1 };
4972  }
4973  function decodeAttribute(draco, decoder, dracoGeometry, attributeName, attributeType, attribute) {
4974    const numComponents = attribute.num_components();
4975    const numPoints = dracoGeometry.num_points();
4976    const numValues = numPoints * numComponents;
4977    const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
4978    const dataType = getDracoDataType(draco, attributeType);
4979    const ptr = draco._malloc(byteLength);
4980    decoder.GetAttributeDataArrayForAllPoints(dracoGeometry, attribute, dataType, byteLength, ptr);
4981    const array = new attributeType(draco.HEAPF32.buffer, ptr, numValues).slice();
4982    draco._free(ptr);
4983    return {
4984      name: attributeName,
4985      array,
4986      itemSize: numComponents
4987    };
4988  }
4989  function getDracoDataType(draco, attributeType) {
4990    switch (attributeType) {
4991      case Float32Array:
4992        return draco.DT_FLOAT32;
4993      case Int8Array:
4994        return draco.DT_INT8;
4995      case Int16Array:
4996        return draco.DT_INT16;
4997      case Int32Array:
4998        return draco.DT_INT32;
4999      case Uint8Array:
5000        return draco.DT_UINT8;
5001      case Uint16Array:
5002        return draco.DT_UINT16;
5003      case Uint32Array:
5004        return draco.DT_UINT32;
5005    }
5006  }
5007}
5008
vendor: 4,484 bytes, lines 5009-5127
5009// node_modules/three-stdlib/renderers/CSS2DRenderer.js
5010var CSS2DObject = class extends Object3D {
5011  constructor(element = document.createElement("div")) {
5012    super();
5013    this.isCSS2DObject = true;
5014    this.element = element;
5015    this.element.style.position = "absolute";
5016    this.element.style.userSelect = "none";
5017    this.element.setAttribute("draggable", false);
5018    this.center = new Vector2(0.5, 0.5);
5019    this.addEventListener("removed", function() {
5020      this.traverse(function(object) {
5021        if (object.element instanceof Element && object.element.parentNode !== null) {
5022          object.element.parentNode.removeChild(object.element);
5023        }
5024      });
5025    });
5026  }
5027  copy(source, recursive) {
5028    super.copy(source, recursive);
5029    this.element = source.element.cloneNode(true);
5030    this.center = source.center;
5031    return this;
5032  }
5033};
5034var _vector = /* @__PURE__ */ new Vector3();
5035var _viewMatrix = /* @__PURE__ */ new Matrix4();
5036var _viewProjectionMatrix = /* @__PURE__ */ new Matrix4();
5037var _a = /* @__PURE__ */ new Vector3();
5038var _b = /* @__PURE__ */ new Vector3();
5039var CSS2DRenderer = class {
5040  constructor(parameters = {}) {
5041    const _this = this;
5042    let _width, _height;
5043    let _widthHalf, _heightHalf;
5044    const cache = {
5045      objects: /* @__PURE__ */ new WeakMap()
5046    };
5047    const domElement = parameters.element !== void 0 ? parameters.element : document.createElement("div");
5048    domElement.style.overflow = "hidden";
5049    this.domElement = domElement;
5050    this.getSize = function() {
5051      return {
5052        width: _width,
5053        height: _height
5054      };
5055    };
5056    this.render = function(scene, camera) {
5057      if (scene.matrixWorldAutoUpdate === true)
5058        scene.updateMatrixWorld();
5059      if (camera.parent === null && camera.matrixWorldAutoUpdate === true)
5060        camera.updateMatrixWorld();
5061      _viewMatrix.copy(camera.matrixWorldInverse);
5062      _viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix);
5063      renderObject(scene, scene, camera);
5064      zOrder(scene);
5065    };
5066    this.setSize = function(width, height) {
5067      _width = width;
5068      _height = height;
5069      _widthHalf = _width / 2;
5070      _heightHalf = _height / 2;
5071      domElement.style.width = width + "px";
5072      domElement.style.height = height + "px";
5073    };
5074    function renderObject(object, scene, camera) {
5075      if (object.isCSS2DObject) {
5076        _vector.setFromMatrixPosition(object.matrixWorld);
5077        _vector.applyMatrix4(_viewProjectionMatrix);
5078        const visible = object.visible === true && _vector.z >= -1 && _vector.z <= 1 && object.layers.test(camera.layers) === true;
5079        object.element.style.display = visible === true ? "" : "none";
5080        if (visible === true) {
5081          object.onBeforeRender(_this, scene, camera);
5082          const element = object.element;
5083          element.style.transform = "translate(" + -100 * object.center.x + "%," + -100 * object.center.y + "%)translate(" + (_vector.x * _widthHalf + _widthHalf) + "px," + (-_vector.y * _heightHalf + _heightHalf) + "px)";
5084          if (element.parentNode !== domElement) {
5085            domElement.appendChild(element);
5086          }
5087          object.onAfterRender(_this, scene, camera);
5088        }
5089        const objectData = {
5090          distanceToCameraSquared: getDistanceToSquared(camera, object)
5091        };
5092        cache.objects.set(object, objectData);
5093      }
5094      for (let i = 0, l = object.children.length; i < l; i++) {
5095        renderObject(object.children[i], scene, camera);
5096      }
5097    }
5098    function getDistanceToSquared(object1, object2) {
5099      _a.setFromMatrixPosition(object1.matrixWorld);
5100      _b.setFromMatrixPosition(object2.matrixWorld);
5101      return _a.distanceToSquared(_b);
5102    }
5103    function filterAndFlatten(scene) {
5104      const result = [];
5105      scene.traverse(function(object) {
5106        if (object.isCSS2DObject)
5107          result.push(object);
5108      });
5109      return result;
5110    }
5111    function zOrder(scene) {
5112      const sorted = filterAndFlatten(scene).sort(function(a, b) {
5113        if (a.renderOrder !== b.renderOrder) {
5114          return b.renderOrder - a.renderOrder;
5115        }
5116        const distanceA = cache.objects.get(a).distanceToCameraSquared;
5117        const distanceB = cache.objects.get(b).distanceToCameraSquared;
5118        return distanceA - distanceB;
5119      });
5120      const zMax = sorted.length;
5121      for (let i = 0, l = sorted.length; i < l; i++) {
5122        sorted[i].element.style.zIndex = zMax - i;
5123      }
5124    }
5125  }
5126};
5127
vendor: 70,814 bytes, lines 5128-7049
5128// node_modules/three-stdlib/exporters/GLTFExporter.js
5129var __defProp = Object.defineProperty;
5130var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5131var __publicField = (obj, key, value) => {
5132  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5133  return value;
5134};
5135async function readAsDataURL(blob) {
5136  const buffer = await blob.arrayBuffer();
5137  const data = btoa(String.fromCharCode(...new Uint8Array(buffer)));
5138  return `data:${blob.type || ""};base64,${data}`;
5139}
5140var _renderer;
5141var fullscreenQuadGeometry;
5142var fullscreenQuadMaterial;
5143var fullscreenQuad;
5144function decompress(texture, maxTextureSize = Infinity, renderer = null) {
5145  if (!fullscreenQuadGeometry)
5146    fullscreenQuadGeometry = new PlaneGeometry(2, 2, 1, 1);
5147  if (!fullscreenQuadMaterial)
5148    fullscreenQuadMaterial = new ShaderMaterial({
5149      uniforms: { blitTexture: new Uniform(texture) },
5150      vertexShader: (
5151        /* glsl */
5152        `
5153        varying vec2 vUv;
5154        void main(){
5155            vUv = uv;
5156            gl_Position = vec4(position.xy * 1.0,0.,.999999);
5157        }
5158      `
5159      ),
5160      fragmentShader: (
5161        /* glsl */
5162        `
5163          uniform sampler2D blitTexture; 
5164          varying vec2 vUv;
5165
5166          void main(){ 
5167              gl_FragColor = vec4(vUv.xy, 0, 1);
5168              
5169              #ifdef IS_SRGB
5170              gl_FragColor = LinearTosRGB( texture2D( blitTexture, vUv) );
5171              #else
5172              gl_FragColor = texture2D( blitTexture, vUv);
5173              #endif
5174          }
5175      `
5176      )
5177    });
5178  fullscreenQuadMaterial.uniforms.blitTexture.value = texture;
5179  fullscreenQuadMaterial.defines.IS_SRGB = "colorSpace" in texture ? texture.colorSpace === "srgb" : texture.encoding === 3001;
5180  fullscreenQuadMaterial.needsUpdate = true;
5181  if (!fullscreenQuad) {
5182    fullscreenQuad = new Mesh(fullscreenQuadGeometry, fullscreenQuadMaterial);
5183    fullscreenQuad.frustrumCulled = false;
5184  }
5185  const _camera = new PerspectiveCamera();
5186  const _scene = new Scene();
5187  _scene.add(fullscreenQuad);
5188  if (!renderer) {
5189    renderer = _renderer = new WebGLRenderer({ antialias: false });
5190  }
5191  renderer.setSize(Math.min(texture.image.width, maxTextureSize), Math.min(texture.image.height, maxTextureSize));
5192  renderer.clear();
5193  renderer.render(_scene, _camera);
5194  const readableTexture = new Texture(renderer.domElement);
5195  readableTexture.minFilter = texture.minFilter;
5196  readableTexture.magFilter = texture.magFilter;
5197  readableTexture.wrapS = texture.wrapS;
5198  readableTexture.wrapT = texture.wrapT;
5199  readableTexture.name = texture.name;
5200  if (_renderer) {
5201    _renderer.dispose();
5202    _renderer = null;
5203  }
5204  return readableTexture;
5205}
5206var KHR_mesh_quantization_ExtraAttrTypes = {
5207  POSITION: [
5208    "byte",
5209    "byte normalized",
5210    "unsigned byte",
5211    "unsigned byte normalized",
5212    "short",
5213    "short normalized",
5214    "unsigned short",
5215    "unsigned short normalized"
5216  ],
5217  NORMAL: ["byte normalized", "short normalized"],
5218  TANGENT: ["byte normalized", "short normalized"],
5219  TEXCOORD: ["byte", "byte normalized", "unsigned byte", "short", "short normalized", "unsigned short"]
5220};
5221var GLTFExporter = /* @__PURE__ */ (() => {
5222  class GLTFExporter2 {
5223    constructor() {
5224      this.pluginCallbacks = [];
5225      this.register(function(writer) {
5226        return new GLTFLightExtension(writer);
5227      });
5228      this.register(function(writer) {
5229        return new GLTFMaterialsUnlitExtension2(writer);
5230      });
5231      this.register(function(writer) {
5232        return new GLTFMaterialsTransmissionExtension2(writer);
5233      });
5234      this.register(function(writer) {
5235        return new GLTFMaterialsVolumeExtension2(writer);
5236      });
5237      this.register(function(writer) {
5238        return new GLTFMaterialsIorExtension2(writer);
5239      });
5240      this.register(function(writer) {
5241        return new GLTFMaterialsSpecularExtension2(writer);
5242      });
5243      this.register(function(writer) {
5244        return new GLTFMaterialsClearcoatExtension2(writer);
5245      });
5246      this.register(function(writer) {
5247        return new GLTFMaterialsIridescenceExtension2(writer);
5248      });
5249      this.register(function(writer) {
5250        return new GLTFMaterialsSheenExtension2(writer);
5251      });
5252      this.register(function(writer) {
5253        return new GLTFMaterialsAnisotropyExtension2(writer);
5254      });
5255      this.register(function(writer) {
5256        return new GLTFMaterialsEmissiveStrengthExtension2(writer);
5257      });
5258    }
5259    register(callback) {
5260      if (this.pluginCallbacks.indexOf(callback) === -1) {
5261        this.pluginCallbacks.push(callback);
5262      }
5263      return this;
5264    }
5265    unregister(callback) {
5266      if (this.pluginCallbacks.indexOf(callback) !== -1) {
5267        this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1);
5268      }
5269      return this;
5270    }
5271    /**
5272     * Parse scenes and generate GLTF output
5273     * @param  {Scene or [THREE.Scenes]} input   Scene or Array of THREE.Scenes
5274     * @param  {Function} onDone  Callback on completed
5275     * @param  {Function} onError  Callback on errors
5276     * @param  {Object} options options
5277     */
5278    parse(input, onDone, onError, options) {
5279      const writer = new GLTFWriter();
5280      const plugins = [];
5281      for (let i = 0, il = this.pluginCallbacks.length; i < il; i++) {
5282        plugins.push(this.pluginCallbacks[i](writer));
5283      }
5284      writer.setPlugins(plugins);
5285      writer.write(input, onDone, options).catch(onError);
5286    }
5287    parseAsync(input, options) {
5288      const scope = this;
5289      return new Promise(function(resolve3, reject) {
5290        scope.parse(input, resolve3, reject, options);
5291      });
5292    }
5293  }
5294  __publicField(GLTFExporter2, "Utils", {
5295    insertKeyframe: function(track, time) {
5296      const tolerance = 1e-3;
5297      const valueSize = track.getValueSize();
5298      const times = new track.TimeBufferType(track.times.length + 1);
5299      const values = new track.ValueBufferType(track.values.length + valueSize);
5300      const interpolant = track.createInterpolant(new track.ValueBufferType(valueSize));
5301      let index;
5302      if (track.times.length === 0) {
5303        times[0] = time;
5304        for (let i = 0; i < valueSize; i++) {
5305          values[i] = 0;
5306        }
5307        index = 0;
5308      } else if (time < track.times[0]) {
5309        if (Math.abs(track.times[0] - time) < tolerance)
5310          return 0;
5311        times[0] = time;
5312        times.set(track.times, 1);
5313        values.set(interpolant.evaluate(time), 0);
5314        values.set(track.values, valueSize);
5315        index = 0;
5316      } else if (time > track.times[track.times.length - 1]) {
5317        if (Math.abs(track.times[track.times.length - 1] - time) < tolerance) {
5318          return track.times.length - 1;
5319        }
5320        times[times.length - 1] = time;
5321        times.set(track.times, 0);
5322        values.set(track.values, 0);
5323        values.set(interpolant.evaluate(time), track.values.length);
5324        index = times.length - 1;
5325      } else {
5326        for (let i = 0; i < track.times.length; i++) {
5327          if (Math.abs(track.times[i] - time) < tolerance)
5328            return i;
5329          if (track.times[i] < time && track.times[i + 1] > time) {
5330            times.set(track.times.slice(0, i + 1), 0);
5331            times[i + 1] = time;
5332            times.set(track.times.slice(i + 1), i + 2);
5333            values.set(track.values.slice(0, (i + 1) * valueSize), 0);
5334            values.set(interpolant.evaluate(time), (i + 1) * valueSize);
5335            values.set(track.values.slice((i + 1) * valueSize), (i + 2) * valueSize);
5336            index = i + 1;
5337            break;
5338          }
5339        }
5340      }
5341      track.times = times;
5342      track.values = values;
5343      return index;
5344    },
5345    mergeMorphTargetTracks: function(clip, root) {
5346      const tracks = [];
5347      const mergedTracks = {};
5348      const sourceTracks = clip.tracks;
5349      for (let i = 0; i < sourceTracks.length; ++i) {
5350        let sourceTrack = sourceTracks[i];
5351        const sourceTrackBinding = PropertyBinding.parseTrackName(sourceTrack.name);
5352        const sourceTrackNode = PropertyBinding.findNode(root, sourceTrackBinding.nodeName);
5353        if (sourceTrackBinding.propertyName !== "morphTargetInfluences" || sourceTrackBinding.propertyIndex === void 0) {
5354          tracks.push(sourceTrack);
5355          continue;
5356        }
5357        if (sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodDiscrete && sourceTrack.createInterpolant !== sourceTrack.InterpolantFactoryMethodLinear) {
5358          if (sourceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
5359            throw new Error("THREE.GLTFExporter: Cannot merge tracks with glTF CUBICSPLINE interpolation.");
5360          }
5361          console.warn("THREE.GLTFExporter: Morph target interpolation mode not yet supported. Using LINEAR instead.");
5362          sourceTrack = sourceTrack.clone();
5363          sourceTrack.setInterpolation(InterpolateLinear);
5364        }
5365        const targetCount = sourceTrackNode.morphTargetInfluences.length;
5366        const targetIndex = sourceTrackNode.morphTargetDictionary[sourceTrackBinding.propertyIndex];
5367        if (targetIndex === void 0) {
5368          throw new Error("THREE.GLTFExporter: Morph target name not found: " + sourceTrackBinding.propertyIndex);
5369        }
5370        let mergedTrack;
5371        if (mergedTracks[sourceTrackNode.uuid] === void 0) {
5372          mergedTrack = sourceTrack.clone();
5373          const values = new mergedTrack.ValueBufferType(targetCount * mergedTrack.times.length);
5374          for (let j = 0; j < mergedTrack.times.length; j++) {
5375            values[j * targetCount + targetIndex] = mergedTrack.values[j];
5376          }
5377          mergedTrack.name = (sourceTrackBinding.nodeName || "") + ".morphTargetInfluences";
5378          mergedTrack.values = values;
5379          mergedTracks[sourceTrackNode.uuid] = mergedTrack;
5380          tracks.push(mergedTrack);
5381          continue;
5382        }
5383        const sourceInterpolant = sourceTrack.createInterpolant(new sourceTrack.ValueBufferType(1));
5384        mergedTrack = mergedTracks[sourceTrackNode.uuid];
5385        for (let j = 0; j < mergedTrack.times.length; j++) {
5386          mergedTrack.values[j * targetCount + targetIndex] = sourceInterpolant.evaluate(mergedTrack.times[j]);
5387        }
5388        for (let j = 0; j < sourceTrack.times.length; j++) {
5389          const keyframeIndex = this.insertKeyframe(mergedTrack, sourceTrack.times[j]);
5390          mergedTrack.values[keyframeIndex * targetCount + targetIndex] = sourceTrack.values[j];
5391        }
5392      }
5393      clip.tracks = tracks;
5394      return clip;
5395    }
5396  });
5397  return GLTFExporter2;
5398})();
5399var WEBGL_CONSTANTS2 = {
5400  POINTS: 0,
5401  LINES: 1,
5402  LINE_LOOP: 2,
5403  LINE_STRIP: 3,
5404  TRIANGLES: 4,
5405  TRIANGLE_STRIP: 5,
5406  TRIANGLE_FAN: 6,
5407  BYTE: 5120,
5408  UNSIGNED_BYTE: 5121,
5409  SHORT: 5122,
5410  UNSIGNED_SHORT: 5123,
5411  INT: 5124,
5412  UNSIGNED_INT: 5125,
5413  FLOAT: 5126,
5414  ARRAY_BUFFER: 34962,
5415  ELEMENT_ARRAY_BUFFER: 34963,
5416  NEAREST: 9728,
5417  LINEAR: 9729,
5418  NEAREST_MIPMAP_NEAREST: 9984,
5419  LINEAR_MIPMAP_NEAREST: 9985,
5420  NEAREST_MIPMAP_LINEAR: 9986,
5421  LINEAR_MIPMAP_LINEAR: 9987,
5422  CLAMP_TO_EDGE: 33071,
5423  MIRRORED_REPEAT: 33648,
5424  REPEAT: 10497
5425};
5426var KHR_MESH_QUANTIZATION = "KHR_mesh_quantization";
5427var THREE_TO_WEBGL = {};
5428THREE_TO_WEBGL[NearestFilter] = WEBGL_CONSTANTS2.NEAREST;
5429THREE_TO_WEBGL[NearestMipmapNearestFilter] = WEBGL_CONSTANTS2.NEAREST_MIPMAP_NEAREST;
5430THREE_TO_WEBGL[NearestMipmapLinearFilter] = WEBGL_CONSTANTS2.NEAREST_MIPMAP_LINEAR;
5431THREE_TO_WEBGL[LinearFilter] = WEBGL_CONSTANTS2.LINEAR;
5432THREE_TO_WEBGL[LinearMipmapNearestFilter] = WEBGL_CONSTANTS2.LINEAR_MIPMAP_NEAREST;
5433THREE_TO_WEBGL[LinearMipmapLinearFilter] = WEBGL_CONSTANTS2.LINEAR_MIPMAP_LINEAR;
5434THREE_TO_WEBGL[ClampToEdgeWrapping] = WEBGL_CONSTANTS2.CLAMP_TO_EDGE;
5435THREE_TO_WEBGL[RepeatWrapping] = WEBGL_CONSTANTS2.REPEAT;
5436THREE_TO_WEBGL[MirroredRepeatWrapping] = WEBGL_CONSTANTS2.MIRRORED_REPEAT;
5437var PATH_PROPERTIES2 = {
5438  scale: "scale",
5439  position: "translation",
5440  quaternion: "rotation",
5441  morphTargetInfluences: "weights"
5442};
5443var DEFAULT_SPECULAR_COLOR = /* @__PURE__ */ new Color();
5444var GLB_HEADER_BYTES = 12;
5445var GLB_HEADER_MAGIC = 1179937895;
5446var GLB_VERSION = 2;
5447var GLB_CHUNK_PREFIX_BYTES = 8;
5448var GLB_CHUNK_TYPE_JSON = 1313821514;
5449var GLB_CHUNK_TYPE_BIN = 5130562;
5450function equalArray(array1, array2) {
5451  return array1.length === array2.length && array1.every(function(element, index) {
5452    return element === array2[index];
5453  });
5454}
5455function stringToArrayBuffer(text) {
5456  return new TextEncoder().encode(text).buffer;
5457}
5458function isIdentityMatrix(matrix) {
5459  return equalArray(matrix.elements, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
5460}
5461function getMinMax(attribute, start, count) {
5462  const output = {
5463    min: new Array(attribute.itemSize).fill(Number.POSITIVE_INFINITY),
5464    max: new Array(attribute.itemSize).fill(Number.NEGATIVE_INFINITY)
5465  };
5466  for (let i = start; i < start + count; i++) {
5467    for (let a = 0; a < attribute.itemSize; a++) {
5468      let value;
5469      if (attribute.itemSize > 4) {
5470        value = attribute.array[i * attribute.itemSize + a];
5471      } else {
5472        if (a === 0)
5473          value = attribute.getX(i);
5474        else if (a === 1)
5475          value = attribute.getY(i);
5476        else if (a === 2)
5477          value = attribute.getZ(i);
5478        else if (a === 3)
5479          value = attribute.getW(i);
5480        if (attribute.normalized === true) {
5481          value = MathUtils.normalize(value, attribute.array);
5482        }
5483      }
5484      output.min[a] = Math.min(output.min[a], value);
5485      output.max[a] = Math.max(output.max[a], value);
5486    }
5487  }
5488  return output;
5489}
5490function getPaddedBufferSize(bufferSize) {
5491  return Math.ceil(bufferSize / 4) * 4;
5492}
5493function getPaddedArrayBuffer(arrayBuffer, paddingByte = 0) {
5494  const paddedLength = getPaddedBufferSize(arrayBuffer.byteLength);
5495  if (paddedLength !== arrayBuffer.byteLength) {
5496    const array = new Uint8Array(paddedLength);
5497    array.set(new Uint8Array(arrayBuffer));
5498    if (paddingByte !== 0) {
5499      for (let i = arrayBuffer.byteLength; i < paddedLength; i++) {
5500        array[i] = paddingByte;
5501      }
5502    }
5503    return array.buffer;
5504  }
5505  return arrayBuffer;
5506}
5507function getCanvas() {
5508  if (typeof document === "undefined" && typeof OffscreenCanvas !== "undefined") {
5509    return new OffscreenCanvas(1, 1);
5510  }
5511  return document.createElement("canvas");
5512}
5513function getToBlobPromise(canvas, mimeType) {
5514  if (canvas.toBlob !== void 0) {
5515    return new Promise((resolve3) => canvas.toBlob(resolve3, mimeType));
5516  }
5517  let quality;
5518  if (mimeType === "image/jpeg") {
5519    quality = 0.92;
5520  } else if (mimeType === "image/webp") {
5521    quality = 0.8;
5522  }
5523  return canvas.convertToBlob({
5524    type: mimeType,
5525    quality
5526  });
5527}
5528var GLTFWriter = class {
5529  constructor() {
5530    this.plugins = [];
5531    this.options = {};
5532    this.pending = [];
5533    this.buffers = [];
5534    this.byteOffset = 0;
5535    this.buffers = [];
5536    this.nodeMap = /* @__PURE__ */ new Map();
5537    this.skins = [];
5538    this.extensionsUsed = {};
5539    this.extensionsRequired = {};
5540    this.uids = /* @__PURE__ */ new Map();
5541    this.uid = 0;
5542    this.json = {
5543      asset: {
5544        version: "2.0",
5545        generator: "THREE.GLTFExporter"
5546      }
5547    };
5548    this.cache = {
5549      meshes: /* @__PURE__ */ new Map(),
5550      attributes: /* @__PURE__ */ new Map(),
5551      attributesNormalized: /* @__PURE__ */ new Map(),
5552      materials: /* @__PURE__ */ new Map(),
5553      textures: /* @__PURE__ */ new Map(),
5554      images: /* @__PURE__ */ new Map()
5555    };
5556  }
5557  setPlugins(plugins) {
5558    this.plugins = plugins;
5559  }
5560  /**
5561   * Parse scenes and generate GLTF output
5562   * @param  {Scene or [THREE.Scenes]} input   Scene or Array of THREE.Scenes
5563   * @param  {Function} onDone  Callback on completed
5564   * @param  {Object} options options
5565   */
5566  async write(input, onDone, options = {}) {
5567    this.options = Object.assign(
5568      {
5569        // default options
5570        binary: false,
5571        trs: false,
5572        onlyVisible: true,
5573        maxTextureSize: Infinity,
5574        animations: [],
5575        includeCustomExtensions: false
5576      },
5577      options
5578    );
5579    if (this.options.animations.length > 0) {
5580      this.options.trs = true;
5581    }
5582    this.processInput(input);
5583    await Promise.all(this.pending);
5584    const writer = this;
5585    const buffers = writer.buffers;
5586    const json = writer.json;
5587    options = writer.options;
5588    const extensionsUsed = writer.extensionsUsed;
5589    const extensionsRequired = writer.extensionsRequired;
5590    const blob = new Blob(buffers, { type: "application/octet-stream" });
5591    const extensionsUsedList = Object.keys(extensionsUsed);
5592    const extensionsRequiredList = Object.keys(extensionsRequired);
5593    if (extensionsUsedList.length > 0)
5594      json.extensionsUsed = extensionsUsedList;
5595    if (extensionsRequiredList.length > 0)
5596      json.extensionsRequired = extensionsRequiredList;
5597    if (json.buffers && json.buffers.length > 0)
5598      json.buffers[0].byteLength = blob.size;
5599    if (options.binary === true) {
5600      blob.arrayBuffer().then((result) => {
5601        const binaryChunk = getPaddedArrayBuffer(result);
5602        const binaryChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
5603        binaryChunkPrefix.setUint32(0, binaryChunk.byteLength, true);
5604        binaryChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_BIN, true);
5605        const jsonChunk = getPaddedArrayBuffer(stringToArrayBuffer(JSON.stringify(json)), 32);
5606        const jsonChunkPrefix = new DataView(new ArrayBuffer(GLB_CHUNK_PREFIX_BYTES));
5607        jsonChunkPrefix.setUint32(0, jsonChunk.byteLength, true);
5608        jsonChunkPrefix.setUint32(4, GLB_CHUNK_TYPE_JSON, true);
5609        const header = new ArrayBuffer(GLB_HEADER_BYTES);
5610        const headerView = new DataView(header);
5611        headerView.setUint32(0, GLB_HEADER_MAGIC, true);
5612        headerView.setUint32(4, GLB_VERSION, true);
5613        const totalByteLength = GLB_HEADER_BYTES + jsonChunkPrefix.byteLength + jsonChunk.byteLength + binaryChunkPrefix.byteLength + binaryChunk.byteLength;
5614        headerView.setUint32(8, totalByteLength, true);
5615        const glbBlob = new Blob([header, jsonChunkPrefix, jsonChunk, binaryChunkPrefix, binaryChunk], {
5616          type: "application/octet-stream"
5617        });
5618        glbBlob.arrayBuffer().then(onDone);
5619      });
5620    } else {
5621      if (json.buffers && json.buffers.length > 0) {
5622        readAsDataURL(blob).then((uri) => {
5623          json.buffers[0].uri = uri;
5624          onDone(json);
5625        });
5626      } else {
5627        onDone(json);
5628      }
5629    }
5630  }
5631  /**
5632   * Serializes a userData.
5633   *
5634   * @param {THREE.Object3D|THREE.Material} object
5635   * @param {Object} objectDef
5636   */
5637  serializeUserData(object, objectDef) {
5638    if (Object.keys(object.userData).length === 0)
5639      return;
5640    const options = this.options;
5641    const extensionsUsed = this.extensionsUsed;
5642    try {
5643      const json = JSON.parse(JSON.stringify(object.userData));
5644      if (options.includeCustomExtensions && json.gltfExtensions) {
5645        if (objectDef.extensions === void 0)
5646          objectDef.extensions = {};
5647        for (const extensionName in json.gltfExtensions) {
5648          objectDef.extensions[extensionName] = json.gltfExtensions[extensionName];
5649          extensionsUsed[extensionName] = true;
5650        }
5651        delete json.gltfExtensions;
5652      }
5653      if (Object.keys(json).length > 0)
5654        objectDef.extras = json;
5655    } catch (error) {
5656      console.warn(
5657        "THREE.GLTFExporter: userData of '" + object.name + "' won't be serialized because of JSON.stringify error - " + error.message
5658      );
5659    }
5660  }
5661  /**
5662   * Returns ids for buffer attributes.
5663   * @param  {Object} object
5664   * @return {Integer}
5665   */
5666  getUID(attribute, isRelativeCopy = false) {
5667    if (this.uids.has(attribute) === false) {
5668      const uids2 = /* @__PURE__ */ new Map();
5669      uids2.set(true, this.uid++);
5670      uids2.set(false, this.uid++);
5671      this.uids.set(attribute, uids2);
5672    }
5673    const uids = this.uids.get(attribute);
5674    return uids.get(isRelativeCopy);
5675  }
5676  /**
5677   * Checks if normal attribute values are normalized.
5678   *
5679   * @param {BufferAttribute} normal
5680   * @returns {Boolean}
5681   */
5682  isNormalizedNormalAttribute(normal) {
5683    const cache = this.cache;
5684    if (cache.attributesNormalized.has(normal))
5685      return false;
5686    const v = new Vector3();
5687    for (let i = 0, il = normal.count; i < il; i++) {
5688      if (Math.abs(v.fromBufferAttribute(normal, i).length() - 1) > 5e-4)
5689        return false;
5690    }
5691    return true;
5692  }
5693  /**
5694   * Creates normalized normal buffer attribute.
5695   *
5696   * @param {BufferAttribute} normal
5697   * @returns {BufferAttribute}
5698   *
5699   */
5700  createNormalizedNormalAttribute(normal) {
5701    const cache = this.cache;
5702    if (cache.attributesNormalized.has(normal))
5703      return cache.attributesNormalized.get(normal);
5704    const attribute = normal.clone();
5705    const v = new Vector3();
5706    for (let i = 0, il = attribute.count; i < il; i++) {
5707      v.fromBufferAttribute(attribute, i);
5708      if (v.x === 0 && v.y === 0 && v.z === 0) {
5709        v.setX(1);
5710      } else {
5711        v.normalize();
5712      }
5713      attribute.setXYZ(i, v.x, v.y, v.z);
5714    }
5715    cache.attributesNormalized.set(normal, attribute);
5716    return attribute;
5717  }
5718  /**
5719   * Applies a texture transform, if present, to the map definition. Requires
5720   * the KHR_texture_transform extension.
5721   *
5722   * @param {Object} mapDef
5723   * @param {THREE.Texture} texture
5724   */
5725  applyTextureTransform(mapDef, texture) {
5726    let didTransform = false;
5727    const transformDef = {};
5728    if (texture.offset.x !== 0 || texture.offset.y !== 0) {
5729      transformDef.offset = texture.offset.toArray();
5730      didTransform = true;
5731    }
5732    if (texture.rotation !== 0) {
5733      transformDef.rotation = texture.rotation;
5734      didTransform = true;
5735    }
5736    if (texture.repeat.x !== 1 || texture.repeat.y !== 1) {
5737      transformDef.scale = texture.repeat.toArray();
5738      didTransform = true;
5739    }
5740    if (didTransform) {
5741      mapDef.extensions = mapDef.extensions || {};
5742      mapDef.extensions["KHR_texture_transform"] = transformDef;
5743      this.extensionsUsed["KHR_texture_transform"] = true;
5744    }
5745  }
5746  buildMetalRoughTexture(metalnessMap, roughnessMap) {
5747    if (metalnessMap === roughnessMap)
5748      return metalnessMap;
5749    function getEncodingConversion(map) {
5750      if ("colorSpace" in map ? map.colorSpace === "srgb" : map.encoding === 3001) {
5751        return function SRGBToLinear(c) {
5752          return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
5753        };
5754      }
5755      return function LinearToLinear(c) {
5756        return c;
5757      };
5758    }
5759    console.warn("THREE.GLTFExporter: Merged metalnessMap and roughnessMap textures.");
5760    if (metalnessMap instanceof CompressedTexture) {
5761      metalnessMap = decompress(metalnessMap);
5762    }
5763    if (roughnessMap instanceof CompressedTexture) {
5764      roughnessMap = decompress(roughnessMap);
5765    }
5766    const metalness = metalnessMap ? metalnessMap.image : null;
5767    const roughness = roughnessMap ? roughnessMap.image : null;
5768    const width = Math.max(metalness ? metalness.width : 0, roughness ? roughness.width : 0);
5769    const height = Math.max(metalness ? metalness.height : 0, roughness ? roughness.height : 0);
5770    const canvas = getCanvas();
5771    canvas.width = width;
5772    canvas.height = height;
5773    const context = canvas.getContext("2d");
5774    context.fillStyle = "#00ffff";
5775    context.fillRect(0, 0, width, height);
5776    const composite = context.getImageData(0, 0, width, height);
5777    if (metalness) {
5778      context.drawImage(metalness, 0, 0, width, height);
5779      const convert = getEncodingConversion(metalnessMap);
5780      const data = context.getImageData(0, 0, width, height).data;
5781      for (let i = 2; i < data.length; i += 4) {
5782        composite.data[i] = convert(data[i] / 256) * 256;
5783      }
5784    }
5785    if (roughness) {
5786      context.drawImage(roughness, 0, 0, width, height);
5787      const convert = getEncodingConversion(roughnessMap);
5788      const data = context.getImageData(0, 0, width, height).data;
5789      for (let i = 1; i < data.length; i += 4) {
5790        composite.data[i] = convert(data[i] / 256) * 256;
5791      }
5792    }
5793    context.putImageData(composite, 0, 0);
5794    const reference = metalnessMap || roughnessMap;
5795    const texture = reference.clone();
5796    texture.source = new Texture(canvas).source;
5797    if ("colorSpace" in texture)
5798      texture.colorSpace = "";
5799    else
5800      texture.encoding = 3e3;
5801    texture.channel = (metalnessMap || roughnessMap).channel;
5802    if (metalnessMap && roughnessMap && metalnessMap.channel !== roughnessMap.channel) {
5803      console.warn("THREE.GLTFExporter: UV channels for metalnessMap and roughnessMap textures must match.");
5804    }
5805    return texture;
5806  }
5807  /**
5808   * Process a buffer to append to the default one.
5809   * @param  {ArrayBuffer} buffer
5810   * @return {Integer}
5811   */
5812  processBuffer(buffer) {
5813    const json = this.json;
5814    const buffers = this.buffers;
5815    if (!json.buffers)
5816      json.buffers = [{ byteLength: 0 }];
5817    buffers.push(buffer);
5818    return 0;
5819  }
5820  /**
5821   * Process and generate a BufferView
5822   * @param  {BufferAttribute} attribute
5823   * @param  {number} componentType
5824   * @param  {number} start
5825   * @param  {number} count
5826   * @param  {number} target (Optional) Target usage of the BufferView
5827   * @return {Object}
5828   */
5829  processBufferView(attribute, componentType, start, count, target) {
5830    const json = this.json;
5831    if (!json.bufferViews)
5832      json.bufferViews = [];
5833    let componentSize;
5834    switch (componentType) {
5835      case WEBGL_CONSTANTS2.BYTE:
5836      case WEBGL_CONSTANTS2.UNSIGNED_BYTE:
5837        componentSize = 1;
5838        break;
5839      case WEBGL_CONSTANTS2.SHORT:
5840      case WEBGL_CONSTANTS2.UNSIGNED_SHORT:
5841        componentSize = 2;
5842        break;
5843      default:
5844        componentSize = 4;
5845    }
5846    let byteStride = attribute.itemSize * componentSize;
5847    if (target === WEBGL_CONSTANTS2.ARRAY_BUFFER) {
5848      byteStride = Math.ceil(byteStride / 4) * 4;
5849    }
5850    const byteLength = getPaddedBufferSize(count * byteStride);
5851    const dataView = new DataView(new ArrayBuffer(byteLength));
5852    let offset = 0;
5853    for (let i = start; i < start + count; i++) {
5854      for (let a = 0; a < attribute.itemSize; a++) {
5855        let value;
5856        if (attribute.itemSize > 4) {
5857          value = attribute.array[i * attribute.itemSize + a];
5858        } else {
5859          if (a === 0)
5860            value = attribute.getX(i);
5861          else if (a === 1)
5862            value = attribute.getY(i);
5863          else if (a === 2)
5864            value = attribute.getZ(i);
5865          else if (a === 3)
5866            value = attribute.getW(i);
5867          if (attribute.normalized === true) {
5868            value = MathUtils.normalize(value, attribute.array);
5869          }
5870        }
5871        if (componentType === WEBGL_CONSTANTS2.FLOAT) {
5872          dataView.setFloat32(offset, value, true);
5873        } else if (componentType === WEBGL_CONSTANTS2.INT) {
5874          dataView.setInt32(offset, value, true);
5875        } else if (componentType === WEBGL_CONSTANTS2.UNSIGNED_INT) {
5876          dataView.setUint32(offset, value, true);
5877        } else if (componentType === WEBGL_CONSTANTS2.SHORT) {
5878          dataView.setInt16(offset, value, true);
5879        } else if (componentType === WEBGL_CONSTANTS2.UNSIGNED_SHORT) {
5880          dataView.setUint16(offset, value, true);
5881        } else if (componentType === WEBGL_CONSTANTS2.BYTE) {
5882          dataView.setInt8(offset, value);
5883        } else if (componentType === WEBGL_CONSTANTS2.UNSIGNED_BYTE) {
5884          dataView.setUint8(offset, value);
5885        }
5886        offset += componentSize;
5887      }
5888      if (offset % byteStride !== 0) {
5889        offset += byteStride - offset % byteStride;
5890      }
5891    }
5892    const bufferViewDef = {
5893      buffer: this.processBuffer(dataView.buffer),
5894      byteOffset: this.byteOffset,
5895      byteLength
5896    };
5897    if (target !== void 0)
5898      bufferViewDef.target = target;
5899    if (target === WEBGL_CONSTANTS2.ARRAY_BUFFER) {
5900      bufferViewDef.byteStride = byteStride;
5901    }
5902    this.byteOffset += byteLength;
5903    json.bufferViews.push(bufferViewDef);
5904    const output = {
5905      id: json.bufferViews.length - 1,
5906      byteLength: 0
5907    };
5908    return output;
5909  }
5910  /**
5911   * Process and generate a BufferView from an image Blob.
5912   * @param {Blob} blob
5913   * @return {Promise<Integer>}
5914   */
5915  processBufferViewImage(blob) {
5916    const writer = this;
5917    const json = writer.json;
5918    if (!json.bufferViews)
5919      json.bufferViews = [];
5920    return blob.arrayBuffer().then((result) => {
5921      const buffer = getPaddedArrayBuffer(result);
5922      const bufferViewDef = {
5923        buffer: writer.processBuffer(buffer),
5924        byteOffset: writer.byteOffset,
5925        byteLength: buffer.byteLength
5926      };
5927      writer.byteOffset += buffer.byteLength;
5928      return json.bufferViews.push(bufferViewDef) - 1;
5929    });
5930  }
5931  /**
5932   * Process attribute to generate an accessor
5933   * @param  {BufferAttribute} attribute Attribute to process
5934   * @param  {THREE.BufferGeometry} geometry (Optional) Geometry used for truncated draw range
5935   * @param  {Integer} start (Optional)
5936   * @param  {Integer} count (Optional)
5937   * @return {Integer|null} Index of the processed accessor on the "accessors" array
5938   */
5939  processAccessor(attribute, geometry, start, count) {
5940    const json = this.json;
5941    const types = {
5942      1: "SCALAR",
5943      2: "VEC2",
5944      3: "VEC3",
5945      4: "VEC4",
5946      9: "MAT3",
5947      16: "MAT4"
5948    };
5949    let componentType;
5950    if (attribute.array.constructor === Float32Array) {
5951      componentType = WEBGL_CONSTANTS2.FLOAT;
5952    } else if (attribute.array.constructor === Int32Array) {
5953      componentType = WEBGL_CONSTANTS2.INT;
5954    } else if (attribute.array.constructor === Uint32Array) {
5955      componentType = WEBGL_CONSTANTS2.UNSIGNED_INT;
5956    } else if (attribute.array.constructor === Int16Array) {
5957      componentType = WEBGL_CONSTANTS2.SHORT;
5958    } else if (attribute.array.constructor === Uint16Array) {
5959      componentType = WEBGL_CONSTANTS2.UNSIGNED_SHORT;
5960    } else if (attribute.array.constructor === Int8Array) {
5961      componentType = WEBGL_CONSTANTS2.BYTE;
5962    } else if (attribute.array.constructor === Uint8Array) {
5963      componentType = WEBGL_CONSTANTS2.UNSIGNED_BYTE;
5964    } else {
5965      throw new Error(
5966        "THREE.GLTFExporter: Unsupported bufferAttribute component type: " + attribute.array.constructor.name
5967      );
5968    }
5969    if (start === void 0)
5970      start = 0;
5971    if (count === void 0)
5972      count = attribute.count;
5973    if (count === 0)
5974      return null;
5975    const minMax = getMinMax(attribute, start, count);
5976    let bufferViewTarget;
5977    if (geometry !== void 0) {
5978      bufferViewTarget = attribute === geometry.index ? WEBGL_CONSTANTS2.ELEMENT_ARRAY_BUFFER : WEBGL_CONSTANTS2.ARRAY_BUFFER;
5979    }
5980    const bufferView = this.processBufferView(attribute, componentType, start, count, bufferViewTarget);
5981    const accessorDef = {
5982      bufferView: bufferView.id,
5983      byteOffset: bufferView.byteOffset,
5984      componentType,
5985      count,
5986      max: minMax.max,
5987      min: minMax.min,
5988      type: types[attribute.itemSize]
5989    };
5990    if (attribute.normalized === true)
5991      accessorDef.normalized = true;
5992    if (!json.accessors)
5993      json.accessors = [];
5994    return json.accessors.push(accessorDef) - 1;
5995  }
5996  /**
5997   * Process image
5998   * @param  {Image} image to process
5999   * @param  {Integer} format of the image (RGBAFormat)
6000   * @param  {Boolean} flipY before writing out the image
6001   * @param  {String} mimeType export format
6002   * @return {Integer}     Index of the processed texture in the "images" array
6003   */
6004  processImage(image, format, flipY, mimeType = "image/png") {
6005    if (image !== null) {
6006      const writer = this;
6007      const cache = writer.cache;
6008      const json = writer.json;
6009      const options = writer.options;
6010      const pending = writer.pending;
6011      if (!cache.images.has(image))
6012        cache.images.set(image, {});
6013      const cachedImages = cache.images.get(image);
6014      const key = mimeType + ":flipY/" + flipY.toString();
6015      if (cachedImages[key] !== void 0)
6016        return cachedImages[key];
6017      if (!json.images)
6018        json.images = [];
6019      const imageDef = { mimeType };
6020      const canvas = getCanvas();
6021      canvas.width = Math.min(image.width, options.maxTextureSize);
6022      canvas.height = Math.min(image.height, options.maxTextureSize);
6023      const ctx = canvas.getContext("2d");
6024      if (flipY === true) {
6025        ctx.translate(0, canvas.height);
6026        ctx.scale(1, -1);
6027      }
6028      if (image.data !== void 0) {
6029        if (format !== RGBAFormat) {
6030          console.error("GLTFExporter: Only RGBAFormat is supported.", format);
6031        }
6032        if (image.width > options.maxTextureSize || image.height > options.maxTextureSize) {
6033          console.warn("GLTFExporter: Image size is bigger than maxTextureSize", image);
6034        }
6035        const data = new Uint8ClampedArray(image.height * image.width * 4);
6036        for (let i = 0; i < data.length; i += 4) {
6037          data[i + 0] = image.data[i + 0];
6038          data[i + 1] = image.data[i + 1];
6039          data[i + 2] = image.data[i + 2];
6040          data[i + 3] = image.data[i + 3];
6041        }
6042        ctx.putImageData(new ImageData(data, image.width, image.height), 0, 0);
6043      } else {
6044        ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
6045      }
6046      if (options.binary === true) {
6047        pending.push(
6048          getToBlobPromise(canvas, mimeType).then((blob) => writer.processBufferViewImage(blob)).then((bufferViewIndex) => {
6049            imageDef.bufferView = bufferViewIndex;
6050          })
6051        );
6052      } else {
6053        if (canvas.toDataURL !== void 0) {
6054          imageDef.uri = canvas.toDataURL(mimeType);
6055        } else {
6056          pending.push(
6057            getToBlobPromise(canvas, mimeType).then(readAsDataURL).then((uri) => {
6058              imageDef.uri = uri;
6059            })
6060          );
6061        }
6062      }
6063      const index = json.images.push(imageDef) - 1;
6064      cachedImages[key] = index;
6065      return index;
6066    } else {
6067      throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.");
6068    }
6069  }
6070  /**
6071   * Process sampler
6072   * @param  {Texture} map Texture to process
6073   * @return {Integer}     Index of the processed texture in the "samplers" array
6074   */
6075  processSampler(map) {
6076    const json = this.json;
6077    if (!json.samplers)
6078      json.samplers = [];
6079    const samplerDef = {
6080      magFilter: THREE_TO_WEBGL[map.magFilter],
6081      minFilter: THREE_TO_WEBGL[map.minFilter],
6082      wrapS: THREE_TO_WEBGL[map.wrapS],
6083      wrapT: THREE_TO_WEBGL[map.wrapT]
6084    };
6085    return json.samplers.push(samplerDef) - 1;
6086  }
6087  /**
6088   * Process texture
6089   * @param  {Texture} map Map to process
6090   * @return {Integer} Index of the processed texture in the "textures" array
6091   */
6092  processTexture(map) {
6093    const writer = this;
6094    const options = writer.options;
6095    const cache = this.cache;
6096    const json = this.json;
6097    if (cache.textures.has(map))
6098      return cache.textures.get(map);
6099    if (!json.textures)
6100      json.textures = [];
6101    if (map instanceof CompressedTexture) {
6102      map = decompress(map, options.maxTextureSize);
6103    }
6104    let mimeType = map.userData.mimeType;
6105    if (mimeType === "image/webp")
6106      mimeType = "image/png";
6107    const textureDef = {
6108      sampler: this.processSampler(map),
6109      source: this.processImage(map.image, map.format, map.flipY, mimeType)
6110    };
6111    if (map.name)
6112      textureDef.name = map.name;
6113    this._invokeAll(function(ext) {
6114      ext.writeTexture && ext.writeTexture(map, textureDef);
6115    });
6116    const index = json.textures.push(textureDef) - 1;
6117    cache.textures.set(map, index);
6118    return index;
6119  }
6120  /**
6121   * Process material
6122   * @param  {THREE.Material} material Material to process
6123   * @return {Integer|null} Index of the processed material in the "materials" array
6124   */
6125  processMaterial(material) {
6126    const cache = this.cache;
6127    const json = this.json;
6128    if (cache.materials.has(material))
6129      return cache.materials.get(material);
6130    if (material.isShaderMaterial) {
6131      console.warn("GLTFExporter: THREE.ShaderMaterial not supported.");
6132      return null;
6133    }
6134    if (!json.materials)
6135      json.materials = [];
6136    const materialDef = { pbrMetallicRoughness: {} };
6137    if (material.isMeshStandardMaterial !== true && material.isMeshBasicMaterial !== true) {
6138      console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");
6139    }
6140    const color = material.color.toArray().concat([material.opacity]);
6141    if (!equalArray(color, [1, 1, 1, 1])) {
6142      materialDef.pbrMetallicRoughness.baseColorFactor = color;
6143    }
6144    if (material.isMeshStandardMaterial) {
6145      materialDef.pbrMetallicRoughness.metallicFactor = material.metalness;
6146      materialDef.pbrMetallicRoughness.roughnessFactor = material.roughness;
6147    } else {
6148      materialDef.pbrMetallicRoughness.metallicFactor = 0.5;
6149      materialDef.pbrMetallicRoughness.roughnessFactor = 0.5;
6150    }
6151    if (material.metalnessMap || material.roughnessMap) {
6152      const metalRoughTexture = this.buildMetalRoughTexture(material.metalnessMap, material.roughnessMap);
6153      const metalRoughMapDef = {
6154        index: this.processTexture(metalRoughTexture),
6155        channel: metalRoughTexture.channel
6156      };
6157      this.applyTextureTransform(metalRoughMapDef, metalRoughTexture);
6158      materialDef.pbrMetallicRoughness.metallicRoughnessTexture = metalRoughMapDef;
6159    }
6160    if (material.map) {
6161      const baseColorMapDef = {
6162        index: this.processTexture(material.map),
6163        texCoord: material.map.channel
6164      };
6165      this.applyTextureTransform(baseColorMapDef, material.map);
6166      materialDef.pbrMetallicRoughness.baseColorTexture = baseColorMapDef;
6167    }
6168    if (material.emissive) {
6169      const emissive = material.emissive;
6170      const maxEmissiveComponent = Math.max(emissive.r, emissive.g, emissive.b);
6171      if (maxEmissiveComponent > 0) {
6172        materialDef.emissiveFactor = material.emissive.toArray();
6173      }
6174      if (material.emissiveMap) {
6175        const emissiveMapDef = {
6176          index: this.processTexture(material.emissiveMap),
6177          texCoord: material.emissiveMap.channel
6178        };
6179        this.applyTextureTransform(emissiveMapDef, material.emissiveMap);
6180        materialDef.emissiveTexture = emissiveMapDef;
6181      }
6182    }
6183    if (material.normalMap) {
6184      const normalMapDef = {
6185        index: this.processTexture(material.normalMap),
6186        texCoord: material.normalMap.channel
6187      };
6188      if (material.normalScale && material.normalScale.x !== 1) {
6189        normalMapDef.scale = material.normalScale.x;
6190      }
6191      this.applyTextureTransform(normalMapDef, material.normalMap);
6192      materialDef.normalTexture = normalMapDef;
6193    }
6194    if (material.aoMap) {
6195      const occlusionMapDef = {
6196        index: this.processTexture(material.aoMap),
6197        texCoord: material.aoMap.channel
6198      };
6199      if (material.aoMapIntensity !== 1) {
6200        occlusionMapDef.strength = material.aoMapIntensity;
6201      }
6202      this.applyTextureTransform(occlusionMapDef, material.aoMap);
6203      materialDef.occlusionTexture = occlusionMapDef;
6204    }
6205    if (material.transparent) {
6206      materialDef.alphaMode = "BLEND";
6207    } else {
6208      if (material.alphaTest > 0) {
6209        materialDef.alphaMode = "MASK";
6210        materialDef.alphaCutoff = material.alphaTest;
6211      }
6212    }
6213    if (material.side === DoubleSide)
6214      materialDef.doubleSided = true;
6215    if (material.name !== "")
6216      materialDef.name = material.name;
6217    this.serializeUserData(material, materialDef);
6218    this._invokeAll(function(ext) {
6219      ext.writeMaterial && ext.writeMaterial(material, materialDef);
6220    });
6221    const index = json.materials.push(materialDef) - 1;
6222    cache.materials.set(material, index);
6223    return index;
6224  }
6225  /**
6226   * Process mesh
6227   * @param  {THREE.Mesh} mesh Mesh to process
6228   * @return {Integer|null} Index of the processed mesh in the "meshes" array
6229   */
6230  processMesh(mesh) {
6231    const cache = this.cache;
6232    const json = this.json;
6233    const meshCacheKeyParts = [mesh.geometry.uuid];
6234    if (Array.isArray(mesh.material)) {
6235      for (let i = 0, l = mesh.material.length; i < l; i++) {
6236        meshCacheKeyParts.push(mesh.material[i].uuid);
6237      }
6238    } else {
6239      meshCacheKeyParts.push(mesh.material.uuid);
6240    }
6241    const meshCacheKey = meshCacheKeyParts.join(":");
6242    if (cache.meshes.has(meshCacheKey))
6243      return cache.meshes.get(meshCacheKey);
6244    const geometry = mesh.geometry;
6245    let mode;
6246    if (mesh.isLineSegments) {
6247      mode = WEBGL_CONSTANTS2.LINES;
6248    } else if (mesh.isLineLoop) {
6249      mode = WEBGL_CONSTANTS2.LINE_LOOP;
6250    } else if (mesh.isLine) {
6251      mode = WEBGL_CONSTANTS2.LINE_STRIP;
6252    } else if (mesh.isPoints) {
6253      mode = WEBGL_CONSTANTS2.POINTS;
6254    } else {
6255      mode = mesh.material.wireframe ? WEBGL_CONSTANTS2.LINES : WEBGL_CONSTANTS2.TRIANGLES;
6256    }
6257    const meshDef = {};
6258    const attributes = {};
6259    const primitives = [];
6260    const targets = [];
6261    const nameConversion = {
6262      ...version >= 152 ? {
6263        uv: "TEXCOORD_0",
6264        uv1: "TEXCOORD_1",
6265        uv2: "TEXCOORD_2",
6266        uv3: "TEXCOORD_3"
6267      } : {
6268        uv: "TEXCOORD_0",
6269        uv2: "TEXCOORD_1"
6270      },
6271      color: "COLOR_0",
6272      skinWeight: "WEIGHTS_0",
6273      skinIndex: "JOINTS_0"
6274    };
6275    const originalNormal = geometry.getAttribute("normal");
6276    if (originalNormal !== void 0 && !this.isNormalizedNormalAttribute(originalNormal)) {
6277      console.warn("THREE.GLTFExporter: Creating normalized normal attribute from the non-normalized one.");
6278      geometry.setAttribute("normal", this.createNormalizedNormalAttribute(originalNormal));
6279    }
6280    let modifiedAttribute = null;
6281    for (let attributeName in geometry.attributes) {
6282      if (attributeName.slice(0, 5) === "morph")
6283        continue;
6284      const attribute = geometry.attributes[attributeName];
6285      attributeName = nameConversion[attributeName] || attributeName.toUpperCase();
6286      const validVertexAttributes = /^(POSITION|NORMAL|TANGENT|TEXCOORD_\d+|COLOR_\d+|JOINTS_\d+|WEIGHTS_\d+)$/;
6287      if (!validVertexAttributes.test(attributeName))
6288        attributeName = "_" + attributeName;
6289      if (cache.attributes.has(this.getUID(attribute))) {
6290        attributes[attributeName] = cache.attributes.get(this.getUID(attribute));
6291        continue;
6292      }
6293      modifiedAttribute = null;
6294      const array = attribute.array;
6295      if (attributeName === "JOINTS_0" && !(array instanceof Uint16Array) && !(array instanceof Uint8Array)) {
6296        console.warn('GLTFExporter: Attribute "skinIndex" converted to type UNSIGNED_SHORT.');
6297        modifiedAttribute = new BufferAttribute(new Uint16Array(array), attribute.itemSize, attribute.normalized);
6298      }
6299      const accessor = this.processAccessor(modifiedAttribute || attribute, geometry);
6300      if (accessor !== null) {
6301        if (!attributeName.startsWith("_")) {
6302          this.detectMeshQuantization(attributeName, attribute);
6303        }
6304        attributes[attributeName] = accessor;
6305        cache.attributes.set(this.getUID(attribute), accessor);
6306      }
6307    }
6308    if (originalNormal !== void 0)
6309      geometry.setAttribute("normal", originalNormal);
6310    if (Object.keys(attributes).length === 0)
6311      return null;
6312    if (mesh.morphTargetInfluences !== void 0 && mesh.morphTargetInfluences.length > 0) {
6313      const weights = [];
6314      const targetNames = [];
6315      const reverseDictionary = {};
6316      if (mesh.morphTargetDictionary !== void 0) {
6317        for (const key in mesh.morphTargetDictionary) {
6318          reverseDictionary[mesh.morphTargetDictionary[key]] = key;
6319        }
6320      }
6321      for (let i = 0; i < mesh.morphTargetInfluences.length; ++i) {
6322        const target = {};
6323        let warned = false;
6324        for (const attributeName in geometry.morphAttributes) {
6325          if (attributeName !== "position" && attributeName !== "normal") {
6326            if (!warned) {
6327              console.warn("GLTFExporter: Only POSITION and NORMAL morph are supported.");
6328              warned = true;
6329            }
6330            continue;
6331          }
6332          const attribute = geometry.morphAttributes[attributeName][i];
6333          const gltfAttributeName = attributeName.toUpperCase();
6334          const baseAttribute = geometry.attributes[attributeName];
6335          if (cache.attributes.has(this.getUID(attribute, true))) {
6336            target[gltfAttributeName] = cache.attributes.get(this.getUID(attribute, true));
6337            continue;
6338          }
6339          const relativeAttribute = attribute.clone();
6340          if (!geometry.morphTargetsRelative) {
6341            for (let j = 0, jl = attribute.count; j < jl; j++) {
6342              for (let a = 0; a < attribute.itemSize; a++) {
6343                if (a === 0)
6344                  relativeAttribute.setX(j, attribute.getX(j) - baseAttribute.getX(j));
6345                if (a === 1)
6346                  relativeAttribute.setY(j, attribute.getY(j) - baseAttribute.getY(j));
6347                if (a === 2)
6348                  relativeAttribute.setZ(j, attribute.getZ(j) - baseAttribute.getZ(j));
6349                if (a === 3)
6350                  relativeAttribute.setW(j, attribute.getW(j) - baseAttribute.getW(j));
6351              }
6352            }
6353          }
6354          target[gltfAttributeName] = this.processAccessor(relativeAttribute, geometry);
6355          cache.attributes.set(this.getUID(baseAttribute, true), target[gltfAttributeName]);
6356        }
6357        targets.push(target);
6358        weights.push(mesh.morphTargetInfluences[i]);
6359        if (mesh.morphTargetDictionary !== void 0)
6360          targetNames.push(reverseDictionary[i]);
6361      }
6362      meshDef.weights = weights;
6363      if (targetNames.length > 0) {
6364        meshDef.extras = {};
6365        meshDef.extras.targetNames = targetNames;
6366      }
6367    }
6368    const isMultiMaterial = Array.isArray(mesh.material);
6369    if (isMultiMaterial && geometry.groups.length === 0)
6370      return null;
6371    const materials = isMultiMaterial ? mesh.material : [mesh.material];
6372    const groups = isMultiMaterial ? geometry.groups : [{ materialIndex: 0, start: void 0, count: void 0 }];
6373    for (let i = 0, il = groups.length; i < il; i++) {
6374      const primitive = {
6375        mode,
6376        attributes
6377      };
6378      this.serializeUserData(geometry, primitive);
6379      if (targets.length > 0)
6380        primitive.targets = targets;
6381      if (geometry.index !== null) {
6382        let cacheKey = this.getUID(geometry.index);
6383        if (groups[i].start !== void 0 || groups[i].count !== void 0) {
6384          cacheKey += ":" + groups[i].start + ":" + groups[i].count;
6385        }
6386        if (cache.attributes.has(cacheKey)) {
6387          primitive.indices = cache.attributes.get(cacheKey);
6388        } else {
6389          primitive.indices = this.processAccessor(geometry.index, geometry, groups[i].start, groups[i].count);
6390          cache.attributes.set(cacheKey, primitive.indices);
6391        }
6392        if (primitive.indices === null)
6393          delete primitive.indices;
6394      }
6395      const material = this.processMaterial(materials[groups[i].materialIndex]);
6396      if (material !== null)
6397        primitive.material = material;
6398      primitives.push(primitive);
6399    }
6400    meshDef.primitives = primitives;
6401    if (!json.meshes)
6402      json.meshes = [];
6403    this._invokeAll(function(ext) {
6404      ext.writeMesh && ext.writeMesh(mesh, meshDef);
6405    });
6406    const index = json.meshes.push(meshDef) - 1;
6407    cache.meshes.set(meshCacheKey, index);
6408    return index;
6409  }
6410  /**
6411   * If a vertex attribute with a
6412   * [non-standard data type](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview)
6413   * is used, it is checked whether it is a valid data type according to the
6414   * [KHR_mesh_quantization](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_mesh_quantization/README.md)
6415   * extension.
6416   * In this case the extension is automatically added to the list of used extensions.
6417   *
6418   * @param {string} attributeName
6419   * @param {THREE.BufferAttribute} attribute
6420   */
6421  detectMeshQuantization(attributeName, attribute) {
6422    if (this.extensionsUsed[KHR_MESH_QUANTIZATION])
6423      return;
6424    let attrType = void 0;
6425    switch (attribute.array.constructor) {
6426      case Int8Array:
6427        attrType = "byte";
6428        break;
6429      case Uint8Array:
6430        attrType = "unsigned byte";
6431        break;
6432      case Int16Array:
6433        attrType = "short";
6434        break;
6435      case Uint16Array:
6436        attrType = "unsigned short";
6437        break;
6438      default:
6439        return;
6440    }
6441    if (attribute.normalized)
6442      attrType += " normalized";
6443    const attrNamePrefix = attributeName.split("_", 1)[0];
6444    if (KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix] && KHR_mesh_quantization_ExtraAttrTypes[attrNamePrefix].includes(attrType)) {
6445      this.extensionsUsed[KHR_MESH_QUANTIZATION] = true;
6446      this.extensionsRequired[KHR_MESH_QUANTIZATION] = true;
6447    }
6448  }
6449  /**
6450   * Process camera
6451   * @param  {THREE.Camera} camera Camera to process
6452   * @return {Integer}      Index of the processed mesh in the "camera" array
6453   */
6454  processCamera(camera) {
6455    const json = this.json;
6456    if (!json.cameras)
6457      json.cameras = [];
6458    const isOrtho = camera.isOrthographicCamera;
6459    const cameraDef = {
6460      type: isOrtho ? "orthographic" : "perspective"
6461    };
6462    if (isOrtho) {
6463      cameraDef.orthographic = {
6464        xmag: camera.right * 2,
6465        ymag: camera.top * 2,
6466        zfar: camera.far <= 0 ? 1e-3 : camera.far,
6467        znear: camera.near < 0 ? 0 : camera.near
6468      };
6469    } else {
6470      cameraDef.perspective = {
6471        aspectRatio: camera.aspect,
6472        yfov: MathUtils.degToRad(camera.fov),
6473        zfar: camera.far <= 0 ? 1e-3 : camera.far,
6474        znear: camera.near < 0 ? 0 : camera.near
6475      };
6476    }
6477    if (camera.name !== "")
6478      cameraDef.name = camera.type;
6479    return json.cameras.push(cameraDef) - 1;
6480  }
6481  /**
6482   * Creates glTF animation entry from AnimationClip object.
6483   *
6484   * Status:
6485   * - Only properties listed in PATH_PROPERTIES may be animated.
6486   *
6487   * @param {THREE.AnimationClip} clip
6488   * @param {THREE.Object3D} root
6489   * @return {number|null}
6490   */
6491  processAnimation(clip, root) {
6492    const json = this.json;
6493    const nodeMap = this.nodeMap;
6494    if (!json.animations)
6495      json.animations = [];
6496    clip = GLTFExporter.Utils.mergeMorphTargetTracks(clip.clone(), root);
6497    const tracks = clip.tracks;
6498    const channels = [];
6499    const samplers = [];
6500    for (let i = 0; i < tracks.length; ++i) {
6501      const track = tracks[i];
6502      const trackBinding = PropertyBinding.parseTrackName(track.name);
6503      let trackNode = PropertyBinding.findNode(root, trackBinding.nodeName);
6504      const trackProperty = PATH_PROPERTIES2[trackBinding.propertyName];
6505      if (trackBinding.objectName === "bones") {
6506        if (trackNode.isSkinnedMesh === true) {
6507          trackNode = trackNode.skeleton.getBoneByName(trackBinding.objectIndex);
6508        } else {
6509          trackNode = void 0;
6510        }
6511      }
6512      if (!trackNode || !trackProperty) {
6513        console.warn('THREE.GLTFExporter: Could not export animation track "%s".', track.name);
6514        return null;
6515      }
6516      const inputItemSize = 1;
6517      let outputItemSize = track.values.length / track.times.length;
6518      if (trackProperty === PATH_PROPERTIES2.morphTargetInfluences) {
6519        outputItemSize /= trackNode.morphTargetInfluences.length;
6520      }
6521      let interpolation;
6522      if (track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline === true) {
6523        interpolation = "CUBICSPLINE";
6524        outputItemSize /= 3;
6525      } else if (track.getInterpolation() === InterpolateDiscrete) {
6526        interpolation = "STEP";
6527      } else {
6528        interpolation = "LINEAR";
6529      }
6530      samplers.push({
6531        input: this.processAccessor(new BufferAttribute(track.times, inputItemSize)),
6532        output: this.processAccessor(new BufferAttribute(track.values, outputItemSize)),
6533        interpolation
6534      });
6535      channels.push({
6536        sampler: samplers.length - 1,
6537        target: {
6538          node: nodeMap.get(trackNode),
6539          path: trackProperty
6540        }
6541      });
6542    }
6543    json.animations.push({
6544      name: clip.name || "clip_" + json.animations.length,
6545      samplers,
6546      channels
6547    });
6548    return json.animations.length - 1;
6549  }
6550  /**
6551   * @param {THREE.Object3D} object
6552   * @return {number|null}
6553   */
6554  processSkin(object) {
6555    const json = this.json;
6556    const nodeMap = this.nodeMap;
6557    const node = json.nodes[nodeMap.get(object)];
6558    const skeleton = object.skeleton;
6559    if (skeleton === void 0)
6560      return null;
6561    const rootJoint = object.skeleton.bones[0];
6562    if (rootJoint === void 0)
6563      return null;
6564    const joints = [];
6565    const inverseBindMatrices = new Float32Array(skeleton.bones.length * 16);
6566    const temporaryBoneInverse = new Matrix4();
6567    for (let i = 0; i < skeleton.bones.length; ++i) {
6568      joints.push(nodeMap.get(skeleton.bones[i]));
6569      temporaryBoneInverse.copy(skeleton.boneInverses[i]);
6570      temporaryBoneInverse.multiply(object.bindMatrix).toArray(inverseBindMatrices, i * 16);
6571    }
6572    if (json.skins === void 0)
6573      json.skins = [];
6574    json.skins.push({
6575      inverseBindMatrices: this.processAccessor(new BufferAttribute(inverseBindMatrices, 16)),
6576      joints,
6577      skeleton: nodeMap.get(rootJoint)
6578    });
6579    const skinIndex = node.skin = json.skins.length - 1;
6580    return skinIndex;
6581  }
6582  /**
6583   * Process Object3D node
6584   * @param  {THREE.Object3D} node Object3D to processNode
6585   * @return {Integer} Index of the node in the nodes list
6586   */
6587  processNode(object) {
6588    const json = this.json;
6589    const options = this.options;
6590    const nodeMap = this.nodeMap;
6591    if (!json.nodes)
6592      json.nodes = [];
6593    const nodeDef = {};
6594    if (options.trs) {
6595      const rotation = object.quaternion.toArray();
6596      const position2 = object.position.toArray();
6597      const scale = object.scale.toArray();
6598      if (!equalArray(rotation, [0, 0, 0, 1])) {
6599        nodeDef.rotation = rotation;
6600      }
6601      if (!equalArray(position2, [0, 0, 0])) {
6602        nodeDef.translation = position2;
6603      }
6604      if (!equalArray(scale, [1, 1, 1])) {
6605        nodeDef.scale = scale;
6606      }
6607    } else {
6608      if (object.matrixAutoUpdate) {
6609        object.updateMatrix();
6610      }
6611      if (isIdentityMatrix(object.matrix) === false) {
6612        nodeDef.matrix = object.matrix.elements;
6613      }
6614    }
6615    if (object.name !== "")
6616      nodeDef.name = String(object.name);
6617    this.serializeUserData(object, nodeDef);
6618    if (object.isMesh || object.isLine || object.isPoints) {
6619      const meshIndex = this.processMesh(object);
6620      if (meshIndex !== null)
6621        nodeDef.mesh = meshIndex;
6622    } else if (object.isCamera) {
6623      nodeDef.camera = this.processCamera(object);
6624    }
6625    if (object.isSkinnedMesh)
6626      this.skins.push(object);
6627    if (object.children.length > 0) {
6628      const children2 = [];
6629      for (let i = 0, l = object.children.length; i < l; i++) {
6630        const child = object.children[i];
6631        if (child.visible || options.onlyVisible === false) {
6632          const nodeIndex2 = this.processNode(child);
6633          if (nodeIndex2 !== null)
6634            children2.push(nodeIndex2);
6635        }
6636      }
6637      if (children2.length > 0)
6638        nodeDef.children = children2;
6639    }
6640    this._invokeAll(function(ext) {
6641      ext.writeNode && ext.writeNode(object, nodeDef);
6642    });
6643    const nodeIndex = json.nodes.push(nodeDef) - 1;
6644    nodeMap.set(object, nodeIndex);
6645    return nodeIndex;
6646  }
6647  /**
6648   * Process Scene
6649   * @param  {Scene} node Scene to process
6650   */
6651  processScene(scene) {
6652    const json = this.json;
6653    const options = this.options;
6654    if (!json.scenes) {
6655      json.scenes = [];
6656      json.scene = 0;
6657    }
6658    const sceneDef = {};
6659    if (scene.name !== "")
6660      sceneDef.name = scene.name;
6661    json.scenes.push(sceneDef);
6662    const nodes = [];
6663    for (let i = 0, l = scene.children.length; i < l; i++) {
6664      const child = scene.children[i];
6665      if (child.visible || options.onlyVisible === false) {
6666        const nodeIndex = this.processNode(child);
6667        if (nodeIndex !== null)
6668          nodes.push(nodeIndex);
6669      }
6670    }
6671    if (nodes.length > 0)
6672      sceneDef.nodes = nodes;
6673    this.serializeUserData(scene, sceneDef);
6674  }
6675  /**
6676   * Creates a Scene to hold a list of objects and parse it
6677   * @param  {Array} objects List of objects to process
6678   */
6679  processObjects(objects) {
6680    const scene = new Scene();
6681    scene.name = "AuxScene";
6682    for (let i = 0; i < objects.length; i++) {
6683      scene.children.push(objects[i]);
6684    }
6685    this.processScene(scene);
6686  }
6687  /**
6688   * @param {THREE.Object3D|Array<THREE.Object3D>} input
6689   */
6690  processInput(input) {
6691    const options = this.options;
6692    input = input instanceof Array ? input : [input];
6693    this._invokeAll(function(ext) {
6694      ext.beforeParse && ext.beforeParse(input);
6695    });
6696    const objectsWithoutScene = [];
6697    for (let i = 0; i < input.length; i++) {
6698      if (input[i] instanceof Scene) {
6699        this.processScene(input[i]);
6700      } else {
6701        objectsWithoutScene.push(input[i]);
6702      }
6703    }
6704    if (objectsWithoutScene.length > 0)
6705      this.processObjects(objectsWithoutScene);
6706    for (let i = 0; i < this.skins.length; ++i) {
6707      this.processSkin(this.skins[i]);
6708    }
6709    for (let i = 0; i < options.animations.length; ++i) {
6710      this.processAnimation(options.animations[i], input[0]);
6711    }
6712    this._invokeAll(function(ext) {
6713      ext.afterParse && ext.afterParse(input);
6714    });
6715  }
6716  _invokeAll(func) {
6717    for (let i = 0, il = this.plugins.length; i < il; i++) {
6718      func(this.plugins[i]);
6719    }
6720  }
6721};
6722var GLTFLightExtension = class {
6723  constructor(writer) {
6724    this.writer = writer;
6725    this.name = "KHR_lights_punctual";
6726  }
6727  writeNode(light, nodeDef) {
6728    if (!light.isLight)
6729      return;
6730    if (!light.isDirectionalLight && !light.isPointLight && !light.isSpotLight) {
6731      console.warn("THREE.GLTFExporter: Only directional, point, and spot lights are supported.", light);
6732      return;
6733    }
6734    const writer = this.writer;
6735    const json = writer.json;
6736    const extensionsUsed = writer.extensionsUsed;
6737    const lightDef = {};
6738    if (light.name)
6739      lightDef.name = light.name;
6740    lightDef.color = light.color.toArray();
6741    lightDef.intensity = light.intensity;
6742    if (light.isDirectionalLight) {
6743      lightDef.type = "directional";
6744    } else if (light.isPointLight) {
6745      lightDef.type = "point";
6746      if (light.distance > 0)
6747        lightDef.range = light.distance;
6748    } else if (light.isSpotLight) {
6749      lightDef.type = "spot";
6750      if (light.distance > 0)
6751        lightDef.range = light.distance;
6752      lightDef.spot = {};
6753      lightDef.spot.innerConeAngle = (light.penumbra - 1) * light.angle * -1;
6754      lightDef.spot.outerConeAngle = light.angle;
6755    }
6756    if (light.decay !== void 0 && light.decay !== 2) {
6757      console.warn(
6758        "THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2."
6759      );
6760    }
6761    if (light.target && (light.target.parent !== light || light.target.position.x !== 0 || light.target.position.y !== 0 || light.target.position.z !== -1)) {
6762      console.warn(
6763        "THREE.GLTFExporter: Light direction may be lost. For best results, make light.target a child of the light with position 0,0,-1."
6764      );
6765    }
6766    if (!extensionsUsed[this.name]) {
6767      json.extensions = json.extensions || {};
6768      json.extensions[this.name] = { lights: [] };
6769      extensionsUsed[this.name] = true;
6770    }
6771    const lights = json.extensions[this.name].lights;
6772    lights.push(lightDef);
6773    nodeDef.extensions = nodeDef.extensions || {};
6774    nodeDef.extensions[this.name] = { light: lights.length - 1 };
6775  }
6776};
6777var GLTFMaterialsUnlitExtension2 = class {
6778  constructor(writer) {
6779    this.writer = writer;
6780    this.name = "KHR_materials_unlit";
6781  }
6782  writeMaterial(material, materialDef) {
6783    if (!material.isMeshBasicMaterial)
6784      return;
6785    const writer = this.writer;
6786    const extensionsUsed = writer.extensionsUsed;
6787    materialDef.extensions = materialDef.extensions || {};
6788    materialDef.extensions[this.name] = {};
6789    extensionsUsed[this.name] = true;
6790    materialDef.pbrMetallicRoughness.metallicFactor = 0;
6791    materialDef.pbrMetallicRoughness.roughnessFactor = 0.9;
6792  }
6793};
6794var GLTFMaterialsClearcoatExtension2 = class {
6795  constructor(writer) {
6796    this.writer = writer;
6797    this.name = "KHR_materials_clearcoat";
6798  }
6799  writeMaterial(material, materialDef) {
6800    if (!material.isMeshPhysicalMaterial || material.clearcoat === 0)
6801      return;
6802    const writer = this.writer;
6803    const extensionsUsed = writer.extensionsUsed;
6804    const extensionDef = {};
6805    extensionDef.clearcoatFactor = material.clearcoat;
6806    if (material.clearcoatMap) {
6807      const clearcoatMapDef = {
6808        index: writer.processTexture(material.clearcoatMap),
6809        texCoord: material.clearcoatMap.channel
6810      };
6811      writer.applyTextureTransform(clearcoatMapDef, material.clearcoatMap);
6812      extensionDef.clearcoatTexture = clearcoatMapDef;
6813    }
6814    extensionDef.clearcoatRoughnessFactor = material.clearcoatRoughness;
6815    if (material.clearcoatRoughnessMap) {
6816      const clearcoatRoughnessMapDef = {
6817        index: writer.processTexture(material.clearcoatRoughnessMap),
6818        texCoord: material.clearcoatRoughnessMap.channel
6819      };
6820      writer.applyTextureTransform(clearcoatRoughnessMapDef, material.clearcoatRoughnessMap);
6821      extensionDef.clearcoatRoughnessTexture = clearcoatRoughnessMapDef;
6822    }
6823    if (material.clearcoatNormalMap) {
6824      const clearcoatNormalMapDef = {
6825        index: writer.processTexture(material.clearcoatNormalMap),
6826        texCoord: material.clearcoatNormalMap.channel
6827      };
6828      writer.applyTextureTransform(clearcoatNormalMapDef, material.clearcoatNormalMap);
6829      extensionDef.clearcoatNormalTexture = clearcoatNormalMapDef;
6830    }
6831    materialDef.extensions = materialDef.extensions || {};
6832    materialDef.extensions[this.name] = extensionDef;
6833    extensionsUsed[this.name] = true;
6834  }
6835};
6836var GLTFMaterialsIridescenceExtension2 = class {
6837  constructor(writer) {
6838    this.writer = writer;
6839    this.name = "KHR_materials_iridescence";
6840  }
6841  writeMaterial(material, materialDef) {
6842    if (!material.isMeshPhysicalMaterial || material.iridescence === 0)
6843      return;
6844    const writer = this.writer;
6845    const extensionsUsed = writer.extensionsUsed;
6846    const extensionDef = {};
6847    extensionDef.iridescenceFactor = material.iridescence;
6848    if (material.iridescenceMap) {
6849      const iridescenceMapDef = {
6850        index: writer.processTexture(material.iridescenceMap),
6851        texCoord: material.iridescenceMap.channel
6852      };
6853      writer.applyTextureTransform(iridescenceMapDef, material.iridescenceMap);
6854      extensionDef.iridescenceTexture = iridescenceMapDef;
6855    }
6856    extensionDef.iridescenceIor = material.iridescenceIOR;
6857    extensionDef.iridescenceThicknessMinimum = material.iridescenceThicknessRange[0];
6858    extensionDef.iridescenceThicknessMaximum = material.iridescenceThicknessRange[1];
6859    if (material.iridescenceThicknessMap) {
6860      const iridescenceThicknessMapDef = {
6861        index: writer.processTexture(material.iridescenceThicknessMap),
6862        texCoord: material.iridescenceThicknessMap.channel
6863      };
6864      writer.applyTextureTransform(iridescenceThicknessMapDef, material.iridescenceThicknessMap);
6865      extensionDef.iridescenceThicknessTexture = iridescenceThicknessMapDef;
6866    }
6867    materialDef.extensions = materialDef.extensions || {};
6868    materialDef.extensions[this.name] = extensionDef;
6869    extensionsUsed[this.name] = true;
6870  }
6871};
6872var GLTFMaterialsTransmissionExtension2 = class {
6873  constructor(writer) {
6874    this.writer = writer;
6875    this.name = "KHR_materials_transmission";
6876  }
6877  writeMaterial(material, materialDef) {
6878    if (!material.isMeshPhysicalMaterial || material.transmission === 0)
6879      return;
6880    const writer = this.writer;
6881    const extensionsUsed = writer.extensionsUsed;
6882    const extensionDef = {};
6883    extensionDef.transmissionFactor = material.transmission;
6884    if (material.transmissionMap) {
6885      const transmissionMapDef = {
6886        index: writer.processTexture(material.transmissionMap),
6887        texCoord: material.transmissionMap.channel
6888      };
6889      writer.applyTextureTransform(transmissionMapDef, material.transmissionMap);
6890      extensionDef.transmissionTexture = transmissionMapDef;
6891    }
6892    materialDef.extensions = materialDef.extensions || {};
6893    materialDef.extensions[this.name] = extensionDef;
6894    extensionsUsed[this.name] = true;
6895  }
6896};
6897var GLTFMaterialsVolumeExtension2 = class {
6898  constructor(writer) {
6899    this.writer = writer;
6900    this.name = "KHR_materials_volume";
6901  }
6902  writeMaterial(material, materialDef) {
6903    if (!material.isMeshPhysicalMaterial || material.transmission === 0)
6904      return;
6905    const writer = this.writer;
6906    const extensionsUsed = writer.extensionsUsed;
6907    const extensionDef = {};
6908    extensionDef.thicknessFactor = material.thickness;
6909    if (material.thicknessMap) {
6910      const thicknessMapDef = {
6911        index: writer.processTexture(material.thicknessMap),
6912        texCoord: material.thicknessMap.channel
6913      };
6914      writer.applyTextureTransform(thicknessMapDef, material.thicknessMap);
6915      extensionDef.thicknessTexture = thicknessMapDef;
6916    }
6917    extensionDef.attenuationDistance = material.attenuationDistance;
6918    extensionDef.attenuationColor = material.attenuationColor.toArray();
6919    materialDef.extensions = materialDef.extensions || {};
6920    materialDef.extensions[this.name] = extensionDef;
6921    extensionsUsed[this.name] = true;
6922  }
6923};
6924var GLTFMaterialsIorExtension2 = class {
6925  constructor(writer) {
6926    this.writer = writer;
6927    this.name = "KHR_materials_ior";
6928  }
6929  writeMaterial(material, materialDef) {
6930    if (!material.isMeshPhysicalMaterial || material.ior === 1.5)
6931      return;
6932    const writer = this.writer;
6933    const extensionsUsed = writer.extensionsUsed;
6934    const extensionDef = {};
6935    extensionDef.ior = material.ior;
6936    materialDef.extensions = materialDef.extensions || {};
6937    materialDef.extensions[this.name] = extensionDef;
6938    extensionsUsed[this.name] = true;
6939  }
6940};
6941var GLTFMaterialsSpecularExtension2 = class {
6942  constructor(writer) {
6943    this.writer = writer;
6944    this.name = "KHR_materials_specular";
6945  }
6946  writeMaterial(material, materialDef) {
6947    if (!material.isMeshPhysicalMaterial || material.specularIntensity === 1 && material.specularColor.equals(DEFAULT_SPECULAR_COLOR) && !material.specularIntensityMap && !material.specularColorTexture)
6948      return;
6949    const writer = this.writer;
6950    const extensionsUsed = writer.extensionsUsed;
6951    const extensionDef = {};
6952    if (material.specularIntensityMap) {
6953      const specularIntensityMapDef = {
6954        index: writer.processTexture(material.specularIntensityMap),
6955        texCoord: material.specularIntensityMap.channel
6956      };
6957      writer.applyTextureTransform(specularIntensityMapDef, material.specularIntensityMap);
6958      extensionDef.specularTexture = specularIntensityMapDef;
6959    }
6960    if (material.specularColorMap) {
6961      const specularColorMapDef = {
6962        index: writer.processTexture(material.specularColorMap),
6963        texCoord: material.specularColorMap.channel
6964      };
6965      writer.applyTextureTransform(specularColorMapDef, material.specularColorMap);
6966      extensionDef.specularColorTexture = specularColorMapDef;
6967    }
6968    extensionDef.specularFactor = material.specularIntensity;
6969    extensionDef.specularColorFactor = material.specularColor.toArray();
6970    materialDef.extensions = materialDef.extensions || {};
6971    materialDef.extensions[this.name] = extensionDef;
6972    extensionsUsed[this.name] = true;
6973  }
6974};
6975var GLTFMaterialsSheenExtension2 = class {
6976  constructor(writer) {
6977    this.writer = writer;
6978    this.name = "KHR_materials_sheen";
6979  }
6980  writeMaterial(material, materialDef) {
6981    if (!material.isMeshPhysicalMaterial || material.sheen == 0)
6982      return;
6983    const writer = this.writer;
6984    const extensionsUsed = writer.extensionsUsed;
6985    const extensionDef = {};
6986    if (material.sheenRoughnessMap) {
6987      const sheenRoughnessMapDef = {
6988        index: writer.processTexture(material.sheenRoughnessMap),
6989        texCoord: material.sheenRoughnessMap.channel
6990      };
6991      writer.applyTextureTransform(sheenRoughnessMapDef, material.sheenRoughnessMap);
6992      extensionDef.sheenRoughnessTexture = sheenRoughnessMapDef;
6993    }
6994    if (material.sheenColorMap) {
6995      const sheenColorMapDef = {
6996        index: writer.processTexture(material.sheenColorMap),
6997        texCoord: material.sheenColorMap.channel
6998      };
6999      writer.applyTextureTransform(sheenColorMapDef, material.sheenColorMap);
7000      extensionDef.sheenColorTexture = sheenColorMapDef;
7001    }
7002    extensionDef.sheenRoughnessFactor = material.sheenRoughness;
7003    extensionDef.sheenColorFactor = material.sheenColor.toArray();
7004    materialDef.extensions = materialDef.extensions || {};
7005    materialDef.extensions[this.name] = extensionDef;
7006    extensionsUsed[this.name] = true;
7007  }
7008};
7009var GLTFMaterialsAnisotropyExtension2 = class {
7010  constructor(writer) {
7011    this.writer = writer;
7012    this.name = "KHR_materials_anisotropy";
7013  }
7014  writeMaterial(material, materialDef) {
7015    if (!material.isMeshPhysicalMaterial || material.anisotropy == 0)
7016      return;
7017    const writer = this.writer;
7018    const extensionsUsed = writer.extensionsUsed;
7019    const extensionDef = {};
7020    if (material.anisotropyMap) {
7021      const anisotropyMapDef = { index: writer.processTexture(material.anisotropyMap) };
7022      writer.applyTextureTransform(anisotropyMapDef, material.anisotropyMap);
7023      extensionDef.anisotropyTexture = anisotropyMapDef;
7024    }
7025    extensionDef.anisotropyStrength = material.anisotropy;
7026    extensionDef.anisotropyRotation = material.anisotropyRotation;
7027    materialDef.extensions = materialDef.extensions || {};
7028    materialDef.extensions[this.name] = extensionDef;
7029    extensionsUsed[this.name] = true;
7030  }
7031};
7032var GLTFMaterialsEmissiveStrengthExtension2 = class {
7033  constructor(writer) {
7034    this.writer = writer;
7035    this.name = "KHR_materials_emissive_strength";
7036  }
7037  writeMaterial(material, materialDef) {
7038    if (!material.isMeshStandardMaterial || material.emissiveIntensity === 1)
7039      return;
7040    const writer = this.writer;
7041    const extensionsUsed = writer.extensionsUsed;
7042    const extensionDef = {};
7043    extensionDef.emissiveStrength = material.emissiveIntensity;
7044    materialDef.extensions = materialDef.extensions || {};
7045    materialDef.extensions[this.name] = extensionDef;
7046    extensionsUsed[this.name] = true;
7047  }
7048};
7049
vendor: 2,432 bytes, lines 7050-7124
7050// node_modules/three-stdlib/controls/EventDispatcher.js
7051var __defProp2 = Object.defineProperty;
7052var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7053var __publicField2 = (obj, key, value) => {
7054  __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
7055  return value;
7056};
7057var EventDispatcher = class {
7058  constructor() {
7059    __publicField2(this, "_listeners");
7060  }
7061  /**
7062   * Adds a listener to an event type.
7063   * @param type The type of event to listen to.
7064   * @param listener The function that gets called when the event is fired.
7065   */
7066  addEventListener(type, listener) {
7067    if (this._listeners === void 0)
7068      this._listeners = {};
7069    const listeners = this._listeners;
7070    if (listeners[type] === void 0) {
7071      listeners[type] = [];
7072    }
7073    if (listeners[type].indexOf(listener) === -1) {
7074      listeners[type].push(listener);
7075    }
7076  }
7077  /**
7078      * Checks if listener is added to an event type.
7079      * @param type The type of event to listen to.
7080      * @param listener The function that gets called when the event is fired.
7081      */
7082  hasEventListener(type, listener) {
7083    if (this._listeners === void 0)
7084      return false;
7085    const listeners = this._listeners;
7086    return listeners[type] !== void 0 && listeners[type].indexOf(listener) !== -1;
7087  }
7088  /**
7089      * Removes a listener from an event type.
7090      * @param type The type of the listener that gets removed.
7091      * @param listener The listener function that gets removed.
7092      */
7093  removeEventListener(type, listener) {
7094    if (this._listeners === void 0)
7095      return;
7096    const listeners = this._listeners;
7097    const listenerArray = listeners[type];
7098    if (listenerArray !== void 0) {
7099      const index = listenerArray.indexOf(listener);
7100      if (index !== -1) {
7101        listenerArray.splice(index, 1);
7102      }
7103    }
7104  }
7105  /**
7106      * Fire an event type.
7107      * @param event The event that gets fired.
7108      */
7109  dispatchEvent(event) {
7110    if (this._listeners === void 0)
7111      return;
7112    const listeners = this._listeners;
7113    const listenerArray = listeners[event.type];
7114    if (listenerArray !== void 0) {
7115      event.target = this;
7116      const array = listenerArray.slice(0);
7117      for (let i = 0, l = array.length; i < l; i++) {
7118        array[i].call(this, event);
7119      }
7120      event.target = null;
7121    }
7122  }
7123};
7124
vendor: 20,995 bytes, lines 7125-7619
7125// node_modules/three-stdlib/controls/TrackballControls.js
7126var __defProp3 = Object.defineProperty;
7127var __defNormalProp3 = (obj, key, value) => key in obj ? __defProp3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7128var __publicField3 = (obj, key, value) => {
7129  __defNormalProp3(obj, typeof key !== "symbol" ? key + "" : key, value);
7130  return value;
7131};
7132var TrackballControls = class extends EventDispatcher {
7133  constructor(object, domElement) {
7134    super();
7135    __publicField3(this, "enabled", true);
7136    __publicField3(this, "screen", { left: 0, top: 0, width: 0, height: 0 });
7137    __publicField3(this, "rotateSpeed", 1);
7138    __publicField3(this, "zoomSpeed", 1.2);
7139    __publicField3(this, "panSpeed", 0.3);
7140    __publicField3(this, "noRotate", false);
7141    __publicField3(this, "noZoom", false);
7142    __publicField3(this, "noPan", false);
7143    __publicField3(this, "staticMoving", false);
7144    __publicField3(this, "dynamicDampingFactor", 0.2);
7145    __publicField3(this, "minDistance", 0);
7146    __publicField3(this, "maxDistance", Infinity);
7147    __publicField3(this, "keys", [
7148      "KeyA",
7149      "KeyS",
7150      "KeyD"
7151      /*D*/
7152    ]);
7153    __publicField3(this, "mouseButtons", {
7154      LEFT: MOUSE.ROTATE,
7155      MIDDLE: MOUSE.DOLLY,
7156      RIGHT: MOUSE.PAN
7157    });
7158    __publicField3(this, "object");
7159    __publicField3(this, "domElement");
7160    __publicField3(this, "cursorZoom", false);
7161    __publicField3(this, "target", new Vector3());
7162    __publicField3(this, "mousePosition", new Vector2());
7163    __publicField3(this, "STATE", {
7164      NONE: -1,
7165      ROTATE: 0,
7166      ZOOM: 1,
7167      PAN: 2,
7168      TOUCH_ROTATE: 3,
7169      TOUCH_ZOOM_PAN: 4
7170    });
7171    __publicField3(this, "EPS", 1e-6);
7172    __publicField3(this, "lastZoom", 1);
7173    __publicField3(this, "lastPosition", new Vector3());
7174    __publicField3(this, "cursorVector", new Vector3());
7175    __publicField3(this, "targetVector", new Vector3());
7176    __publicField3(this, "_state", this.STATE.NONE);
7177    __publicField3(this, "_keyState", this.STATE.NONE);
7178    __publicField3(this, "_eye", new Vector3());
7179    __publicField3(this, "_movePrev", new Vector2());
7180    __publicField3(this, "_moveCurr", new Vector2());
7181    __publicField3(this, "_lastAxis", new Vector3());
7182    __publicField3(this, "_lastAngle", 0);
7183    __publicField3(this, "_zoomStart", new Vector2());
7184    __publicField3(this, "_zoomEnd", new Vector2());
7185    __publicField3(this, "_touchZoomDistanceStart", 0);
7186    __publicField3(this, "_touchZoomDistanceEnd", 0);
7187    __publicField3(this, "_panStart", new Vector2());
7188    __publicField3(this, "_panEnd", new Vector2());
7189    __publicField3(this, "target0");
7190    __publicField3(this, "position0");
7191    __publicField3(this, "up0");
7192    __publicField3(this, "zoom0");
7193    __publicField3(this, "changeEvent", { type: "change" });
7194    __publicField3(this, "startEvent", { type: "start" });
7195    __publicField3(this, "endEvent", { type: "end" });
7196    __publicField3(this, "onScreenVector", new Vector2());
7197    __publicField3(this, "getMouseOnScreen", (pageX, pageY) => {
7198      this.onScreenVector.set(
7199        (pageX - this.screen.left) / this.screen.width,
7200        (pageY - this.screen.top) / this.screen.height
7201      );
7202      return this.onScreenVector;
7203    });
7204    __publicField3(this, "onCircleVector", new Vector2());
7205    __publicField3(this, "getMouseOnCircle", (pageX, pageY) => {
7206      this.onCircleVector.set(
7207        (pageX - this.screen.width * 0.5 - this.screen.left) / (this.screen.width * 0.5),
7208        (this.screen.height + 2 * (this.screen.top - pageY)) / this.screen.width
7209        // screen.width intentional
7210      );
7211      return this.onCircleVector;
7212    });
7213    __publicField3(this, "axis", new Vector3());
7214    __publicField3(this, "quaternion", new Quaternion());
7215    __publicField3(this, "eyeDirection", new Vector3());
7216    __publicField3(this, "objectUpDirection", new Vector3());
7217    __publicField3(this, "objectSidewaysDirection", new Vector3());
7218    __publicField3(this, "moveDirection", new Vector3());
7219    __publicField3(this, "angle", 0);
7220    __publicField3(this, "rotateCamera", () => {
7221      this.moveDirection.set(this._moveCurr.x - this._movePrev.x, this._moveCurr.y - this._movePrev.y, 0);
7222      this.angle = this.moveDirection.length();
7223      if (this.angle) {
7224        this._eye.copy(this.object.position).sub(this.target);
7225        this.eyeDirection.copy(this._eye).normalize();
7226        this.objectUpDirection.copy(this.object.up).normalize();
7227        this.objectSidewaysDirection.crossVectors(this.objectUpDirection, this.eyeDirection).normalize();
7228        this.objectUpDirection.setLength(this._moveCurr.y - this._movePrev.y);
7229        this.objectSidewaysDirection.setLength(this._moveCurr.x - this._movePrev.x);
7230        this.moveDirection.copy(this.objectUpDirection.add(this.objectSidewaysDirection));
7231        this.axis.crossVectors(this.moveDirection, this._eye).normalize();
7232        this.angle *= this.rotateSpeed;
7233        this.quaternion.setFromAxisAngle(this.axis, this.angle);
7234        this._eye.applyQuaternion(this.quaternion);
7235        this.object.up.applyQuaternion(this.quaternion);
7236        this._lastAxis.copy(this.axis);
7237        this._lastAngle = this.angle;
7238      } else if (!this.staticMoving && this._lastAngle) {
7239        this._lastAngle *= Math.sqrt(1 - this.dynamicDampingFactor);
7240        this._eye.copy(this.object.position).sub(this.target);
7241        this.quaternion.setFromAxisAngle(this._lastAxis, this._lastAngle);
7242        this._eye.applyQuaternion(this.quaternion);
7243        this.object.up.applyQuaternion(this.quaternion);
7244      }
7245      this._movePrev.copy(this._moveCurr);
7246    });
7247    __publicField3(this, "zoomCamera", () => {
7248      let factor;
7249      if (this._state === this.STATE.TOUCH_ZOOM_PAN) {
7250        factor = this._touchZoomDistanceStart / this._touchZoomDistanceEnd;
7251        this._touchZoomDistanceStart = this._touchZoomDistanceEnd;
7252        if (this.object.isPerspectiveCamera) {
7253          this._eye.multiplyScalar(factor);
7254        } else if (this.object.isOrthographicCamera) {
7255          this.object.zoom /= factor;
7256          this.object.updateProjectionMatrix();
7257        } else {
7258          console.warn("THREE.TrackballControls: Unsupported camera type");
7259        }
7260      } else {
7261        factor = 1 + (this._zoomEnd.y - this._zoomStart.y) * this.zoomSpeed;
7262        if (Math.abs(factor - 1) > this.EPS && factor > 0) {
7263          if (this.object.isPerspectiveCamera) {
7264            if (factor > 1 && this._eye.length() >= this.maxDistance - this.EPS) {
7265              factor = 1;
7266            }
7267            this._eye.multiplyScalar(factor);
7268          } else if (this.object.isOrthographicCamera) {
7269            if (factor > 1 && this.object.zoom < this.maxDistance * this.maxDistance) {
7270              factor = 1;
7271            }
7272            this.object.zoom /= factor;
7273          } else {
7274            console.warn("THREE.TrackballControls: Unsupported camera type");
7275          }
7276        }
7277        if (this.staticMoving) {
7278          this._zoomStart.copy(this._zoomEnd);
7279        } else {
7280          this._zoomStart.y += (this._zoomEnd.y - this._zoomStart.y) * this.dynamicDampingFactor;
7281        }
7282        if (this.cursorZoom) {
7283          this.targetVector.copy(this.target).project(this.object);
7284          let worldPos = this.cursorVector.set(this.mousePosition.x, this.mousePosition.y, this.targetVector.z).unproject(this.object);
7285          this.target.lerpVectors(worldPos, this.target, factor);
7286        }
7287        if (this.object.isOrthographicCamera) {
7288          this.object.updateProjectionMatrix();
7289        }
7290      }
7291    });
7292    __publicField3(this, "mouseChange", new Vector2());
7293    __publicField3(this, "objectUp", new Vector3());
7294    __publicField3(this, "pan", new Vector3());
7295    __publicField3(this, "panCamera", () => {
7296      if (!this.domElement)
7297        return;
7298      this.mouseChange.copy(this._panEnd).sub(this._panStart);
7299      if (this.mouseChange.lengthSq() > this.EPS) {
7300        if (this.object.isOrthographicCamera) {
7301          const orthoObject = this.object;
7302          const scale_x = (orthoObject.right - orthoObject.left) / this.object.zoom;
7303          const scale_y = (orthoObject.top - orthoObject.bottom) / this.object.zoom;
7304          this.mouseChange.x *= scale_x;
7305          this.mouseChange.y *= scale_y;
7306        } else {
7307          this.mouseChange.multiplyScalar(this._eye.length() * this.panSpeed);
7308        }
7309        this.pan.copy(this._eye).cross(this.object.up).setLength(this.mouseChange.x);
7310        this.pan.add(this.objectUp.copy(this.object.up).setLength(this.mouseChange.y));
7311        this.object.position.add(this.pan);
7312        this.target.add(this.pan);
7313        if (this.staticMoving) {
7314          this._panStart.copy(this._panEnd);
7315        } else {
7316          this._panStart.add(
7317            this.mouseChange.subVectors(this._panEnd, this._panStart).multiplyScalar(this.dynamicDampingFactor)
7318          );
7319        }
7320      }
7321    });
7322    __publicField3(this, "checkDistances", () => {
7323      if (!this.noZoom || !this.noPan) {
7324        if (this._eye.lengthSq() > this.maxDistance * this.maxDistance) {
7325          this.object.position.addVectors(this.target, this._eye.setLength(this.maxDistance));
7326          this._zoomStart.copy(this._zoomEnd);
7327        }
7328        if (this._eye.lengthSq() < this.minDistance * this.minDistance) {
7329          this.object.position.addVectors(this.target, this._eye.setLength(this.minDistance));
7330          this._zoomStart.copy(this._zoomEnd);
7331        }
7332      }
7333    });
7334    __publicField3(this, "handleResize", () => {
7335      if (!this.domElement)
7336        return;
7337      const box = this.domElement.getBoundingClientRect();
7338      const d = this.domElement.ownerDocument.documentElement;
7339      this.screen.left = box.left + window.pageXOffset - d.clientLeft;
7340      this.screen.top = box.top + window.pageYOffset - d.clientTop;
7341      this.screen.width = box.width;
7342      this.screen.height = box.height;
7343    });
7344    __publicField3(this, "update", () => {
7345      this._eye.subVectors(this.object.position, this.target);
7346      if (!this.noRotate) {
7347        this.rotateCamera();
7348      }
7349      if (!this.noZoom) {
7350        this.zoomCamera();
7351      }
7352      if (!this.noPan) {
7353        this.panCamera();
7354      }
7355      this.object.position.addVectors(this.target, this._eye);
7356      if (this.object.isPerspectiveCamera) {
7357        this.checkDistances();
7358        this.object.lookAt(this.target);
7359        if (this.lastPosition.distanceToSquared(this.object.position) > this.EPS) {
7360          this.dispatchEvent(this.changeEvent);
7361          this.lastPosition.copy(this.object.position);
7362        }
7363      } else if (this.object.isOrthographicCamera) {
7364        this.object.lookAt(this.target);
7365        if (this.lastPosition.distanceToSquared(this.object.position) > this.EPS || this.lastZoom !== this.object.zoom) {
7366          this.dispatchEvent(this.changeEvent);
7367          this.lastPosition.copy(this.object.position);
7368          this.lastZoom = this.object.zoom;
7369        }
7370      } else {
7371        console.warn("THREE.TrackballControls: Unsupported camera type");
7372      }
7373    });
7374    __publicField3(this, "reset", () => {
7375      this._state = this.STATE.NONE;
7376      this._keyState = this.STATE.NONE;
7377      this.target.copy(this.target0);
7378      this.object.position.copy(this.position0);
7379      this.object.up.copy(this.up0);
7380      this.object.zoom = this.zoom0;
7381      this.object.updateProjectionMatrix();
7382      this._eye.subVectors(this.object.position, this.target);
7383      this.object.lookAt(this.target);
7384      this.dispatchEvent(this.changeEvent);
7385      this.lastPosition.copy(this.object.position);
7386      this.lastZoom = this.object.zoom;
7387    });
7388    __publicField3(this, "keydown", (event) => {
7389      if (this.enabled === false)
7390        return;
7391      window.removeEventListener("keydown", this.keydown);
7392      if (this._keyState !== this.STATE.NONE) {
7393        return;
7394      } else if (event.code === this.keys[this.STATE.ROTATE] && !this.noRotate) {
7395        this._keyState = this.STATE.ROTATE;
7396      } else if (event.code === this.keys[this.STATE.ZOOM] && !this.noZoom) {
7397        this._keyState = this.STATE.ZOOM;
7398      } else if (event.code === this.keys[this.STATE.PAN] && !this.noPan) {
7399        this._keyState = this.STATE.PAN;
7400      }
7401    });
7402    __publicField3(this, "onPointerDown", (event) => {
7403      if (this.enabled === false)
7404        return;
7405      switch (event.pointerType) {
7406        case "mouse":
7407        case "pen":
7408          this.onMouseDown(event);
7409          break;
7410      }
7411    });
7412    __publicField3(this, "onPointerMove", (event) => {
7413      if (this.enabled === false)
7414        return;
7415      switch (event.pointerType) {
7416        case "mouse":
7417        case "pen":
7418          this.onMouseMove(event);
7419          break;
7420      }
7421    });
7422    __publicField3(this, "onPointerUp", (event) => {
7423      if (this.enabled === false)
7424        return;
7425      switch (event.pointerType) {
7426        case "mouse":
7427        case "pen":
7428          this.onMouseUp();
7429          break;
7430      }
7431    });
7432    __publicField3(this, "keyup", () => {
7433      if (this.enabled === false)
7434        return;
7435      this._keyState = this.STATE.NONE;
7436      window.addEventListener("keydown", this.keydown);
7437    });
7438    __publicField3(this, "onMouseDown", (event) => {
7439      if (!this.domElement)
7440        return;
7441      if (this._state === this.STATE.NONE) {
7442        switch (event.button) {
7443          case this.mouseButtons.LEFT:
7444            this._state = this.STATE.ROTATE;
7445            break;
7446          case this.mouseButtons.MIDDLE:
7447            this._state = this.STATE.ZOOM;
7448            break;
7449          case this.mouseButtons.RIGHT:
7450            this._state = this.STATE.PAN;
7451            break;
7452        }
7453      }
7454      const state = this._keyState !== this.STATE.NONE ? this._keyState : this._state;
7455      if (state === this.STATE.ROTATE && !this.noRotate) {
7456        this._moveCurr.copy(this.getMouseOnCircle(event.pageX, event.pageY));
7457        this._movePrev.copy(this._moveCurr);
7458      } else if (state === this.STATE.ZOOM && !this.noZoom) {
7459        this._zoomStart.copy(this.getMouseOnScreen(event.pageX, event.pageY));
7460        this._zoomEnd.copy(this._zoomStart);
7461      } else if (state === this.STATE.PAN && !this.noPan) {
7462        this._panStart.copy(this.getMouseOnScreen(event.pageX, event.pageY));
7463        this._panEnd.copy(this._panStart);
7464      }
7465      this.domElement.ownerDocument.addEventListener("pointermove", this.onPointerMove);
7466      this.domElement.ownerDocument.addEventListener("pointerup", this.onPointerUp);
7467      this.dispatchEvent(this.startEvent);
7468    });
7469    __publicField3(this, "onMouseMove", (event) => {
7470      if (this.enabled === false)
7471        return;
7472      const state = this._keyState !== this.STATE.NONE ? this._keyState : this._state;
7473      if (state === this.STATE.ROTATE && !this.noRotate) {
7474        this._movePrev.copy(this._moveCurr);
7475        this._moveCurr.copy(this.getMouseOnCircle(event.pageX, event.pageY));
7476      } else if (state === this.STATE.ZOOM && !this.noZoom) {
7477        this._zoomEnd.copy(this.getMouseOnScreen(event.pageX, event.pageY));
7478      } else if (state === this.STATE.PAN && !this.noPan) {
7479        this._panEnd.copy(this.getMouseOnScreen(event.pageX, event.pageY));
7480      }
7481    });
7482    __publicField3(this, "onMouseUp", () => {
7483      if (!this.domElement)
7484        return;
7485      if (this.enabled === false)
7486        return;
7487      this._state = this.STATE.NONE;
7488      this.domElement.ownerDocument.removeEventListener("pointermove", this.onPointerMove);
7489      this.domElement.ownerDocument.removeEventListener("pointerup", this.onPointerUp);
7490      this.dispatchEvent(this.endEvent);
7491    });
7492    __publicField3(this, "mousewheel", (event) => {
7493      if (this.enabled === false)
7494        return;
7495      if (this.noZoom === true)
7496        return;
7497      event.preventDefault();
7498      switch (event.deltaMode) {
7499        case 2:
7500          this._zoomStart.y -= event.deltaY * 0.025;
7501          break;
7502        case 1:
7503          this._zoomStart.y -= event.deltaY * 0.01;
7504          break;
7505        default:
7506          this._zoomStart.y -= event.deltaY * 25e-5;
7507          break;
7508      }
7509      this.mousePosition.x = event.offsetX / this.screen.width * 2 - 1;
7510      this.mousePosition.y = -(event.offsetY / this.screen.height) * 2 + 1;
7511      this.dispatchEvent(this.startEvent);
7512      this.dispatchEvent(this.endEvent);
7513    });
7514    __publicField3(this, "touchstart", (event) => {
7515      if (this.enabled === false)
7516        return;
7517      event.preventDefault();
7518      switch (event.touches.length) {
7519        case 1:
7520          this._state = this.STATE.TOUCH_ROTATE;
7521          this._moveCurr.copy(this.getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));
7522          this._movePrev.copy(this._moveCurr);
7523          break;
7524        default:
7525          this._state = this.STATE.TOUCH_ZOOM_PAN;
7526          const dx = event.touches[0].pageX - event.touches[1].pageX;
7527          const dy = event.touches[0].pageY - event.touches[1].pageY;
7528          this._touchZoomDistanceEnd = this._touchZoomDistanceStart = Math.sqrt(dx * dx + dy * dy);
7529          const x = (event.touches[0].pageX + event.touches[1].pageX) / 2;
7530          const y = (event.touches[0].pageY + event.touches[1].pageY) / 2;
7531          this._panStart.copy(this.getMouseOnScreen(x, y));
7532          this._panEnd.copy(this._panStart);
7533          break;
7534      }
7535      this.dispatchEvent(this.startEvent);
7536    });
7537    __publicField3(this, "touchmove", (event) => {
7538      if (this.enabled === false)
7539        return;
7540      event.preventDefault();
7541      switch (event.touches.length) {
7542        case 1:
7543          this._movePrev.copy(this._moveCurr);
7544          this._moveCurr.copy(this.getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));
7545          break;
7546        default:
7547          const dx = event.touches[0].pageX - event.touches[1].pageX;
7548          const dy = event.touches[0].pageY - event.touches[1].pageY;
7549          this._touchZoomDistanceEnd = Math.sqrt(dx * dx + dy * dy);
7550          const x = (event.touches[0].pageX + event.touches[1].pageX) / 2;
7551          const y = (event.touches[0].pageY + event.touches[1].pageY) / 2;
7552          this._panEnd.copy(this.getMouseOnScreen(x, y));
7553          break;
7554      }
7555    });
7556    __publicField3(this, "touchend", (event) => {
7557      if (this.enabled === false)
7558        return;
7559      switch (event.touches.length) {
7560        case 0:
7561          this._state = this.STATE.NONE;
7562          break;
7563        case 1:
7564          this._state = this.STATE.TOUCH_ROTATE;
7565          this._moveCurr.copy(this.getMouseOnCircle(event.touches[0].pageX, event.touches[0].pageY));
7566          this._movePrev.copy(this._moveCurr);
7567          break;
7568      }
7569      this.dispatchEvent(this.endEvent);
7570    });
7571    __publicField3(this, "contextmenu", (event) => {
7572      if (this.enabled === false)
7573        return;
7574      event.preventDefault();
7575    });
7576    __publicField3(this, "connect", (domElement2) => {
7577      if (domElement2 === document) {
7578        console.error(
7579          'THREE.OrbitControls: "document" should not be used as the target "domElement". Please use "renderer.domElement" instead.'
7580        );
7581      }
7582      this.domElement = domElement2;
7583      this.domElement.addEventListener("contextmenu", this.contextmenu);
7584      this.domElement.addEventListener("pointerdown", this.onPointerDown);
7585      this.domElement.addEventListener("wheel", this.mousewheel);
7586      this.domElement.addEventListener("touchstart", this.touchstart);
7587      this.domElement.addEventListener("touchend", this.touchend);
7588      this.domElement.addEventListener("touchmove", this.touchmove);
7589      this.domElement.ownerDocument.addEventListener("pointermove", this.onPointerMove);
7590      this.domElement.ownerDocument.addEventListener("pointerup", this.onPointerUp);
7591      window.addEventListener("keydown", this.keydown);
7592      window.addEventListener("keyup", this.keyup);
7593      this.handleResize();
7594    });
7595    __publicField3(this, "dispose", () => {
7596      if (!this.domElement)
7597        return;
7598      this.domElement.removeEventListener("contextmenu", this.contextmenu);
7599      this.domElement.removeEventListener("pointerdown", this.onPointerDown);
7600      this.domElement.removeEventListener("wheel", this.mousewheel);
7601      this.domElement.removeEventListener("touchstart", this.touchstart);
7602      this.domElement.removeEventListener("touchend", this.touchend);
7603      this.domElement.removeEventListener("touchmove", this.touchmove);
7604      this.domElement.ownerDocument.removeEventListener("pointermove", this.onPointerMove);
7605      this.domElement.ownerDocument.removeEventListener("pointerup", this.onPointerUp);
7606      window.removeEventListener("keydown", this.keydown);
7607      window.removeEventListener("keyup", this.keyup);
7608    });
7609    this.object = object;
7610    this.target0 = this.target.clone();
7611    this.position0 = this.object.position.clone();
7612    this.up0 = this.object.up.clone();
7613    this.zoom0 = this.object.zoom;
7614    if (domElement !== void 0)
7615      this.connect(domElement);
7616    this.update();
7617  }
7618};
7619
vendor: 2,937 bytes, lines 7620-7699
7620// node_modules/three-stdlib/webxr/XRHandMeshModel.js
7621var __defProp4 = Object.defineProperty;
7622var __defNormalProp4 = (obj, key, value) => key in obj ? __defProp4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7623var __publicField4 = (obj, key, value) => {
7624  __defNormalProp4(obj, typeof key !== "symbol" ? key + "" : key, value);
7625  return value;
7626};
7627var DEFAULT_HAND_PROFILE_PATH = "https://cdn.jsdelivr.net/npm/@webxr-input-profiles/[email protected]/dist/profiles/generic-hand/";
7628var XRHandMeshModel = class {
7629  constructor(handModel, controller, path = DEFAULT_HAND_PROFILE_PATH, handedness, customModelPath) {
7630    __publicField4(this, "controller");
7631    __publicField4(this, "handModel");
7632    __publicField4(this, "bones");
7633    this.controller = controller;
7634    this.handModel = handModel;
7635    this.bones = [];
7636    const loader = new GLTFLoader();
7637    if (!customModelPath)
7638      loader.setPath(path);
7639    loader.load(customModelPath != null ? customModelPath : `${handedness}.glb`, (gltf) => {
7640      const object = gltf.scene.children[0];
7641      this.handModel.add(object);
7642      const mesh = object.getObjectByProperty("type", "SkinnedMesh");
7643      mesh.frustumCulled = false;
7644      mesh.castShadow = true;
7645      mesh.receiveShadow = true;
7646      const joints = [
7647        "wrist",
7648        "thumb-metacarpal",
7649        "thumb-phalanx-proximal",
7650        "thumb-phalanx-distal",
7651        "thumb-tip",
7652        "index-finger-metacarpal",
7653        "index-finger-phalanx-proximal",
7654        "index-finger-phalanx-intermediate",
7655        "index-finger-phalanx-distal",
7656        "index-finger-tip",
7657        "middle-finger-metacarpal",
7658        "middle-finger-phalanx-proximal",
7659        "middle-finger-phalanx-intermediate",
7660        "middle-finger-phalanx-distal",
7661        "middle-finger-tip",
7662        "ring-finger-metacarpal",
7663        "ring-finger-phalanx-proximal",
7664        "ring-finger-phalanx-intermediate",
7665        "ring-finger-phalanx-distal",
7666        "ring-finger-tip",
7667        "pinky-finger-metacarpal",
7668        "pinky-finger-phalanx-proximal",
7669        "pinky-finger-phalanx-intermediate",
7670        "pinky-finger-phalanx-distal",
7671        "pinky-finger-tip"
7672      ];
7673      joints.forEach((jointName) => {
7674        const bone = object.getObjectByName(jointName);
7675        if (bone !== void 0) {
7676          bone.jointName = jointName;
7677        } else {
7678          console.warn(`Couldn't find ${jointName} in ${handedness} hand mesh`);
7679        }
7680        this.bones.push(bone);
7681      });
7682    });
7683  }
7684  updateMesh() {
7685    const XRJoints = this.controller.joints;
7686    for (let i = 0; i < this.bones.length; i++) {
7687      const bone = this.bones[i];
7688      if (bone) {
7689        const XRJoint = XRJoints[bone.jointName];
7690        if (XRJoint.visible) {
7691          const position2 = XRJoint.position;
7692          bone.position.copy(position2);
7693          bone.quaternion.copy(XRJoint.quaternion);
7694        }
7695      }
7696    }
7697  }
7698};
7699
vendor: 974 bytes, lines 7700-7728
7700// node_modules/three-stdlib/webxr/Text2D.js
7701function createText(message, height) {
7702  const canvas = document.createElement("canvas");
7703  const context = canvas.getContext("2d");
7704  let metrics = null;
7705  const textHeight = 100;
7706  context.font = "normal " + textHeight + "px Arial";
7707  metrics = context.measureText(message);
7708  const textWidth = metrics.width;
7709  canvas.width = textWidth;
7710  canvas.height = textHeight;
7711  context.font = "normal " + textHeight + "px Arial";
7712  context.textAlign = "center";
7713  context.textBaseline = "middle";
7714  context.fillStyle = "#ffffff";
7715  context.fillText(message, textWidth / 2, textHeight / 2);
7716  const texture = new Texture(canvas);
7717  texture.needsUpdate = true;
7718  const material = new MeshBasicMaterial({
7719    color: 16777215,
7720    side: DoubleSide,
7721    map: texture,
7722    transparent: true
7723  });
7724  const geometry = new PlaneGeometry(height * textWidth / textHeight, height);
7725  const plane = new Mesh(geometry, material);
7726  return plane;
7727}
7728
vendor: 12,304 bytes, lines 7729-8049
7729// node_modules/three-stdlib/libs/MotionControllers.js
7730var __defProp5 = Object.defineProperty;
7731var __defNormalProp5 = (obj, key, value) => key in obj ? __defProp5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7732var __publicField5 = (obj, key, value) => {
7733  __defNormalProp5(obj, typeof key !== "symbol" ? key + "" : key, value);
7734  return value;
7735};
7736var MotionControllerConstants = {
7737  Handedness: {
7738    NONE: "none",
7739    LEFT: "left",
7740    RIGHT: "right"
7741  },
7742  ComponentState: {
7743    DEFAULT: "default",
7744    TOUCHED: "touched",
7745    PRESSED: "pressed"
7746  },
7747  ComponentProperty: {
7748    BUTTON: "button",
7749    X_AXIS: "xAxis",
7750    Y_AXIS: "yAxis",
7751    STATE: "state"
7752  },
7753  ComponentType: {
7754    TRIGGER: "trigger",
7755    SQUEEZE: "squeeze",
7756    TOUCHPAD: "touchpad",
7757    THUMBSTICK: "thumbstick",
7758    BUTTON: "button"
7759  },
7760  ButtonTouchThreshold: 0.05,
7761  AxisTouchThreshold: 0.1,
7762  VisualResponseProperty: {
7763    TRANSFORM: "transform",
7764    VISIBILITY: "visibility"
7765  }
7766};
7767async function fetchJsonFile(path) {
7768  const response = await fetch(path);
7769  if (!response.ok) {
7770    throw new Error(response.statusText);
7771  } else {
7772    return response.json();
7773  }
7774}
7775async function fetchProfilesList(basePath) {
7776  if (!basePath) {
7777    throw new Error("No basePath supplied");
7778  }
7779  const profileListFileName = "profilesList.json";
7780  const profilesList = await fetchJsonFile(`${basePath}/${profileListFileName}`);
7781  return profilesList;
7782}
7783async function fetchProfile(xrInputSource, basePath, defaultProfile = null, getAssetPath = true) {
7784  if (!xrInputSource) {
7785    throw new Error("No xrInputSource supplied");
7786  }
7787  if (!basePath) {
7788    throw new Error("No basePath supplied");
7789  }
7790  const supportedProfilesList = await fetchProfilesList(basePath);
7791  let match = void 0;
7792  xrInputSource.profiles.some((profileId) => {
7793    const supportedProfile = supportedProfilesList[profileId];
7794    if (supportedProfile) {
7795      match = {
7796        profileId,
7797        profilePath: `${basePath}/${supportedProfile.path}`,
7798        deprecated: !!supportedProfile.deprecated
7799      };
7800    }
7801    return !!match;
7802  });
7803  if (!match) {
7804    if (!defaultProfile) {
7805      throw new Error("No matching profile name found");
7806    }
7807    const supportedProfile = supportedProfilesList[defaultProfile];
7808    if (!supportedProfile) {
7809      throw new Error(`No matching profile name found and default profile "${defaultProfile}" missing.`);
7810    }
7811    match = {
7812      profileId: defaultProfile,
7813      profilePath: `${basePath}/${supportedProfile.path}`,
7814      deprecated: !!supportedProfile.deprecated
7815    };
7816  }
7817  const profile = await fetchJsonFile(match.profilePath);
7818  let assetPath = void 0;
7819  if (getAssetPath) {
7820    let layout;
7821    if (xrInputSource.handedness === "any") {
7822      layout = profile.layouts[Object.keys(profile.layouts)[0]];
7823    } else {
7824      layout = profile.layouts[xrInputSource.handedness];
7825    }
7826    if (!layout) {
7827      throw new Error(`No matching handedness, ${xrInputSource.handedness}, in profile ${match.profileId}`);
7828    }
7829    if (layout.assetPath) {
7830      assetPath = match.profilePath.replace("profile.json", layout.assetPath);
7831    }
7832  }
7833  return { profile, assetPath };
7834}
7835var defaultComponentValues = {
7836  xAxis: 0,
7837  yAxis: 0,
7838  button: 0,
7839  state: MotionControllerConstants.ComponentState.DEFAULT
7840};
7841function normalizeAxes(x = 0, y = 0) {
7842  let xAxis = x;
7843  let yAxis = y;
7844  const hypotenuse = Math.sqrt(x * x + y * y);
7845  if (hypotenuse > 1) {
7846    const theta = Math.atan2(y, x);
7847    xAxis = Math.cos(theta);
7848    yAxis = Math.sin(theta);
7849  }
7850  const result = {
7851    normalizedXAxis: xAxis * 0.5 + 0.5,
7852    normalizedYAxis: yAxis * 0.5 + 0.5
7853  };
7854  return result;
7855}
7856var VisualResponse = class {
7857  constructor(visualResponseDescription) {
7858    __publicField5(this, "value");
7859    __publicField5(this, "componentProperty");
7860    __publicField5(this, "states");
7861    __publicField5(this, "valueNodeName");
7862    __publicField5(this, "valueNodeProperty");
7863    __publicField5(this, "minNodeName");
7864    __publicField5(this, "maxNodeName");
7865    __publicField5(this, "valueNode");
7866    __publicField5(this, "minNode");
7867    __publicField5(this, "maxNode");
7868    this.componentProperty = visualResponseDescription.componentProperty;
7869    this.states = visualResponseDescription.states;
7870    this.valueNodeName = visualResponseDescription.valueNodeName;
7871    this.valueNodeProperty = visualResponseDescription.valueNodeProperty;
7872    if (this.valueNodeProperty === MotionControllerConstants.VisualResponseProperty.TRANSFORM) {
7873      this.minNodeName = visualResponseDescription.minNodeName;
7874      this.maxNodeName = visualResponseDescription.maxNodeName;
7875    }
7876    this.value = 0;
7877    this.updateFromComponent(defaultComponentValues);
7878  }
7879  /**
7880   * Computes the visual response's interpolation weight based on component state
7881   * @param {Object} componentValues - The component from which to update
7882   * @param {number | undefined} xAxis - The reported X axis value of the component
7883   * @param {number | undefined} yAxis - The reported Y axis value of the component
7884   * @param {number | undefined} button - The reported value of the component's button
7885   * @param {string} state - The component's active state
7886   */
7887  updateFromComponent({
7888    xAxis,
7889    yAxis,
7890    button,
7891    state
7892  }) {
7893    const { normalizedXAxis, normalizedYAxis } = normalizeAxes(xAxis, yAxis);
7894    switch (this.componentProperty) {
7895      case MotionControllerConstants.ComponentProperty.X_AXIS:
7896        this.value = this.states.includes(state) ? normalizedXAxis : 0.5;
7897        break;
7898      case MotionControllerConstants.ComponentProperty.Y_AXIS:
7899        this.value = this.states.includes(state) ? normalizedYAxis : 0.5;
7900        break;
7901      case MotionControllerConstants.ComponentProperty.BUTTON:
7902        this.value = this.states.includes(state) && button ? button : 0;
7903        break;
7904      case MotionControllerConstants.ComponentProperty.STATE:
7905        if (this.valueNodeProperty === MotionControllerConstants.VisualResponseProperty.VISIBILITY) {
7906          this.value = this.states.includes(state);
7907        } else {
7908          this.value = this.states.includes(state) ? 1 : 0;
7909        }
7910        break;
7911      default:
7912        throw new Error(`Unexpected visualResponse componentProperty ${this.componentProperty}`);
7913    }
7914  }
7915};
7916var Component = class {
7917  /**
7918   * @param {string} componentId - Id of the component
7919   * @param {InputProfileComponent} componentDescription - Description of the component to be created
7920   */
7921  constructor(componentId, componentDescription) {
7922    __publicField5(this, "id");
7923    __publicField5(this, "values");
7924    __publicField5(this, "type");
7925    __publicField5(this, "gamepadIndices");
7926    __publicField5(this, "rootNodeName");
7927    __publicField5(this, "visualResponses");
7928    __publicField5(this, "touchPointNodeName");
7929    __publicField5(this, "touchPointNode");
7930    if (!componentId || !componentDescription || !componentDescription.visualResponses || !componentDescription.gamepadIndices || Object.keys(componentDescription.gamepadIndices).length === 0) {
7931      throw new Error("Invalid arguments supplied");
7932    }
7933    this.id = componentId;
7934    this.type = componentDescription.type;
7935    this.rootNodeName = componentDescription.rootNodeName;
7936    this.touchPointNodeName = componentDescription.touchPointNodeName;
7937    this.visualResponses = {};
7938    Object.keys(componentDescription.visualResponses).forEach((responseName) => {
7939      const visualResponse = new VisualResponse(componentDescription.visualResponses[responseName]);
7940      this.visualResponses[responseName] = visualResponse;
7941    });
7942    this.gamepadIndices = Object.assign({}, componentDescription.gamepadIndices);
7943    this.values = {
7944      state: MotionControllerConstants.ComponentState.DEFAULT,
7945      button: this.gamepadIndices.button !== void 0 ? 0 : void 0,
7946      xAxis: this.gamepadIndices.xAxis !== void 0 ? 0 : void 0,
7947      yAxis: this.gamepadIndices.yAxis !== void 0 ? 0 : void 0
7948    };
7949  }
7950  get data() {
7951    const data = { id: this.id, ...this.values };
7952    return data;
7953  }
7954  /**
7955   * @description Poll for updated data based on current gamepad state
7956   * @param {Object} gamepad - The gamepad object from which the component data should be polled
7957   */
7958  updateFromGamepad(gamepad) {
7959    this.values.state = MotionControllerConstants.ComponentState.DEFAULT;
7960    if (this.gamepadIndices.button !== void 0 && gamepad.buttons.length > this.gamepadIndices.button) {
7961      const gamepadButton = gamepad.buttons[this.gamepadIndices.button];
7962      this.values.button = gamepadButton.value;
7963      this.values.button = this.values.button < 0 ? 0 : this.values.button;
7964      this.values.button = this.values.button > 1 ? 1 : this.values.button;
7965      if (gamepadButton.pressed || this.values.button === 1) {
7966        this.values.state = MotionControllerConstants.ComponentState.PRESSED;
7967      } else if (gamepadButton.touched || this.values.button > MotionControllerConstants.ButtonTouchThreshold) {
7968        this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
7969      }
7970    }
7971    if (this.gamepadIndices.xAxis !== void 0 && gamepad.axes.length > this.gamepadIndices.xAxis) {
7972      this.values.xAxis = gamepad.axes[this.gamepadIndices.xAxis];
7973      this.values.xAxis = this.values.xAxis < -1 ? -1 : this.values.xAxis;
7974      this.values.xAxis = this.values.xAxis > 1 ? 1 : this.values.xAxis;
7975      if (this.values.state === MotionControllerConstants.ComponentState.DEFAULT && Math.abs(this.values.xAxis) > MotionControllerConstants.AxisTouchThreshold) {
7976        this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
7977      }
7978    }
7979    if (this.gamepadIndices.yAxis !== void 0 && gamepad.axes.length > this.gamepadIndices.yAxis) {
7980      this.values.yAxis = gamepad.axes[this.gamepadIndices.yAxis];
7981      this.values.yAxis = this.values.yAxis < -1 ? -1 : this.values.yAxis;
7982      this.values.yAxis = this.values.yAxis > 1 ? 1 : this.values.yAxis;
7983      if (this.values.state === MotionControllerConstants.ComponentState.DEFAULT && Math.abs(this.values.yAxis) > MotionControllerConstants.AxisTouchThreshold) {
7984        this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
7985      }
7986    }
7987    Object.values(this.visualResponses).forEach((visualResponse) => {
7988      visualResponse.updateFromComponent(this.values);
7989    });
7990  }
7991};
7992var MotionController = class {
7993  /**
7994   * @param {XRInputSource} xrInputSource - The XRInputSource to build the MotionController around
7995   * @param {Profile} profile - The best matched profile description for the supplied xrInputSource
7996   * @param {string} assetUrl
7997   */
7998  constructor(xrInputSource, profile, assetUrl) {
7999    __publicField5(this, "xrInputSource");
8000    __publicField5(this, "assetUrl");
8001    __publicField5(this, "layoutDescription");
8002    __publicField5(this, "id");
8003    __publicField5(this, "components");
8004    if (!xrInputSource) {
8005      throw new Error("No xrInputSource supplied");
8006    }
8007    if (!profile) {
8008      throw new Error("No profile supplied");
8009    }
8010    if (!profile.layouts[xrInputSource.handedness]) {
8011      throw new Error("No layout for " + xrInputSource.handedness + " handedness");
8012    }
8013    this.xrInputSource = xrInputSource;
8014    this.assetUrl = assetUrl;
8015    this.id = profile.profileId;
8016    this.layoutDescription = profile.layouts[xrInputSource.handedness];
8017    this.components = {};
8018    Object.keys(this.layoutDescription.components).forEach((componentId) => {
8019      const componentDescription = this.layoutDescription.components[componentId];
8020      this.components[componentId] = new Component(componentId, componentDescription);
8021    });
8022    this.updateFromGamepad();
8023  }
8024  get gripSpace() {
8025    return this.xrInputSource.gripSpace;
8026  }
8027  get targetRaySpace() {
8028    return this.xrInputSource.targetRaySpace;
8029  }
8030  /**
8031   * @description Returns a subset of component data for simplified debugging
8032   */
8033  get data() {
8034    const data = [];
8035    Object.values(this.components).forEach((component) => {
8036      data.push(component.data);
8037    });
8038    return data;
8039  }
8040  /**
8041   * @description Poll for updated data based on current gamepad state
8042   */
8043  updateFromGamepad() {
8044    Object.values(this.components).forEach((component) => {
8045      component.updateFromGamepad(this.xrInputSource.gamepad);
8046    });
8047  }
8048};
8049
vendor: 6,727 bytes, lines 8050-8219
8050// node_modules/three-stdlib/webxr/XRControllerModelFactory.js
8051var __defProp6 = Object.defineProperty;
8052var __defNormalProp6 = (obj, key, value) => key in obj ? __defProp6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8053var __publicField6 = (obj, key, value) => {
8054  __defNormalProp6(obj, typeof key !== "symbol" ? key + "" : key, value);
8055  return value;
8056};
8057var DEFAULT_PROFILES_PATH = "https://cdn.jsdelivr.net/npm/@webxr-input-profiles/[email protected]/dist/profiles";
8058var DEFAULT_PROFILE = "generic-trigger";
8059var applyEnvironmentMap = (envMap, obj) => {
8060  obj.traverse((child) => {
8061    if (child instanceof Mesh && "envMap" in child.material) {
8062      child.material.envMap = envMap;
8063      child.material.needsUpdate = true;
8064    }
8065  });
8066};
8067var XRControllerModel = class extends Object3D {
8068  constructor() {
8069    super();
8070    __publicField6(this, "envMap");
8071    __publicField6(this, "motionController");
8072    this.motionController = null;
8073    this.envMap = null;
8074  }
8075  setEnvironmentMap(envMap) {
8076    if (this.envMap == envMap) {
8077      return this;
8078    }
8079    this.envMap = envMap;
8080    applyEnvironmentMap(this.envMap, this);
8081    return this;
8082  }
8083  /**
8084   * Polls data from the XRInputSource and updates the model's components to match
8085   * the real world data
8086   */
8087  updateMatrixWorld(force) {
8088    super.updateMatrixWorld(force);
8089    if (!this.motionController)
8090      return;
8091    this.motionController.updateFromGamepad();
8092    Object.values(this.motionController.components).forEach((component) => {
8093      Object.values(component.visualResponses).forEach((visualResponse) => {
8094        const { valueNode, minNode, maxNode, value, valueNodeProperty } = visualResponse;
8095        if (!valueNode)
8096          return;
8097        if (valueNodeProperty === MotionControllerConstants.VisualResponseProperty.VISIBILITY && typeof value === "boolean") {
8098          valueNode.visible = value;
8099        } else if (valueNodeProperty === MotionControllerConstants.VisualResponseProperty.TRANSFORM && minNode && maxNode && typeof value === "number") {
8100          valueNode.quaternion.slerpQuaternions(minNode.quaternion, maxNode.quaternion, value);
8101          valueNode.position.lerpVectors(minNode.position, maxNode.position, value);
8102        }
8103      });
8104    });
8105  }
8106};
8107function findNodes(motionController, scene) {
8108  Object.values(motionController.components).forEach((component) => {
8109    const { type, touchPointNodeName, visualResponses } = component;
8110    if (type === MotionControllerConstants.ComponentType.TOUCHPAD && touchPointNodeName) {
8111      component.touchPointNode = scene.getObjectByName(touchPointNodeName);
8112      if (component.touchPointNode) {
8113        const sphereGeometry = new SphereGeometry(1e-3);
8114        const material = new MeshBasicMaterial({ color: 255 });
8115        const sphere = new Mesh(sphereGeometry, material);
8116        component.touchPointNode.add(sphere);
8117      } else {
8118        console.warn(`Could not find touch dot, ${component.touchPointNodeName}, in touchpad component ${component.id}`);
8119      }
8120    }
8121    Object.values(visualResponses).forEach((visualResponse) => {
8122      const { valueNodeName, minNodeName, maxNodeName, valueNodeProperty } = visualResponse;
8123      if (valueNodeProperty === MotionControllerConstants.VisualResponseProperty.TRANSFORM && minNodeName && maxNodeName) {
8124        visualResponse.minNode = scene.getObjectByName(minNodeName);
8125        visualResponse.maxNode = scene.getObjectByName(maxNodeName);
8126        if (!visualResponse.minNode) {
8127          console.warn(`Could not find ${minNodeName} in the model`);
8128          return;
8129        }
8130        if (!visualResponse.maxNode) {
8131          console.warn(`Could not find ${maxNodeName} in the model`);
8132          return;
8133        }
8134      }
8135      visualResponse.valueNode = scene.getObjectByName(valueNodeName);
8136      if (!visualResponse.valueNode) {
8137        console.warn(`Could not find ${valueNodeName} in the model`);
8138      }
8139    });
8140  });
8141}
8142function addAssetSceneToControllerModel(controllerModel, scene) {
8143  findNodes(controllerModel.motionController, scene);
8144  if (controllerModel.envMap) {
8145    applyEnvironmentMap(controllerModel.envMap, scene);
8146  }
8147  controllerModel.add(scene);
8148}
8149var XRControllerModelFactory = class {
8150  constructor(gltfLoader = null) {
8151    __publicField6(this, "gltfLoader");
8152    __publicField6(this, "path");
8153    __publicField6(this, "_assetCache");
8154    this.gltfLoader = gltfLoader;
8155    this.path = DEFAULT_PROFILES_PATH;
8156    this._assetCache = {};
8157    if (!this.gltfLoader) {
8158      this.gltfLoader = new GLTFLoader();
8159    }
8160  }
8161  createControllerModel(controller) {
8162    const controllerModel = new XRControllerModel();
8163    let scene = null;
8164    const onConnected = (event) => {
8165      const xrInputSource = event.data;
8166      if (xrInputSource.targetRayMode !== "tracked-pointer" || !xrInputSource.gamepad)
8167        return;
8168      fetchProfile(xrInputSource, this.path, DEFAULT_PROFILE).then(({ profile, assetPath }) => {
8169        if (!assetPath) {
8170          throw new Error("no asset path");
8171        }
8172        controllerModel.motionController = new MotionController(xrInputSource, profile, assetPath);
8173        const assetUrl = controllerModel.motionController.assetUrl;
8174        const cachedAsset = this._assetCache[assetUrl];
8175        if (cachedAsset) {
8176          scene = cachedAsset.scene.clone();
8177          addAssetSceneToControllerModel(controllerModel, scene);
8178        } else {
8179          if (!this.gltfLoader) {
8180            throw new Error("GLTFLoader not set.");
8181          }
8182          this.gltfLoader.setPath("");
8183          this.gltfLoader.load(
8184            controllerModel.motionController.assetUrl,
8185            (asset) => {
8186              if (!controllerModel.motionController) {
8187                console.warn("motionController gone while gltf load, bailing...");
8188                return;
8189              }
8190              this._assetCache[assetUrl] = asset;
8191              scene = asset.scene.clone();
8192              addAssetSceneToControllerModel(controllerModel, scene);
8193            },
8194            () => {
8195            },
8196            () => {
8197              throw new Error(`Asset ${assetUrl} missing or malformed.`);
8198            }
8199          );
8200        }
8201      }).catch((err) => {
8202        console.warn(err);
8203      });
8204    };
8205    controller.addEventListener("connected", onConnected);
8206    const onDisconnected = () => {
8207      controller.removeEventListener("connected", onConnected);
8208      controller.removeEventListener("disconnected", onDisconnected);
8209      controllerModel.motionController = null;
8210      if (scene) {
8211        controllerModel.remove(scene);
8212      }
8213      scene = null;
8214    };
8215    controller.addEventListener("disconnected", onDisconnected);
8216    return controllerModel;
8217  }
8218};
8219
vendor: 2,269 bytes, lines 8220-8285
8220// node_modules/three-stdlib/webxr/XRHandPrimitiveModel.js
8221var _matrix = /* @__PURE__ */ new Matrix4();
8222var _vector2 = /* @__PURE__ */ new Vector3();
8223var XRHandPrimitiveModel = class {
8224  constructor(handModel, controller, path, handedness, options) {
8225    this.controller = controller;
8226    this.handModel = handModel;
8227    this.envMap = null;
8228    let geometry;
8229    if (!options || !options.primitive || options.primitive === "sphere") {
8230      geometry = new SphereGeometry(1, 10, 10);
8231    } else if (options.primitive === "box") {
8232      geometry = new BoxGeometry(1, 1, 1);
8233    }
8234    const material = new MeshStandardMaterial();
8235    this.handMesh = new InstancedMesh(geometry, material, 30);
8236    this.handMesh.instanceMatrix.setUsage(DynamicDrawUsage);
8237    this.handMesh.castShadow = true;
8238    this.handMesh.receiveShadow = true;
8239    this.handModel.add(this.handMesh);
8240    this.joints = [
8241      "wrist",
8242      "thumb-metacarpal",
8243      "thumb-phalanx-proximal",
8244      "thumb-phalanx-distal",
8245      "thumb-tip",
8246      "index-finger-metacarpal",
8247      "index-finger-phalanx-proximal",
8248      "index-finger-phalanx-intermediate",
8249      "index-finger-phalanx-distal",
8250      "index-finger-tip",
8251      "middle-finger-metacarpal",
8252      "middle-finger-phalanx-proximal",
8253      "middle-finger-phalanx-intermediate",
8254      "middle-finger-phalanx-distal",
8255      "middle-finger-tip",
8256      "ring-finger-metacarpal",
8257      "ring-finger-phalanx-proximal",
8258      "ring-finger-phalanx-intermediate",
8259      "ring-finger-phalanx-distal",
8260      "ring-finger-tip",
8261      "pinky-finger-metacarpal",
8262      "pinky-finger-phalanx-proximal",
8263      "pinky-finger-phalanx-intermediate",
8264      "pinky-finger-phalanx-distal",
8265      "pinky-finger-tip"
8266    ];
8267  }
8268  updateMesh() {
8269    const defaultRadius = 8e-3;
8270    const joints = this.controller.joints;
8271    let count = 0;
8272    for (let i = 0; i < this.joints.length; i++) {
8273      const joint = joints[this.joints[i]];
8274      if (joint.visible) {
8275        _vector2.setScalar(joint.jointRadius || defaultRadius);
8276        _matrix.compose(joint.position, joint.quaternion, _vector2);
8277        this.handMesh.setMatrixAt(i, _matrix);
8278        count++;
8279      }
8280    }
8281    this.handMesh.count = count;
8282    this.handMesh.instanceMatrix.needsUpdate = true;
8283  }
8284};
8285
vendor: 1,926 bytes, lines 8286-8360
8286// node_modules/three-stdlib/webxr/XRHandModelFactory.js
8287var XRHandModel = class extends Object3D {
8288  constructor(controller) {
8289    super();
8290    this.controller = controller;
8291    this.motionController = null;
8292    this.envMap = null;
8293    this.mesh = null;
8294  }
8295  updateMatrixWorld(force) {
8296    super.updateMatrixWorld(force);
8297    if (this.motionController) {
8298      this.motionController.updateMesh();
8299    }
8300  }
8301};
8302var XRHandModelFactory = class {
8303  constructor() {
8304    this.path = null;
8305  }
8306  setPath(path) {
8307    this.path = path;
8308    return this;
8309  }
8310  createHandModel(controller, profile) {
8311    const handModel = new XRHandModel(controller);
8312    controller.addEventListener("connected", (event) => {
8313      const xrInputSource = event.data;
8314      if (xrInputSource.hand && !handModel.motionController) {
8315        handModel.xrInputSource = xrInputSource;
8316        if (profile === void 0 || profile === "spheres") {
8317          handModel.motionController = new XRHandPrimitiveModel(
8318            handModel,
8319            controller,
8320            this.path,
8321            xrInputSource.handedness,
8322            { primitive: "sphere" }
8323          );
8324        } else if (profile === "boxes") {
8325          handModel.motionController = new XRHandPrimitiveModel(
8326            handModel,
8327            controller,
8328            this.path,
8329            xrInputSource.handedness,
8330            { primitive: "box" }
8331          );
8332        } else if (profile === "mesh") {
8333          handModel.motionController = new XRHandMeshModel(handModel, controller, this.path, xrInputSource.handedness);
8334        }
8335      }
8336    });
8337    controller.addEventListener("disconnected", () => {
8338    });
8339    return handModel;
8340  }
8341};
8342
8343export {
8344  useFrame,
8345  useThree,
8346  Canvas,
8347  Resource,
8348  createT,
8349  useXR,
8350  createXR,
8351  CSS2DObject,
8352  CSS2DRenderer,
8353  GLTFExporter,
8354  TrackballControls,
8355  GLTFLoader,
8356  createText,
8357  XRControllerModelFactory,
8358  XRHandModelFactory,
8359  DRACOLoader
8360};

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.