@limrun/ui 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,76 @@ logo is omitted. Pass your own images through the `assets` prop if you want fram
16
16
  `onConnectionStateChange` reports `connecting`, `connected`, `reconnecting`, `failed`, and
17
17
  `terminated` so a host can show status text without tracking the retry logic.
18
18
 
19
+ ## Playback buffering
20
+
21
+ `jitterBufferTargetMs` sets a preferred browser jitter buffer duration for incoming
22
+ audio and video on Android and iOS streams. It accepts finite numbers from 0 to
23
+ 4000 milliseconds. For example:
24
+
25
+ ```tsx
26
+ <RemoteControl url={instanceWebsocketUrl} token={instanceToken} jitterBufferTargetMs={50} />
27
+ ```
28
+
29
+ The default is the browser's automatic buffering. Changing the prop updates active
30
+ receivers without reconnecting and applies to new receivers after a reconnect.
31
+ Remove the prop or set it to `null` to restore automatic buffering. Browsers without
32
+ `RTCRtpReceiver.jitterBufferTarget` ignore the prop. Invalid values produce a console
33
+ warning and leave the receiver's previous target unchanged.
34
+
35
+ The target is a preference, not a maximum buffer size or an end-to-end latency
36
+ guarantee. A lower value can reduce playback delay but increase dropped frames,
37
+ freezes, or audio interruptions on unstable connections. The browser can use a
38
+ different duration and can adjust gradually. Compare first-frame latency after idle,
39
+ steady playback, and drops or freezes on your target browsers and networks before
40
+ choosing a value. The example's 50 ms is not a recommended default.
41
+
42
+ ## Playback measurements
43
+
44
+ Pass `onPlaybackStats` to receive browser measurements for incoming iOS and
45
+ Android streams, including phones, tablets, Apple Watch, and both Duo displays.
46
+ The callback and its types are available from `@limrun/ui` and `@limrun/ui/lite`.
47
+
48
+ ```tsx
49
+ import { useState } from 'react';
50
+ import { RemoteControl, type PlaybackStats } from '@limrun/ui';
51
+
52
+ function Player({ url, token }: { url: string; token: string }) {
53
+ const [stats, setStats] = useState<PlaybackStats | null>(null);
54
+ const primary = stats?.video.find((video) => video.display === 'primary');
55
+ return (
56
+ <>
57
+ <RemoteControl url={url} token={token} onPlaybackStats={setStats} />
58
+ <output>Buffer delay: {primary?.bufferDelayMs?.toFixed(1) ?? '—'} ms</output>
59
+ </>
60
+ );
61
+ }
62
+ ```
63
+
64
+ Collection uses the existing connection about every two seconds while the callback
65
+ is set and the tab is visible. Removing the callback stops collection. A disconnect,
66
+ hidden tab, or collection error emits `null` once after a measurement. Resuming or
67
+ reconnecting starts a fresh baseline. Changing the callback function does not reconnect
68
+ or restart collection. No stats requests run without a subscriber.
69
+
70
+ `PlaybackStats` contains `video` and `audio` arrays, a Unix-millisecond `timestamp`,
71
+ `requestedTargetMs`, and optional selected-connection `rttMs`. A `null` target means
72
+ automatic buffering. An invalid target prop leaves this field undefined. The requested
73
+ target does not confirm browser support or the duration actually used.
74
+
75
+ Each track has `id`, `trackId`, `timestamp`, and optional `intervalMs`,
76
+ `bufferDelayMs`, and `bitrateBps`. Video adds `display`, `fps`, `droppedFrames`, and
77
+ `freezes`. Duo's `primary` and `inner` displays stay separate. Audio is empty when
78
+ the connection has no incoming audio stream. Camera and microphone uploads are excluded.
79
+
80
+ Rates and counts describe the interval since that stream's previous sample.
81
+ Buffer delay divides the change in accumulated jitter-buffer delay by the change
82
+ in emitted frames or audio samples. FPS uses decoded frames; freezes count only
83
+ browser-reported freezes that have completed. Missing browser fields, the first
84
+ sample, and reset counters leave affected measurements undefined. A buffer with
85
+ no emitted frames has no delay measurement; it is not zero. Static screens may
86
+ have low FPS. These measurements do not include tap-to-screen latency or server
87
+ encoding time.
88
+
19
89
  ## Simulated cameras
20
90
 
21
91
  `RemoteControl` responds automatically when an app in the instance opens,
@@ -43,10 +113,14 @@ Related browser workflow packages are published separately:
43
113
  ## Latency diagnostics
44
114
 
45
115
  Pass `onTrace={(message) => ...}` to receive each parsed diagnostic message
46
- from supported single-display iOS instances. Omitting the callback leaves tracing off.
116
+ from supported single-display iOS and Android instances. Omitting the callback leaves tracing off.
47
117
  Adding or removing it reconnects the stream; replacing the callback does not.
48
118
  Older servers keep streaming normally without diagnostics.
49
119
 
120
+ Both platforms use the same versioned messages, input sequences, and frame records.
121
+ See [latency diagnostics](https://docs.limrun.com/platform/embed-simulator#latency-diagnostics)
122
+ for the event fields and measurement limits.
123
+
50
124
  ## Releasing
51
125
 
52
126
  This package is not part of generated SDK, hence you need to publish it manually in GitHub Actions.
@@ -1,4 +1,4 @@
1
- import { L as Ae, a as G, F as he, M as w, V as fe, C as F, b, S as U, c as Le, P as Me, D as Se, d as K, e as C, I as ye, Q as de, f as we, O as pe, T as be, g as Ne, B as V, h as Ie, i as me, N as Oe, j as Ce, k as Fe, l as Q, m as ge, R as J, n as Pe, o as ke, p as He, q as z, r as De, s as Te, t as ve, u as v, v as Ge, w as Ue, x as Ke, y as Be, z as ee, A as je, E as Ve, G as ze, H as Xe, J as X, K as qe, U as We, W as Ye, X as Qe, Y as Je, Z as Ze, _ as $e, $ as Re, a0 as en, a1 as ne, a2 as te, a3 as se, a4 as ie, a5 as re, a6 as nn, a7 as tn, a8 as sn, a9 as rn, aa as on, ab as an } from "./duo-frame-D17Tat2r.mjs";
1
+ import { L as Ae, a as G, F as he, M as w, V as fe, C as F, b, S as U, c as Le, P as Me, D as Se, d as K, e as C, I as ye, Q as de, f as we, O as pe, T as be, g as Ne, B as V, h as Ie, i as me, N as Oe, j as Ce, k as Fe, l as Q, m as ge, R as J, n as Pe, o as ke, p as He, q as z, r as De, s as Te, t as ve, u as v, v as Ge, w as Ue, x as Ke, y as Be, z as ee, A as je, E as Ve, G as ze, H as Xe, J as X, K as qe, U as We, W as Ye, X as Qe, Y as Je, Z as Ze, _ as $e, $ as Re, a0 as en, a1 as ne, a2 as te, a3 as se, a4 as ie, a5 as re, a6 as nn, a7 as tn, a8 as sn, a9 as rn, aa as on, ab as an } from "./duo-frame-CB8dL8T-.mjs";
2
2
  function cn(f) {
3
3
  const n = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Map(), t = f.clone();
4
4
  return Ee(f, t, function(s, i) {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./duo-frame-BFXPC17N.js");function Q(d){const t=new Map,e=new Map,n=d.clone();return q(d,n,function(s,r){t.set(r,s),e.set(s,r)}),n.traverse(function(s){if(!s.isSkinnedMesh)return;const r=s,o=t.get(s),a=o.skeleton.bones;r.skeleton=o.skeleton.clone(),r.bindMatrix.copy(o.bindMatrix),r.skeleton.bones=a.map(function(i){return e.get(i)}),r.bind(r.skeleton,r.bindMatrix)}),n}function q(d,t,e){e(d,t);for(let n=0;n<d.children.length;n++)q(d.children[n],t.children[n],e)}class J extends h.Loader{constructor(t){super(t),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new ne(e)}),this.register(function(e){return new se(e)}),this.register(function(e){return new fe(e)}),this.register(function(e){return new de(e)}),this.register(function(e){return new pe(e)}),this.register(function(e){return new ie(e)}),this.register(function(e){return new oe(e)}),this.register(function(e){return new ae(e)}),this.register(function(e){return new ce(e)}),this.register(function(e){return new te(e)}),this.register(function(e){return new le(e)}),this.register(function(e){return new re(e)}),this.register(function(e){return new he(e)}),this.register(function(e){return new ue(e)}),this.register(function(e){return new $(e)}),this.register(function(e){return new K(e,T.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new K(e,T.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new me(e)})}load(t,e,n,s){const r=this;let o;if(this.resourcePath!=="")o=this.resourcePath;else if(this.path!==""){const c=h.LoaderUtils.extractUrlBase(t);o=h.LoaderUtils.resolveURL(c,this.path)}else o=h.LoaderUtils.extractUrlBase(t);this.manager.itemStart(t);const a=function(c){s?s(c):console.error(c),r.manager.itemError(t),r.manager.itemEnd(t)},i=new h.FileLoader(this.manager);i.setPath(this.path),i.setResponseType("arraybuffer"),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(t,function(c){try{r.parse(c,o,function(u){e(u),r.manager.itemEnd(t)},a)}catch(u){a(u)}},n,a)}setDRACOLoader(t){return this.dracoLoader=t,this}setKTX2Loader(t){return this.ktx2Loader=t,this}setMeshoptDecoder(t){return this.meshoptDecoder=t,this}register(t){return this.pluginCallbacks.indexOf(t)===-1&&this.pluginCallbacks.push(t),this}unregister(t){return this.pluginCallbacks.indexOf(t)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(t),1),this}parse(t,e,n,s){let r;const o={},a={},i=new TextDecoder;if(typeof t=="string")r=JSON.parse(t);else if(t instanceof ArrayBuffer)if(i.decode(new Uint8Array(t,0,4))===W){try{o[T.KHR_BINARY_GLTF]=new ge(t)}catch(l){s&&s(l);return}r=JSON.parse(o[T.KHR_BINARY_GLTF].content)}else r=JSON.parse(i.decode(t));else r=t;if(r.asset===void 0||r.asset.version[0]<2){s&&s(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));return}const c=new Ne(r,{path:e||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let u=0;u<this.pluginCallbacks.length;u++){const l=this.pluginCallbacks[u](c);l.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),a[l.name]=l,o[l.name]=!0}if(r.extensionsUsed)for(let u=0;u<r.extensionsUsed.length;++u){const l=r.extensionsUsed[u],f=r.extensionsRequired||[];switch(l){case T.KHR_MATERIALS_UNLIT:o[l]=new ee;break;case T.KHR_DRACO_MESH_COMPRESSION:o[l]=new Te(r,this.dracoLoader);break;case T.KHR_TEXTURE_TRANSFORM:o[l]=new Re;break;case T.KHR_MESH_QUANTIZATION:o[l]=new Me;break;default:f.indexOf(l)>=0&&a[l]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+l+'".')}}c.setExtensions(o),c.setPlugins(a),c.parse(n,s)}parseAsync(t,e){const n=this;return new Promise(function(s,r){n.parse(t,e,s,r)})}}function Z(){let d={};return{get:function(t){return d[t]},add:function(t,e){d[t]=e},remove:function(t){delete d[t]},removeAll:function(){d={}}}}function _(d,t,e){const n=d.json.materials[t];return n.extensions&&n.extensions[e]?n.extensions[e]:null}const T={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",KHR_MESHOPT_COMPRESSION:"KHR_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class ${constructor(t){this.parser=t,this.name=T.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const t=this.parser,e=this.parser.json.nodes||[];for(let n=0,s=e.length;n<s;n++){const r=e[n];r.extensions&&r.extensions[this.name]&&r.extensions[this.name].light!==void 0&&t._addNodeRef(this.cache,r.extensions[this.name].light)}}_loadLight(t){const e=this.parser,n="light:"+t;let s=e.cache.get(n);if(s)return s;const r=e.json,i=((r.extensions&&r.extensions[this.name]||{}).lights||[])[t];let c;const u=new h.Color(16777215);i.color!==void 0&&u.setRGB(i.color[0],i.color[1],i.color[2],h.LinearSRGBColorSpace);const l=i.range!==void 0?i.range:0;switch(i.type){case"directional":c=new h.DirectionalLight(u),c.target.position.set(0,0,-1),c.add(c.target);break;case"point":c=new h.PointLight(u),c.distance=l;break;case"spot":c=new h.SpotLight(u),c.distance=l,i.spot=i.spot||{},i.spot.innerConeAngle=i.spot.innerConeAngle!==void 0?i.spot.innerConeAngle:0,i.spot.outerConeAngle=i.spot.outerConeAngle!==void 0?i.spot.outerConeAngle:Math.PI/4,c.angle=i.spot.outerConeAngle,c.penumbra=1-i.spot.innerConeAngle/i.spot.outerConeAngle,c.target.position.set(0,0,-1),c.add(c.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+i.type)}return c.position.set(0,0,0),w(c,i),i.intensity!==void 0&&(c.intensity=i.intensity),c.name=e.createUniqueName(i.name||"light_"+t),s=Promise.resolve(c),e.cache.add(n,s),s}getDependency(t,e){if(t==="light")return this._loadLight(e)}createNodeAttachment(t){const e=this,n=this.parser,r=n.json.nodes[t],a=(r.extensions&&r.extensions[this.name]||{}).light;return a===void 0?null:this._loadLight(a).then(function(i){return n._getNodeRef(e.cache,a,i)})}}class ee{constructor(){this.name=T.KHR_MATERIALS_UNLIT}getMaterialType(){return h.MeshBasicMaterial}extendParams(t,e,n){const s=[];t.color=new h.Color(1,1,1),t.opacity=1;const r=e.pbrMetallicRoughness;if(r){if(Array.isArray(r.baseColorFactor)){const o=r.baseColorFactor;t.color.setRGB(o[0],o[1],o[2],h.LinearSRGBColorSpace),t.opacity=o[3]}r.baseColorTexture!==void 0&&s.push(n.assignTexture(t,"map",r.baseColorTexture,h.SRGBColorSpace))}return Promise.all(s)}}class te{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||n.emissiveStrength!==void 0&&(e.emissiveIntensity=n.emissiveStrength),Promise.resolve()}}class ne{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_CLEARCOAT}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];if(n.clearcoatFactor!==void 0&&(e.clearcoat=n.clearcoatFactor),n.clearcoatTexture!==void 0&&s.push(this.parser.assignTexture(e,"clearcoatMap",n.clearcoatTexture)),n.clearcoatRoughnessFactor!==void 0&&(e.clearcoatRoughness=n.clearcoatRoughnessFactor),n.clearcoatRoughnessTexture!==void 0&&s.push(this.parser.assignTexture(e,"clearcoatRoughnessMap",n.clearcoatRoughnessTexture)),n.clearcoatNormalTexture!==void 0&&(s.push(this.parser.assignTexture(e,"clearcoatNormalMap",n.clearcoatNormalTexture)),n.clearcoatNormalTexture.scale!==void 0)){const r=n.clearcoatNormalTexture.scale;e.clearcoatNormalScale=new h.Vector2(r,r)}return Promise.all(s)}}class se{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_DISPERSION}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||(e.dispersion=n.dispersion!==void 0?n.dispersion:0),Promise.resolve()}}class re{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_IRIDESCENCE}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.iridescenceFactor!==void 0&&(e.iridescence=n.iridescenceFactor),n.iridescenceTexture!==void 0&&s.push(this.parser.assignTexture(e,"iridescenceMap",n.iridescenceTexture)),n.iridescenceIor!==void 0&&(e.iridescenceIOR=n.iridescenceIor),e.iridescenceThicknessRange===void 0&&(e.iridescenceThicknessRange=[100,400]),n.iridescenceThicknessMinimum!==void 0&&(e.iridescenceThicknessRange[0]=n.iridescenceThicknessMinimum),n.iridescenceThicknessMaximum!==void 0&&(e.iridescenceThicknessRange[1]=n.iridescenceThicknessMaximum),n.iridescenceThicknessTexture!==void 0&&s.push(this.parser.assignTexture(e,"iridescenceThicknessMap",n.iridescenceThicknessTexture)),Promise.all(s)}}class ie{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_SHEEN}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];if(e.sheenColor=new h.Color(0,0,0),e.sheenRoughness=0,e.sheen=1,n.sheenColorFactor!==void 0){const r=n.sheenColorFactor;e.sheenColor.setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace)}return n.sheenRoughnessFactor!==void 0&&(e.sheenRoughness=n.sheenRoughnessFactor),n.sheenColorTexture!==void 0&&s.push(this.parser.assignTexture(e,"sheenColorMap",n.sheenColorTexture,h.SRGBColorSpace)),n.sheenRoughnessTexture!==void 0&&s.push(this.parser.assignTexture(e,"sheenRoughnessMap",n.sheenRoughnessTexture)),Promise.all(s)}}class oe{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_TRANSMISSION}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.transmissionFactor!==void 0&&(e.transmission=n.transmissionFactor),n.transmissionTexture!==void 0&&s.push(this.parser.assignTexture(e,"transmissionMap",n.transmissionTexture)),Promise.all(s)}}class ae{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_VOLUME}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];e.thickness=n.thicknessFactor!==void 0?n.thicknessFactor:0,n.thicknessTexture!==void 0&&s.push(this.parser.assignTexture(e,"thicknessMap",n.thicknessTexture)),e.attenuationDistance=n.attenuationDistance||1/0;const r=n.attenuationColor||[1,1,1];return e.attenuationColor=new h.Color().setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace),Promise.all(s)}}class ce{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_IOR}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||(e.ior=n.ior!==void 0?n.ior:1.5),Promise.resolve()}}class le{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_SPECULAR}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];e.specularIntensity=n.specularFactor!==void 0?n.specularFactor:1,n.specularTexture!==void 0&&s.push(this.parser.assignTexture(e,"specularIntensityMap",n.specularTexture));const r=n.specularColorFactor||[1,1,1];return e.specularColor=new h.Color().setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace),n.specularColorTexture!==void 0&&s.push(this.parser.assignTexture(e,"specularColorMap",n.specularColorTexture,h.SRGBColorSpace)),Promise.all(s)}}class ue{constructor(t){this.parser=t,this.name=T.EXT_MATERIALS_BUMP}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return e.bumpScale=n.bumpFactor!==void 0?n.bumpFactor:1,n.bumpTexture!==void 0&&s.push(this.parser.assignTexture(e,"bumpMap",n.bumpTexture)),Promise.all(s)}}class he{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_ANISOTROPY}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.anisotropyStrength!==void 0&&(e.anisotropy=n.anisotropyStrength),n.anisotropyRotation!==void 0&&(e.anisotropyRotation=n.anisotropyRotation),n.anisotropyTexture!==void 0&&s.push(this.parser.assignTexture(e,"anisotropyMap",n.anisotropyTexture)),Promise.all(s)}}class fe{constructor(t){this.parser=t,this.name=T.KHR_TEXTURE_BASISU}loadTexture(t){const e=this.parser,n=e.json,s=n.textures[t];if(!s.extensions||!s.extensions[this.name])return null;const r=s.extensions[this.name],o=e.options.ktx2Loader;if(!o){if(n.extensionsRequired&&n.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return e.loadTextureImage(t,r.source,o)}}class de{constructor(t){this.parser=t,this.name=T.EXT_TEXTURE_WEBP}loadTexture(t){const e=this.name,n=this.parser,s=n.json,r=s.textures[t];if(!r.extensions||!r.extensions[e])return null;const o=r.extensions[e],a=s.images[o.source];let i=n.textureLoader;if(a.uri){const c=n.options.manager.getHandler(a.uri);c!==null&&(i=c)}return n.loadTextureImage(t,o.source,i)}}class pe{constructor(t){this.parser=t,this.name=T.EXT_TEXTURE_AVIF}loadTexture(t){const e=this.name,n=this.parser,s=n.json,r=s.textures[t];if(!r.extensions||!r.extensions[e])return null;const o=r.extensions[e],a=s.images[o.source];let i=n.textureLoader;if(a.uri){const c=n.options.manager.getHandler(a.uri);c!==null&&(i=c)}return n.loadTextureImage(t,o.source,i)}}class K{constructor(t,e){this.name=e,this.parser=t}loadBufferView(t){const e=this.parser.json,n=e.bufferViews[t];if(n.extensions&&n.extensions[this.name]){const s=n.extensions[this.name],r=this.parser.getDependency("buffer",s.buffer),o=this.parser.options.meshoptDecoder;if(!o||!o.supported){if(e.extensionsRequired&&e.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return r.then(function(a){const i=s.byteOffset||0,c=s.byteLength||0,u=s.count,l=s.byteStride,f=new Uint8Array(a,i,c);return o.decodeGltfBufferAsync?o.decodeGltfBufferAsync(u,l,f,s.mode,s.filter).then(function(p){return p.buffer}):o.ready.then(function(){const p=new ArrayBuffer(u*l);return o.decodeGltfBuffer(new Uint8Array(p),u,l,f,s.mode,s.filter),p})})}else return null}}class me{constructor(t){this.name=T.EXT_MESH_GPU_INSTANCING,this.parser=t}createNodeMesh(t){const e=this.parser.json,n=e.nodes[t];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;const s=e.meshes[n.mesh];for(const c of s.primitives)if(c.mode!==S.TRIANGLES&&c.mode!==S.TRIANGLE_STRIP&&c.mode!==S.TRIANGLE_FAN&&c.mode!==void 0)return null;const o=n.extensions[this.name].attributes,a=[],i={};for(const c in o)a.push(this.parser.getDependency("accessor",o[c]).then(u=>(i[c]=u,i[c])));return a.length<1?null:(a.push(this.parser.createNodeMesh(t)),Promise.all(a).then(c=>{const u=c.pop(),l=u.isGroup?u.children:[u],f=c[0].count,p=[];for(const m of l){const M=new h.Matrix4,g=new h.Vector3,R=new h.Quaternion,A=new h.Vector3(1,1,1),x=new h.InstancedMesh(m.geometry,m.material,f);for(let E=0;E<f;E++)i.TRANSLATION&&g.fromBufferAttribute(i.TRANSLATION,E),i.ROTATION&&R.fromBufferAttribute(i.ROTATION,E),i.SCALE&&A.fromBufferAttribute(i.SCALE,E),x.setMatrixAt(E,M.compose(g,R,A));for(const E in i)if(E==="_COLOR_0"){const L=i[E];x.instanceColor=new h.InstancedBufferAttribute(L.array,L.itemSize,L.normalized)}else E!=="TRANSLATION"&&E!=="ROTATION"&&E!=="SCALE"&&m.geometry.setAttribute(E,i[E]);h.Object3D.prototype.copy.call(x,m),this.parser.assignFinalMaterial(x),p.push(x)}return u.isGroup?(u.clear(),u.add(...p),u):p[0]}))}}const W="glTF",F=12,j={JSON:1313821514,BIN:5130562};class ge{constructor(t){this.name=T.KHR_BINARY_GLTF,this.content=null,this.body=null;const e=new DataView(t,0,F),n=new TextDecoder;if(this.header={magic:n.decode(new Uint8Array(t.slice(0,4))),version:e.getUint32(4,!0),length:e.getUint32(8,!0)},this.header.magic!==W)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const s=this.header.length-F,r=new DataView(t,F);let o=0;for(;o<s;){const a=r.getUint32(o,!0);o+=4;const i=r.getUint32(o,!0);if(o+=4,i===j.JSON){const c=new Uint8Array(t,F+o,a);this.content=n.decode(c)}else if(i===j.BIN){const c=F+o;this.body=t.slice(c,c+a)}o+=a}if(this.content===null)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class Te{constructor(t,e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=T.KHR_DRACO_MESH_COMPRESSION,this.json=t,this.dracoLoader=e,this.dracoLoader.preload()}decodePrimitive(t,e){const n=this.json,s=this.dracoLoader,r=t.extensions[this.name].bufferView,o=t.extensions[this.name].attributes,a={},i={},c={};for(const u in o){const l=B[u]||u.toLowerCase();a[l]=o[u]}for(const u in t.attributes){const l=B[u]||u.toLowerCase();if(o[u]!==void 0){const f=n.accessors[t.attributes[u]],p=O[f.componentType];c[l]=p.name,i[l]=f.normalized===!0}}return e.getDependency("bufferView",r).then(function(u){return new Promise(function(l,f){s.decodeDracoFile(u,function(p){for(const m in p.attributes){const M=p.attributes[m],g=i[m];g!==void 0&&(M.normalized=g)}l(p)},a,c,h.LinearSRGBColorSpace,f)})})}}class Re{constructor(){this.name=T.KHR_TEXTURE_TRANSFORM}extendTexture(t,e){return(e.texCoord===void 0||e.texCoord===t.channel)&&e.offset===void 0&&e.rotation===void 0&&e.scale===void 0||(t=t.clone(),e.texCoord!==void 0&&(t.channel=e.texCoord),e.offset!==void 0&&t.offset.fromArray(e.offset),e.rotation!==void 0&&(t.rotation=e.rotation),e.scale!==void 0&&t.repeat.fromArray(e.scale),t.needsUpdate=!0),t}}class Me{constructor(){this.name=T.KHR_MESH_QUANTIZATION}}class Y extends h.Interpolant{constructor(t,e,n,s){super(t,e,n,s)}copySampleValue_(t){const e=this.resultBuffer,n=this.sampleValues,s=this.valueSize,r=t*s*3+s;for(let o=0;o!==s;o++)e[o]=n[r+o];return e}interpolate_(t,e,n,s){const r=this.resultBuffer,o=this.sampleValues,a=this.valueSize,i=a*2,c=a*3,u=s-e,l=(n-e)/u,f=l*l,p=f*l,m=t*c,M=m-c,g=-2*p+3*f,R=p-f,A=1-g,x=R-f+l;for(let E=0;E!==a;E++){const L=o[M+E+a],b=o[M+E+i]*u,y=o[m+E+a],P=o[m+E]*u;r[E]=A*L+x*b+g*y+R*P}return r}}const Ee=new h.Quaternion;class xe extends Y{interpolate_(t,e,n,s){const r=super.interpolate_(t,e,n,s);return Ee.fromArray(r).normalize().toArray(r),r}}const S={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},O={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},V={9728:h.NearestFilter,9729:h.LinearFilter,9984:h.NearestMipmapNearestFilter,9985:h.LinearMipmapNearestFilter,9986:h.NearestMipmapLinearFilter,9987:h.LinearMipmapLinearFilter},z={33071:h.ClampToEdgeWrapping,33648:h.MirroredRepeatWrapping,10497:h.RepeatWrapping},D={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},B={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},N={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},Ae={CUBICSPLINE:void 0,LINEAR:h.InterpolateLinear,STEP:h.InterpolateDiscrete},G={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"};function _e(d){return d.DefaultMaterial===void 0&&(d.DefaultMaterial=new h.MeshStandardMaterial({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:h.FrontSide})),d.DefaultMaterial}function I(d,t,e){for(const n in e.extensions)d[n]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[n]=e.extensions[n])}function w(d,t){t.extras!==void 0&&(typeof t.extras=="object"?Object.assign(d.userData,t.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+t.extras))}function Le(d,t,e){let n=!1,s=!1,r=!1;for(let c=0,u=t.length;c<u;c++){const l=t[c];if(l.POSITION!==void 0&&(n=!0),l.NORMAL!==void 0&&(s=!0),l.COLOR_0!==void 0&&(r=!0),n&&s&&r)break}if(!n&&!s&&!r)return Promise.resolve(d);const o=[],a=[],i=[];for(let c=0,u=t.length;c<u;c++){const l=t[c];if(n){const f=l.POSITION!==void 0?e.getDependency("accessor",l.POSITION):d.attributes.position;o.push(f)}if(s){const f=l.NORMAL!==void 0?e.getDependency("accessor",l.NORMAL):d.attributes.normal;a.push(f)}if(r){const f=l.COLOR_0!==void 0?e.getDependency("accessor",l.COLOR_0):d.attributes.color;i.push(f)}}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(i)]).then(function(c){const u=c[0],l=c[1],f=c[2];return n&&(d.morphAttributes.position=u),s&&(d.morphAttributes.normal=l),r&&(d.morphAttributes.color=f),d.morphTargetsRelative=!0,d})}function Se(d,t){if(d.updateMorphTargets(),t.weights!==void 0)for(let e=0,n=t.weights.length;e<n;e++)d.morphTargetInfluences[e]=t.weights[e];if(t.extras&&Array.isArray(t.extras.targetNames)){const e=t.extras.targetNames;if(d.morphTargetInfluences.length===e.length){d.morphTargetDictionary={};for(let n=0,s=e.length;n<s;n++)d.morphTargetDictionary[e[n]]=n}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function ye(d){let t;const e=d.extensions&&d.extensions[T.KHR_DRACO_MESH_COMPRESSION];if(e?t="draco:"+e.bufferView+":"+e.indices+":"+v(e.attributes):t=d.indices+":"+v(d.attributes)+":"+d.mode,d.targets!==void 0)for(let n=0,s=d.targets.length;n<s;n++)t+=":"+v(d.targets[n]);return t}function v(d){let t="";const e=Object.keys(d).sort();for(let n=0,s=e.length;n<s;n++)t+=e[n]+":"+d[e[n]]+";";return t}function U(d){switch(d){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}function we(d){return d.search(/\.jpe?g($|\?)/i)>0||d.search(/^data\:image\/jpeg/)===0?"image/jpeg":d.search(/\.webp($|\?)/i)>0||d.search(/^data\:image\/webp/)===0?"image/webp":d.search(/\.ktx2($|\?)/i)>0||d.search(/^data\:image\/ktx2/)===0?"image/ktx2":"image/png"}const be=new h.Matrix4;class Ne{constructor(t={},e={}){this.json=t,this.extensions={},this.plugins={},this.options=e,this.cache=new Z,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,s=-1,r=!1,o=-1;if(typeof navigator<"u"&&typeof navigator.userAgent<"u"){const a=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(a)===!0;const i=a.match(/Version\/(\d+)/);s=n&&i?parseInt(i[1],10):-1,r=a.indexOf("Firefox")>-1,o=r?a.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>"u"||n&&s<17||r&&o<98?this.textureLoader=new h.TextureLoader(this.options.manager):this.textureLoader=new h.ImageBitmapLoader(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new h.FileLoader(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(t){this.extensions=t}setPlugins(t){this.plugins=t}parse(t,e){const n=this,s=this.json,r=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(o){return o._markDefs&&o._markDefs()}),Promise.all(this._invokeAll(function(o){return o.beforeRoot&&o.beforeRoot()})).then(function(){return Promise.all([n.getDependencies("scene"),n.getDependencies("animation"),n.getDependencies("camera")])}).then(function(o){const a={scene:o[0][s.scene||0],scenes:o[0],animations:o[1],cameras:o[2],asset:s.asset,parser:n,userData:{}};return I(r,a,s),w(a,s),Promise.all(n._invokeAll(function(i){return i.afterRoot&&i.afterRoot(a)})).then(function(){for(const i of a.scenes)i.updateMatrixWorld();t(a)})}).catch(e)}_markDefs(){const t=this.json.nodes||[],e=this.json.skins||[],n=this.json.meshes||[];for(let s=0,r=e.length;s<r;s++){const o=e[s].joints;for(let a=0,i=o.length;a<i;a++)t[o[a]].isBone=!0}for(let s=0,r=t.length;s<r;s++){const o=t[s];o.mesh!==void 0&&(this._addNodeRef(this.meshCache,o.mesh),o.skin!==void 0&&(n[o.mesh].isSkinnedMesh=!0)),o.camera!==void 0&&this._addNodeRef(this.cameraCache,o.camera)}}_addNodeRef(t,e){e!==void 0&&(t.refs[e]===void 0&&(t.refs[e]=t.uses[e]=0),t.refs[e]++)}_getNodeRef(t,e,n){if(t.refs[e]<=1)return n;const s=n.clone(),r=(o,a)=>{const i=this.associations.get(o);i!=null&&this.associations.set(a,i);for(const[c,u]of o.children.entries())r(u,a.children[c])};return r(n,s),s.name+="_instance_"+t.uses[e]++,s}_invokeOne(t){const e=Object.values(this.plugins);e.push(this);for(let n=0;n<e.length;n++){const s=t(e[n]);if(s)return s}return null}_invokeAll(t){const e=Object.values(this.plugins);e.unshift(this);const n=[];for(let s=0;s<e.length;s++){const r=t(e[s]);r&&n.push(r)}return n}getDependency(t,e){const n=t+":"+e;let s=this.cache.get(n);if(!s){switch(t){case"scene":s=this.loadScene(e);break;case"node":s=this._invokeOne(function(r){return r.loadNode&&r.loadNode(e)});break;case"mesh":s=this._invokeOne(function(r){return r.loadMesh&&r.loadMesh(e)});break;case"accessor":s=this.loadAccessor(e);break;case"bufferView":s=this._invokeOne(function(r){return r.loadBufferView&&r.loadBufferView(e)});break;case"buffer":s=this.loadBuffer(e);break;case"material":s=this._invokeOne(function(r){return r.loadMaterial&&r.loadMaterial(e)});break;case"texture":s=this._invokeOne(function(r){return r.loadTexture&&r.loadTexture(e)});break;case"skin":s=this.loadSkin(e);break;case"animation":s=this._invokeOne(function(r){return r.loadAnimation&&r.loadAnimation(e)});break;case"camera":s=this.loadCamera(e);break;default:if(s=this._invokeOne(function(r){return r!=this&&r.getDependency&&r.getDependency(t,e)}),!s)throw new Error("Unknown type: "+t);break}this.cache.add(n,s)}return s}getDependencies(t){let e=this.cache.get(t);if(!e){const n=this,s=this.json[t+(t==="mesh"?"es":"s")]||[];e=Promise.all(s.map(function(r,o){return n.getDependency(t,o)})),this.cache.add(t,e)}return e}loadBuffer(t){const e=this.json.buffers[t],n=this.fileLoader;if(e.type&&e.type!=="arraybuffer")throw new Error("THREE.GLTFLoader: "+e.type+" buffer type is not supported.");if(e.uri===void 0&&t===0)return Promise.resolve(this.extensions[T.KHR_BINARY_GLTF].body);const s=this.options;return new Promise(function(r,o){n.load(h.LoaderUtils.resolveURL(e.uri,s.path),r,void 0,function(){o(new Error('THREE.GLTFLoader: Failed to load buffer "'+e.uri+'".'))})})}loadBufferView(t){const e=this.json.bufferViews[t];return this.getDependency("buffer",e.buffer).then(function(n){const s=e.byteLength||0,r=e.byteOffset||0;return n.slice(r,r+s)})}loadAccessor(t){const e=this,n=this.json,s=this.json.accessors[t];if(s.bufferView===void 0&&s.sparse===void 0){const o=D[s.type],a=O[s.componentType],i=s.normalized===!0,c=new a(s.count*o);return Promise.resolve(new h.BufferAttribute(c,o,i))}const r=[];return s.bufferView!==void 0?r.push(this.getDependency("bufferView",s.bufferView)):r.push(null),s.sparse!==void 0&&(r.push(this.getDependency("bufferView",s.sparse.indices.bufferView)),r.push(this.getDependency("bufferView",s.sparse.values.bufferView))),Promise.all(r).then(function(o){const a=o[0],i=D[s.type],c=O[s.componentType],u=c.BYTES_PER_ELEMENT,l=u*i,f=s.byteOffset||0,p=s.bufferView!==void 0?n.bufferViews[s.bufferView].byteStride:void 0,m=s.normalized===!0;let M,g;if(p&&p!==l){const R=Math.floor(f/p),A="InterleavedBuffer:"+s.bufferView+":"+s.componentType+":"+R+":"+s.count;let x=e.cache.get(A);x||(M=new c(a,R*p,s.count*p/u),x=new h.InterleavedBuffer(M,p/u),e.cache.add(A,x)),g=new h.InterleavedBufferAttribute(x,i,f%p/u,m)}else a===null?M=new c(s.count*i):M=new c(a,f,s.count*i),g=new h.BufferAttribute(M,i,m);if(s.sparse!==void 0){const R=D.SCALAR,A=O[s.sparse.indices.componentType],x=s.sparse.indices.byteOffset||0,E=s.sparse.values.byteOffset||0,L=new A(o[1],x,s.sparse.count*R),b=new c(o[2],E,s.sparse.count*i);a!==null&&(g=new h.BufferAttribute(g.array.slice(),g.itemSize,g.normalized)),g.normalized=!1;for(let y=0,P=L.length;y<P;y++){const C=L[y];if(g.setX(C,b[y*i]),i>=2&&g.setY(C,b[y*i+1]),i>=3&&g.setZ(C,b[y*i+2]),i>=4&&g.setW(C,b[y*i+3]),i>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}g.normalized=m}return g})}loadTexture(t){const e=this.json,n=this.options,r=e.textures[t].source,o=e.images[r];let a=this.textureLoader;if(o.uri){const i=n.manager.getHandler(o.uri);i!==null&&(a=i)}return this.loadTextureImage(t,r,a)}loadTextureImage(t,e,n){const s=this,r=this.json,o=r.textures[t],a=r.images[e],i=(a.uri||a.bufferView)+":"+o.sampler;if(this.textureCache[i])return this.textureCache[i];const c=this.loadImageSource(e,n).then(function(u){u.flipY=!1,u.name=o.name||a.name||"",u.name===""&&typeof a.uri=="string"&&a.uri.startsWith("data:image/")===!1&&(u.name=a.uri);const f=(r.samplers||{})[o.sampler]||{};return u.magFilter=V[f.magFilter]||h.LinearFilter,u.minFilter=V[f.minFilter]||h.LinearMipmapLinearFilter,u.wrapS=z[f.wrapS]||h.RepeatWrapping,u.wrapT=z[f.wrapT]||h.RepeatWrapping,u.generateMipmaps=!u.isCompressedTexture&&u.minFilter!==h.NearestFilter&&u.minFilter!==h.LinearFilter,s.associations.set(u,{textures:t}),u}).catch(function(){return null});return this.textureCache[i]=c,c}loadImageSource(t,e){const n=this,s=this.json,r=this.options;if(this.sourceCache[t]!==void 0)return this.sourceCache[t].then(l=>l.clone());const o=s.images[t],a=self.URL||self.webkitURL;let i=o.uri||"",c=!1;if(o.bufferView!==void 0)i=n.getDependency("bufferView",o.bufferView).then(function(l){c=!0;const f=new Blob([l],{type:o.mimeType});return i=a.createObjectURL(f),i});else if(o.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+t+" is missing URI and bufferView");const u=Promise.resolve(i).then(function(l){return new Promise(function(f,p){let m=f;e.isImageBitmapLoader===!0&&(m=function(M){const g=new h.Texture(M);g.needsUpdate=!0,f(g)}),e.load(h.LoaderUtils.resolveURL(l,r.path),m,void 0,p)})}).then(function(l){return c===!0&&a.revokeObjectURL(i),w(l,o),l.userData.mimeType=o.mimeType||we(o.uri),l}).catch(function(l){throw console.error("THREE.GLTFLoader: Couldn't load texture",i),l});return this.sourceCache[t]=u,u}assignTexture(t,e,n,s){const r=this;return this.getDependency("texture",n.index).then(function(o){if(!o)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(o=o.clone(),o.channel=n.texCoord),r.extensions[T.KHR_TEXTURE_TRANSFORM]){const a=n.extensions!==void 0?n.extensions[T.KHR_TEXTURE_TRANSFORM]:void 0;if(a){const i=r.associations.get(o);o=r.extensions[T.KHR_TEXTURE_TRANSFORM].extendTexture(o,a),r.associations.set(o,i)}}return s!==void 0&&(o.colorSpace=s),t[e]=o,o})}assignFinalMaterial(t){const e=t.geometry;let n=t.material;const s=e.attributes.tangent===void 0,r=e.attributes.color!==void 0,o=e.attributes.normal===void 0;if(t.isPoints){const a="PointsMaterial:"+n.uuid;let i=this.cache.get(a);i||(i=new h.PointsMaterial,h.Material.prototype.copy.call(i,n),i.color.copy(n.color),i.map=n.map,i.sizeAttenuation=!1,this.cache.add(a,i)),n=i}else if(t.isLine){const a="LineBasicMaterial:"+n.uuid;let i=this.cache.get(a);i||(i=new h.LineBasicMaterial,h.Material.prototype.copy.call(i,n),i.color.copy(n.color),i.map=n.map,this.cache.add(a,i)),n=i}if(s||r||o){let a="ClonedMaterial:"+n.uuid+":";s&&(a+="derivative-tangents:"),r&&(a+="vertex-colors:"),o&&(a+="flat-shading:");let i=this.cache.get(a);i||(i=n.clone(),r&&(i.vertexColors=!0),o&&(i.flatShading=!0),s&&(i.normalScale&&(i.normalScale.y*=-1),i.clearcoatNormalScale&&(i.clearcoatNormalScale.y*=-1)),this.cache.add(a,i),this.associations.set(i,this.associations.get(n))),n=i}t.material=n}getMaterialType(){return h.MeshStandardMaterial}loadMaterial(t){const e=this,n=this.json,s=this.extensions,r=n.materials[t];let o;const a={},i=r.extensions||{},c=[];if(i[T.KHR_MATERIALS_UNLIT]){const l=s[T.KHR_MATERIALS_UNLIT];o=l.getMaterialType(),c.push(l.extendParams(a,r,e))}else{const l=r.pbrMetallicRoughness||{};if(a.color=new h.Color(1,1,1),a.opacity=1,Array.isArray(l.baseColorFactor)){const f=l.baseColorFactor;a.color.setRGB(f[0],f[1],f[2],h.LinearSRGBColorSpace),a.opacity=f[3]}l.baseColorTexture!==void 0&&c.push(e.assignTexture(a,"map",l.baseColorTexture,h.SRGBColorSpace)),a.metalness=l.metallicFactor!==void 0?l.metallicFactor:1,a.roughness=l.roughnessFactor!==void 0?l.roughnessFactor:1,l.metallicRoughnessTexture!==void 0&&(c.push(e.assignTexture(a,"metalnessMap",l.metallicRoughnessTexture)),c.push(e.assignTexture(a,"roughnessMap",l.metallicRoughnessTexture))),o=this._invokeOne(function(f){return f.getMaterialType&&f.getMaterialType(t)}),c.push(Promise.all(this._invokeAll(function(f){return f.extendMaterialParams&&f.extendMaterialParams(t,a)})))}r.doubleSided===!0&&(a.side=h.DoubleSide);const u=r.alphaMode||G.OPAQUE;if(u===G.BLEND?(a.transparent=!0,a.depthWrite=!1):(a.transparent=!1,u===G.MASK&&(a.alphaTest=r.alphaCutoff!==void 0?r.alphaCutoff:.5)),r.normalTexture!==void 0&&o!==h.MeshBasicMaterial&&(c.push(e.assignTexture(a,"normalMap",r.normalTexture)),a.normalScale=new h.Vector2(1,1),r.normalTexture.scale!==void 0)){const l=r.normalTexture.scale;a.normalScale.set(l,l)}if(r.occlusionTexture!==void 0&&o!==h.MeshBasicMaterial&&(c.push(e.assignTexture(a,"aoMap",r.occlusionTexture)),r.occlusionTexture.strength!==void 0&&(a.aoMapIntensity=r.occlusionTexture.strength)),r.emissiveFactor!==void 0&&o!==h.MeshBasicMaterial){const l=r.emissiveFactor;a.emissive=new h.Color().setRGB(l[0],l[1],l[2],h.LinearSRGBColorSpace)}return r.emissiveTexture!==void 0&&o!==h.MeshBasicMaterial&&c.push(e.assignTexture(a,"emissiveMap",r.emissiveTexture,h.SRGBColorSpace)),Promise.all(c).then(function(){const l=new o(a);return r.name&&(l.name=r.name),w(l,r),e.associations.set(l,{materials:t}),r.extensions&&I(s,l,r),l})}createUniqueName(t){const e=h.PropertyBinding.sanitizeNodeName(t||"");return e in this.nodeNamesUsed?e+"_"+ ++this.nodeNamesUsed[e]:(this.nodeNamesUsed[e]=0,e)}loadGeometries(t){const e=this,n=this.extensions,s=this.primitiveCache;function r(a){return n[T.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(a,e).then(function(i){return X(i,a,e)})}const o=[];for(let a=0,i=t.length;a<i;a++){const c=t[a],u=ye(c),l=s[u];if(l)o.push(l.promise);else{let f;c.extensions&&c.extensions[T.KHR_DRACO_MESH_COMPRESSION]?f=r(c):f=X(new h.BufferGeometry,c,e),s[u]={primitive:c,promise:f},o.push(f)}}return Promise.all(o)}loadMesh(t){const e=this,n=this.json,s=this.extensions,r=n.meshes[t],o=r.primitives,a=[];for(let i=0,c=o.length;i<c;i++){const u=o[i].material===void 0?_e(this.cache):this.getDependency("material",o[i].material);a.push(u)}return a.push(e.loadGeometries(o)),Promise.all(a).then(function(i){const c=i.slice(0,i.length-1),u=i[i.length-1],l=[];for(let p=0,m=u.length;p<m;p++){const M=u[p],g=o[p];let R;const A=c[p];if(g.mode===S.TRIANGLES||g.mode===S.TRIANGLE_STRIP||g.mode===S.TRIANGLE_FAN||g.mode===void 0)R=r.isSkinnedMesh===!0?new h.SkinnedMesh(M,A):new h.Mesh(M,A),R.isSkinnedMesh===!0&&R.normalizeSkinWeights(),g.mode===S.TRIANGLE_STRIP?R.geometry=h.toTrianglesDrawMode(R.geometry,h.TriangleStripDrawMode):g.mode===S.TRIANGLE_FAN&&(R.geometry=h.toTrianglesDrawMode(R.geometry,h.TriangleFanDrawMode));else if(g.mode===S.LINES)R=new h.LineSegments(M,A);else if(g.mode===S.LINE_STRIP)R=new h.Line(M,A);else if(g.mode===S.LINE_LOOP)R=new h.LineLoop(M,A);else if(g.mode===S.POINTS)R=new h.Points(M,A);else throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+g.mode);Object.keys(R.geometry.morphAttributes).length>0&&Se(R,r),R.name=e.createUniqueName(r.name||"mesh_"+t),w(R,r),g.extensions&&I(s,R,g),e.assignFinalMaterial(R),l.push(R)}for(let p=0,m=l.length;p<m;p++)e.associations.set(l[p],{meshes:t,primitives:p});if(l.length===1)return r.extensions&&I(s,l[0],r),l[0];const f=new h.Group;r.extensions&&I(s,f,r),e.associations.set(f,{meshes:t});for(let p=0,m=l.length;p<m;p++)f.add(l[p]);return f})}loadCamera(t){let e;const n=this.json.cameras[t],s=n[n.type];if(!s){console.warn("THREE.GLTFLoader: Missing camera parameters.");return}return n.type==="perspective"?e=new h.PerspectiveCamera(h.MathUtils.radToDeg(s.yfov),s.aspectRatio||1,s.znear||1,s.zfar||2e6):n.type==="orthographic"&&(e=new h.OrthographicCamera(-s.xmag,s.xmag,s.ymag,-s.ymag,s.znear,s.zfar)),n.name&&(e.name=this.createUniqueName(n.name)),w(e,n),Promise.resolve(e)}loadSkin(t){const e=this.json.skins[t],n=[];for(let s=0,r=e.joints.length;s<r;s++)n.push(this._loadNodeShallow(e.joints[s]));return e.inverseBindMatrices!==void 0?n.push(this.getDependency("accessor",e.inverseBindMatrices)):n.push(null),Promise.all(n).then(function(s){const r=s.pop(),o=s,a=[],i=[];for(let c=0,u=o.length;c<u;c++){const l=o[c];if(l){a.push(l);const f=new h.Matrix4;r!==null&&f.fromArray(r.array,c*16),i.push(f)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',e.joints[c])}return new h.Skeleton(a,i)})}loadAnimation(t){const e=this.json,n=this,s=e.animations[t],r=s.name?s.name:"animation_"+t,o=[],a=[],i=[],c=[],u=[];for(let l=0,f=s.channels.length;l<f;l++){const p=s.channels[l],m=s.samplers[p.sampler],M=p.target,g=M.node,R=s.parameters!==void 0?s.parameters[m.input]:m.input,A=s.parameters!==void 0?s.parameters[m.output]:m.output;M.node!==void 0&&(o.push(this.getDependency("node",g)),a.push(this.getDependency("accessor",R)),i.push(this.getDependency("accessor",A)),c.push(m),u.push(M))}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(i),Promise.all(c),Promise.all(u)]).then(function(l){const f=l[0],p=l[1],m=l[2],M=l[3],g=l[4],R=[];for(let x=0,E=f.length;x<E;x++){const L=f[x],b=p[x],y=m[x],P=M[x],C=g[x];if(L===void 0)continue;L.updateMatrix&&L.updateMatrix();const k=n._createAnimationTracks(L,b,y,P,C);if(k)for(let H=0;H<k.length;H++)R.push(k[H])}const A=new h.AnimationClip(r,void 0,R);return w(A,s),A})}createNodeMesh(t){const e=this.json,n=this,s=e.nodes[t];return s.mesh===void 0?null:n.getDependency("mesh",s.mesh).then(function(r){const o=n._getNodeRef(n.meshCache,s.mesh,r);return s.weights!==void 0&&o.traverse(function(a){if(a.isMesh)for(let i=0,c=s.weights.length;i<c;i++)a.morphTargetInfluences[i]=s.weights[i]}),o})}loadNode(t){const e=this.json,n=this,s=e.nodes[t],r=n._loadNodeShallow(t),o=[],a=s.children||[];for(let c=0,u=a.length;c<u;c++)o.push(n.getDependency("node",a[c]));const i=s.skin===void 0?Promise.resolve(null):n.getDependency("skin",s.skin);return Promise.all([r,Promise.all(o),i]).then(function(c){const u=c[0],l=c[1],f=c[2];f!==null&&u.traverse(function(p){p.isSkinnedMesh&&p.bind(f,be)});for(let p=0,m=l.length;p<m;p++)u.add(l[p]);if(u.userData.pivot!==void 0&&l.length>0){const p=u.userData.pivot,m=l[0];u.pivot=new h.Vector3().fromArray(p),u.position.x-=p[0],u.position.y-=p[1],u.position.z-=p[2],m.position.set(0,0,0),delete u.userData.pivot}return u})}_loadNodeShallow(t){const e=this.json,n=this.extensions,s=this;if(this.nodeCache[t]!==void 0)return this.nodeCache[t];const r=e.nodes[t],o=r.name?s.createUniqueName(r.name):"",a=[],i=s._invokeOne(function(c){return c.createNodeMesh&&c.createNodeMesh(t)});return i&&a.push(i),r.camera!==void 0&&a.push(s.getDependency("camera",r.camera).then(function(c){return s._getNodeRef(s.cameraCache,r.camera,c)})),s._invokeAll(function(c){return c.createNodeAttachment&&c.createNodeAttachment(t)}).forEach(function(c){a.push(c)}),this.nodeCache[t]=Promise.all(a).then(function(c){let u;if(r.isBone===!0?u=new h.Bone:c.length>1?u=new h.Group:c.length===1?u=c[0]:u=new h.Object3D,u!==c[0])for(let l=0,f=c.length;l<f;l++)u.add(c[l]);if(r.name&&(u.userData.name=r.name,u.name=o),w(u,r),r.extensions&&I(n,u,r),r.matrix!==void 0){const l=new h.Matrix4;l.fromArray(r.matrix),u.applyMatrix4(l)}else r.translation!==void 0&&u.position.fromArray(r.translation),r.rotation!==void 0&&u.quaternion.fromArray(r.rotation),r.scale!==void 0&&u.scale.fromArray(r.scale);if(!s.associations.has(u))s.associations.set(u,{});else if(r.mesh!==void 0&&s.meshCache.refs[r.mesh]>1){const l=s.associations.get(u);s.associations.set(u,{...l})}return s.associations.get(u).nodes=t,u}),this.nodeCache[t]}loadScene(t){const e=this.extensions,n=this.json.scenes[t],s=this,r=new h.Group;n.name&&(r.name=s.createUniqueName(n.name)),w(r,n),n.extensions&&I(e,r,n);const o=n.nodes||[],a=[];for(let i=0,c=o.length;i<c;i++)a.push(s.getDependency("node",o[i]));return Promise.all(a).then(function(i){for(let u=0,l=i.length;u<l;u++){const f=i[u];f.parent!==null?r.add(Q(f)):r.add(f)}const c=u=>{const l=new Map;for(const[f,p]of s.associations)(f instanceof h.Material||f instanceof h.Texture)&&l.set(f,p);return u.traverse(f=>{const p=s.associations.get(f);p!=null&&l.set(f,p)}),l};return s.associations=c(r),r})}_createAnimationTracks(t,e,n,s,r){const o=[],a=t.name?t.name:t.uuid,i=[];N[r.path]===N.weights?t.traverse(function(f){f.morphTargetInfluences&&i.push(f.name?f.name:f.uuid)}):i.push(a);let c;switch(N[r.path]){case N.weights:c=h.NumberKeyframeTrack;break;case N.rotation:c=h.QuaternionKeyframeTrack;break;case N.translation:case N.scale:c=h.VectorKeyframeTrack;break;default:n.itemSize===1?c=h.NumberKeyframeTrack:c=h.VectorKeyframeTrack;break}const u=s.interpolation!==void 0?Ae[s.interpolation]:h.InterpolateLinear,l=this._getArrayFromAccessor(n);for(let f=0,p=i.length;f<p;f++){const m=new c(i[f]+"."+N[r.path],e.array,l,u);s.interpolation==="CUBICSPLINE"&&this._createCubicSplineTrackInterpolant(m),o.push(m)}return o}_getArrayFromAccessor(t){let e=t.array;if(t.normalized){const n=U(e.constructor),s=new Float32Array(e.length);for(let r=0,o=e.length;r<o;r++)s[r]=e[r]*n;e=s}return e}_createCubicSplineTrackInterpolant(t){t.createInterpolant=function(n){const s=this instanceof h.QuaternionKeyframeTrack?xe:Y;return new s(this.times,this.values,this.getValueSize()/3,n)},t.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function Ie(d,t,e){const n=t.attributes,s=new h.Box3;if(n.POSITION!==void 0){const a=e.json.accessors[n.POSITION],i=a.min,c=a.max;if(i!==void 0&&c!==void 0){if(s.set(new h.Vector3(i[0],i[1],i[2]),new h.Vector3(c[0],c[1],c[2])),a.normalized){const u=U(O[a.componentType]);s.min.multiplyScalar(u),s.max.multiplyScalar(u)}}else{console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");return}}else return;const r=t.targets;if(r!==void 0){const a=new h.Vector3,i=new h.Vector3;for(let c=0,u=r.length;c<u;c++){const l=r[c];if(l.POSITION!==void 0){const f=e.json.accessors[l.POSITION],p=f.min,m=f.max;if(p!==void 0&&m!==void 0){if(i.setX(Math.max(Math.abs(p[0]),Math.abs(m[0]))),i.setY(Math.max(Math.abs(p[1]),Math.abs(m[1]))),i.setZ(Math.max(Math.abs(p[2]),Math.abs(m[2]))),f.normalized){const M=U(O[f.componentType]);i.multiplyScalar(M)}a.max(i)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}s.expandByVector(a)}d.boundingBox=s;const o=new h.Sphere;s.getCenter(o.center),o.radius=s.min.distanceTo(s.max)/2,d.boundingSphere=o}function X(d,t,e){const n=t.attributes,s=[];function r(o,a){return e.getDependency("accessor",o).then(function(i){d.setAttribute(a,i)})}for(const o in n){const a=B[o]||o.toLowerCase();a in d.attributes||s.push(r(n[o],a))}if(t.indices!==void 0&&!d.index){const o=e.getDependency("accessor",t.indices).then(function(a){d.setIndex(a)});s.push(o)}return h.ColorManagement.workingColorSpace!==h.LinearSRGBColorSpace&&"COLOR_0"in n&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${h.ColorManagement.workingColorSpace}" not supported.`),w(d,t),Ie(d,t,e),Promise.all(s).then(function(){return t.targets!==void 0?Le(d,t.targets,e):d})}exports.GLTFLoader=J;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./duo-frame-BZ-XDtxc.js");function Q(d){const t=new Map,e=new Map,n=d.clone();return q(d,n,function(s,r){t.set(r,s),e.set(s,r)}),n.traverse(function(s){if(!s.isSkinnedMesh)return;const r=s,o=t.get(s),a=o.skeleton.bones;r.skeleton=o.skeleton.clone(),r.bindMatrix.copy(o.bindMatrix),r.skeleton.bones=a.map(function(i){return e.get(i)}),r.bind(r.skeleton,r.bindMatrix)}),n}function q(d,t,e){e(d,t);for(let n=0;n<d.children.length;n++)q(d.children[n],t.children[n],e)}class J extends h.Loader{constructor(t){super(t),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new ne(e)}),this.register(function(e){return new se(e)}),this.register(function(e){return new fe(e)}),this.register(function(e){return new de(e)}),this.register(function(e){return new pe(e)}),this.register(function(e){return new ie(e)}),this.register(function(e){return new oe(e)}),this.register(function(e){return new ae(e)}),this.register(function(e){return new ce(e)}),this.register(function(e){return new te(e)}),this.register(function(e){return new le(e)}),this.register(function(e){return new re(e)}),this.register(function(e){return new he(e)}),this.register(function(e){return new ue(e)}),this.register(function(e){return new $(e)}),this.register(function(e){return new K(e,T.EXT_MESHOPT_COMPRESSION)}),this.register(function(e){return new K(e,T.KHR_MESHOPT_COMPRESSION)}),this.register(function(e){return new me(e)})}load(t,e,n,s){const r=this;let o;if(this.resourcePath!=="")o=this.resourcePath;else if(this.path!==""){const c=h.LoaderUtils.extractUrlBase(t);o=h.LoaderUtils.resolveURL(c,this.path)}else o=h.LoaderUtils.extractUrlBase(t);this.manager.itemStart(t);const a=function(c){s?s(c):console.error(c),r.manager.itemError(t),r.manager.itemEnd(t)},i=new h.FileLoader(this.manager);i.setPath(this.path),i.setResponseType("arraybuffer"),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(t,function(c){try{r.parse(c,o,function(u){e(u),r.manager.itemEnd(t)},a)}catch(u){a(u)}},n,a)}setDRACOLoader(t){return this.dracoLoader=t,this}setKTX2Loader(t){return this.ktx2Loader=t,this}setMeshoptDecoder(t){return this.meshoptDecoder=t,this}register(t){return this.pluginCallbacks.indexOf(t)===-1&&this.pluginCallbacks.push(t),this}unregister(t){return this.pluginCallbacks.indexOf(t)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(t),1),this}parse(t,e,n,s){let r;const o={},a={},i=new TextDecoder;if(typeof t=="string")r=JSON.parse(t);else if(t instanceof ArrayBuffer)if(i.decode(new Uint8Array(t,0,4))===W){try{o[T.KHR_BINARY_GLTF]=new ge(t)}catch(l){s&&s(l);return}r=JSON.parse(o[T.KHR_BINARY_GLTF].content)}else r=JSON.parse(i.decode(t));else r=t;if(r.asset===void 0||r.asset.version[0]<2){s&&s(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));return}const c=new Ne(r,{path:e||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let u=0;u<this.pluginCallbacks.length;u++){const l=this.pluginCallbacks[u](c);l.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),a[l.name]=l,o[l.name]=!0}if(r.extensionsUsed)for(let u=0;u<r.extensionsUsed.length;++u){const l=r.extensionsUsed[u],f=r.extensionsRequired||[];switch(l){case T.KHR_MATERIALS_UNLIT:o[l]=new ee;break;case T.KHR_DRACO_MESH_COMPRESSION:o[l]=new Te(r,this.dracoLoader);break;case T.KHR_TEXTURE_TRANSFORM:o[l]=new Re;break;case T.KHR_MESH_QUANTIZATION:o[l]=new Me;break;default:f.indexOf(l)>=0&&a[l]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+l+'".')}}c.setExtensions(o),c.setPlugins(a),c.parse(n,s)}parseAsync(t,e){const n=this;return new Promise(function(s,r){n.parse(t,e,s,r)})}}function Z(){let d={};return{get:function(t){return d[t]},add:function(t,e){d[t]=e},remove:function(t){delete d[t]},removeAll:function(){d={}}}}function _(d,t,e){const n=d.json.materials[t];return n.extensions&&n.extensions[e]?n.extensions[e]:null}const T={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",KHR_MESHOPT_COMPRESSION:"KHR_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class ${constructor(t){this.parser=t,this.name=T.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const t=this.parser,e=this.parser.json.nodes||[];for(let n=0,s=e.length;n<s;n++){const r=e[n];r.extensions&&r.extensions[this.name]&&r.extensions[this.name].light!==void 0&&t._addNodeRef(this.cache,r.extensions[this.name].light)}}_loadLight(t){const e=this.parser,n="light:"+t;let s=e.cache.get(n);if(s)return s;const r=e.json,i=((r.extensions&&r.extensions[this.name]||{}).lights||[])[t];let c;const u=new h.Color(16777215);i.color!==void 0&&u.setRGB(i.color[0],i.color[1],i.color[2],h.LinearSRGBColorSpace);const l=i.range!==void 0?i.range:0;switch(i.type){case"directional":c=new h.DirectionalLight(u),c.target.position.set(0,0,-1),c.add(c.target);break;case"point":c=new h.PointLight(u),c.distance=l;break;case"spot":c=new h.SpotLight(u),c.distance=l,i.spot=i.spot||{},i.spot.innerConeAngle=i.spot.innerConeAngle!==void 0?i.spot.innerConeAngle:0,i.spot.outerConeAngle=i.spot.outerConeAngle!==void 0?i.spot.outerConeAngle:Math.PI/4,c.angle=i.spot.outerConeAngle,c.penumbra=1-i.spot.innerConeAngle/i.spot.outerConeAngle,c.target.position.set(0,0,-1),c.add(c.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+i.type)}return c.position.set(0,0,0),w(c,i),i.intensity!==void 0&&(c.intensity=i.intensity),c.name=e.createUniqueName(i.name||"light_"+t),s=Promise.resolve(c),e.cache.add(n,s),s}getDependency(t,e){if(t==="light")return this._loadLight(e)}createNodeAttachment(t){const e=this,n=this.parser,r=n.json.nodes[t],a=(r.extensions&&r.extensions[this.name]||{}).light;return a===void 0?null:this._loadLight(a).then(function(i){return n._getNodeRef(e.cache,a,i)})}}class ee{constructor(){this.name=T.KHR_MATERIALS_UNLIT}getMaterialType(){return h.MeshBasicMaterial}extendParams(t,e,n){const s=[];t.color=new h.Color(1,1,1),t.opacity=1;const r=e.pbrMetallicRoughness;if(r){if(Array.isArray(r.baseColorFactor)){const o=r.baseColorFactor;t.color.setRGB(o[0],o[1],o[2],h.LinearSRGBColorSpace),t.opacity=o[3]}r.baseColorTexture!==void 0&&s.push(n.assignTexture(t,"map",r.baseColorTexture,h.SRGBColorSpace))}return Promise.all(s)}}class te{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||n.emissiveStrength!==void 0&&(e.emissiveIntensity=n.emissiveStrength),Promise.resolve()}}class ne{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_CLEARCOAT}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];if(n.clearcoatFactor!==void 0&&(e.clearcoat=n.clearcoatFactor),n.clearcoatTexture!==void 0&&s.push(this.parser.assignTexture(e,"clearcoatMap",n.clearcoatTexture)),n.clearcoatRoughnessFactor!==void 0&&(e.clearcoatRoughness=n.clearcoatRoughnessFactor),n.clearcoatRoughnessTexture!==void 0&&s.push(this.parser.assignTexture(e,"clearcoatRoughnessMap",n.clearcoatRoughnessTexture)),n.clearcoatNormalTexture!==void 0&&(s.push(this.parser.assignTexture(e,"clearcoatNormalMap",n.clearcoatNormalTexture)),n.clearcoatNormalTexture.scale!==void 0)){const r=n.clearcoatNormalTexture.scale;e.clearcoatNormalScale=new h.Vector2(r,r)}return Promise.all(s)}}class se{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_DISPERSION}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||(e.dispersion=n.dispersion!==void 0?n.dispersion:0),Promise.resolve()}}class re{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_IRIDESCENCE}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.iridescenceFactor!==void 0&&(e.iridescence=n.iridescenceFactor),n.iridescenceTexture!==void 0&&s.push(this.parser.assignTexture(e,"iridescenceMap",n.iridescenceTexture)),n.iridescenceIor!==void 0&&(e.iridescenceIOR=n.iridescenceIor),e.iridescenceThicknessRange===void 0&&(e.iridescenceThicknessRange=[100,400]),n.iridescenceThicknessMinimum!==void 0&&(e.iridescenceThicknessRange[0]=n.iridescenceThicknessMinimum),n.iridescenceThicknessMaximum!==void 0&&(e.iridescenceThicknessRange[1]=n.iridescenceThicknessMaximum),n.iridescenceThicknessTexture!==void 0&&s.push(this.parser.assignTexture(e,"iridescenceThicknessMap",n.iridescenceThicknessTexture)),Promise.all(s)}}class ie{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_SHEEN}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];if(e.sheenColor=new h.Color(0,0,0),e.sheenRoughness=0,e.sheen=1,n.sheenColorFactor!==void 0){const r=n.sheenColorFactor;e.sheenColor.setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace)}return n.sheenRoughnessFactor!==void 0&&(e.sheenRoughness=n.sheenRoughnessFactor),n.sheenColorTexture!==void 0&&s.push(this.parser.assignTexture(e,"sheenColorMap",n.sheenColorTexture,h.SRGBColorSpace)),n.sheenRoughnessTexture!==void 0&&s.push(this.parser.assignTexture(e,"sheenRoughnessMap",n.sheenRoughnessTexture)),Promise.all(s)}}class oe{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_TRANSMISSION}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.transmissionFactor!==void 0&&(e.transmission=n.transmissionFactor),n.transmissionTexture!==void 0&&s.push(this.parser.assignTexture(e,"transmissionMap",n.transmissionTexture)),Promise.all(s)}}class ae{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_VOLUME}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];e.thickness=n.thicknessFactor!==void 0?n.thicknessFactor:0,n.thicknessTexture!==void 0&&s.push(this.parser.assignTexture(e,"thicknessMap",n.thicknessTexture)),e.attenuationDistance=n.attenuationDistance||1/0;const r=n.attenuationColor||[1,1,1];return e.attenuationColor=new h.Color().setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace),Promise.all(s)}}class ce{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_IOR}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);return n===null||(e.ior=n.ior!==void 0?n.ior:1.5),Promise.resolve()}}class le{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_SPECULAR}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];e.specularIntensity=n.specularFactor!==void 0?n.specularFactor:1,n.specularTexture!==void 0&&s.push(this.parser.assignTexture(e,"specularIntensityMap",n.specularTexture));const r=n.specularColorFactor||[1,1,1];return e.specularColor=new h.Color().setRGB(r[0],r[1],r[2],h.LinearSRGBColorSpace),n.specularColorTexture!==void 0&&s.push(this.parser.assignTexture(e,"specularColorMap",n.specularColorTexture,h.SRGBColorSpace)),Promise.all(s)}}class ue{constructor(t){this.parser=t,this.name=T.EXT_MATERIALS_BUMP}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return e.bumpScale=n.bumpFactor!==void 0?n.bumpFactor:1,n.bumpTexture!==void 0&&s.push(this.parser.assignTexture(e,"bumpMap",n.bumpTexture)),Promise.all(s)}}class he{constructor(t){this.parser=t,this.name=T.KHR_MATERIALS_ANISOTROPY}getMaterialType(t){return _(this.parser,t,this.name)!==null?h.MeshPhysicalMaterial:null}extendMaterialParams(t,e){const n=_(this.parser,t,this.name);if(n===null)return Promise.resolve();const s=[];return n.anisotropyStrength!==void 0&&(e.anisotropy=n.anisotropyStrength),n.anisotropyRotation!==void 0&&(e.anisotropyRotation=n.anisotropyRotation),n.anisotropyTexture!==void 0&&s.push(this.parser.assignTexture(e,"anisotropyMap",n.anisotropyTexture)),Promise.all(s)}}class fe{constructor(t){this.parser=t,this.name=T.KHR_TEXTURE_BASISU}loadTexture(t){const e=this.parser,n=e.json,s=n.textures[t];if(!s.extensions||!s.extensions[this.name])return null;const r=s.extensions[this.name],o=e.options.ktx2Loader;if(!o){if(n.extensionsRequired&&n.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return e.loadTextureImage(t,r.source,o)}}class de{constructor(t){this.parser=t,this.name=T.EXT_TEXTURE_WEBP}loadTexture(t){const e=this.name,n=this.parser,s=n.json,r=s.textures[t];if(!r.extensions||!r.extensions[e])return null;const o=r.extensions[e],a=s.images[o.source];let i=n.textureLoader;if(a.uri){const c=n.options.manager.getHandler(a.uri);c!==null&&(i=c)}return n.loadTextureImage(t,o.source,i)}}class pe{constructor(t){this.parser=t,this.name=T.EXT_TEXTURE_AVIF}loadTexture(t){const e=this.name,n=this.parser,s=n.json,r=s.textures[t];if(!r.extensions||!r.extensions[e])return null;const o=r.extensions[e],a=s.images[o.source];let i=n.textureLoader;if(a.uri){const c=n.options.manager.getHandler(a.uri);c!==null&&(i=c)}return n.loadTextureImage(t,o.source,i)}}class K{constructor(t,e){this.name=e,this.parser=t}loadBufferView(t){const e=this.parser.json,n=e.bufferViews[t];if(n.extensions&&n.extensions[this.name]){const s=n.extensions[this.name],r=this.parser.getDependency("buffer",s.buffer),o=this.parser.options.meshoptDecoder;if(!o||!o.supported){if(e.extensionsRequired&&e.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return r.then(function(a){const i=s.byteOffset||0,c=s.byteLength||0,u=s.count,l=s.byteStride,f=new Uint8Array(a,i,c);return o.decodeGltfBufferAsync?o.decodeGltfBufferAsync(u,l,f,s.mode,s.filter).then(function(p){return p.buffer}):o.ready.then(function(){const p=new ArrayBuffer(u*l);return o.decodeGltfBuffer(new Uint8Array(p),u,l,f,s.mode,s.filter),p})})}else return null}}class me{constructor(t){this.name=T.EXT_MESH_GPU_INSTANCING,this.parser=t}createNodeMesh(t){const e=this.parser.json,n=e.nodes[t];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;const s=e.meshes[n.mesh];for(const c of s.primitives)if(c.mode!==S.TRIANGLES&&c.mode!==S.TRIANGLE_STRIP&&c.mode!==S.TRIANGLE_FAN&&c.mode!==void 0)return null;const o=n.extensions[this.name].attributes,a=[],i={};for(const c in o)a.push(this.parser.getDependency("accessor",o[c]).then(u=>(i[c]=u,i[c])));return a.length<1?null:(a.push(this.parser.createNodeMesh(t)),Promise.all(a).then(c=>{const u=c.pop(),l=u.isGroup?u.children:[u],f=c[0].count,p=[];for(const m of l){const M=new h.Matrix4,g=new h.Vector3,R=new h.Quaternion,A=new h.Vector3(1,1,1),x=new h.InstancedMesh(m.geometry,m.material,f);for(let E=0;E<f;E++)i.TRANSLATION&&g.fromBufferAttribute(i.TRANSLATION,E),i.ROTATION&&R.fromBufferAttribute(i.ROTATION,E),i.SCALE&&A.fromBufferAttribute(i.SCALE,E),x.setMatrixAt(E,M.compose(g,R,A));for(const E in i)if(E==="_COLOR_0"){const L=i[E];x.instanceColor=new h.InstancedBufferAttribute(L.array,L.itemSize,L.normalized)}else E!=="TRANSLATION"&&E!=="ROTATION"&&E!=="SCALE"&&m.geometry.setAttribute(E,i[E]);h.Object3D.prototype.copy.call(x,m),this.parser.assignFinalMaterial(x),p.push(x)}return u.isGroup?(u.clear(),u.add(...p),u):p[0]}))}}const W="glTF",F=12,j={JSON:1313821514,BIN:5130562};class ge{constructor(t){this.name=T.KHR_BINARY_GLTF,this.content=null,this.body=null;const e=new DataView(t,0,F),n=new TextDecoder;if(this.header={magic:n.decode(new Uint8Array(t.slice(0,4))),version:e.getUint32(4,!0),length:e.getUint32(8,!0)},this.header.magic!==W)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const s=this.header.length-F,r=new DataView(t,F);let o=0;for(;o<s;){const a=r.getUint32(o,!0);o+=4;const i=r.getUint32(o,!0);if(o+=4,i===j.JSON){const c=new Uint8Array(t,F+o,a);this.content=n.decode(c)}else if(i===j.BIN){const c=F+o;this.body=t.slice(c,c+a)}o+=a}if(this.content===null)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class Te{constructor(t,e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=T.KHR_DRACO_MESH_COMPRESSION,this.json=t,this.dracoLoader=e,this.dracoLoader.preload()}decodePrimitive(t,e){const n=this.json,s=this.dracoLoader,r=t.extensions[this.name].bufferView,o=t.extensions[this.name].attributes,a={},i={},c={};for(const u in o){const l=B[u]||u.toLowerCase();a[l]=o[u]}for(const u in t.attributes){const l=B[u]||u.toLowerCase();if(o[u]!==void 0){const f=n.accessors[t.attributes[u]],p=O[f.componentType];c[l]=p.name,i[l]=f.normalized===!0}}return e.getDependency("bufferView",r).then(function(u){return new Promise(function(l,f){s.decodeDracoFile(u,function(p){for(const m in p.attributes){const M=p.attributes[m],g=i[m];g!==void 0&&(M.normalized=g)}l(p)},a,c,h.LinearSRGBColorSpace,f)})})}}class Re{constructor(){this.name=T.KHR_TEXTURE_TRANSFORM}extendTexture(t,e){return(e.texCoord===void 0||e.texCoord===t.channel)&&e.offset===void 0&&e.rotation===void 0&&e.scale===void 0||(t=t.clone(),e.texCoord!==void 0&&(t.channel=e.texCoord),e.offset!==void 0&&t.offset.fromArray(e.offset),e.rotation!==void 0&&(t.rotation=e.rotation),e.scale!==void 0&&t.repeat.fromArray(e.scale),t.needsUpdate=!0),t}}class Me{constructor(){this.name=T.KHR_MESH_QUANTIZATION}}class Y extends h.Interpolant{constructor(t,e,n,s){super(t,e,n,s)}copySampleValue_(t){const e=this.resultBuffer,n=this.sampleValues,s=this.valueSize,r=t*s*3+s;for(let o=0;o!==s;o++)e[o]=n[r+o];return e}interpolate_(t,e,n,s){const r=this.resultBuffer,o=this.sampleValues,a=this.valueSize,i=a*2,c=a*3,u=s-e,l=(n-e)/u,f=l*l,p=f*l,m=t*c,M=m-c,g=-2*p+3*f,R=p-f,A=1-g,x=R-f+l;for(let E=0;E!==a;E++){const L=o[M+E+a],b=o[M+E+i]*u,y=o[m+E+a],P=o[m+E]*u;r[E]=A*L+x*b+g*y+R*P}return r}}const Ee=new h.Quaternion;class xe extends Y{interpolate_(t,e,n,s){const r=super.interpolate_(t,e,n,s);return Ee.fromArray(r).normalize().toArray(r),r}}const S={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},O={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},V={9728:h.NearestFilter,9729:h.LinearFilter,9984:h.NearestMipmapNearestFilter,9985:h.LinearMipmapNearestFilter,9986:h.NearestMipmapLinearFilter,9987:h.LinearMipmapLinearFilter},z={33071:h.ClampToEdgeWrapping,33648:h.MirroredRepeatWrapping,10497:h.RepeatWrapping},D={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},B={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},N={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},Ae={CUBICSPLINE:void 0,LINEAR:h.InterpolateLinear,STEP:h.InterpolateDiscrete},G={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"};function _e(d){return d.DefaultMaterial===void 0&&(d.DefaultMaterial=new h.MeshStandardMaterial({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:h.FrontSide})),d.DefaultMaterial}function I(d,t,e){for(const n in e.extensions)d[n]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[n]=e.extensions[n])}function w(d,t){t.extras!==void 0&&(typeof t.extras=="object"?Object.assign(d.userData,t.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+t.extras))}function Le(d,t,e){let n=!1,s=!1,r=!1;for(let c=0,u=t.length;c<u;c++){const l=t[c];if(l.POSITION!==void 0&&(n=!0),l.NORMAL!==void 0&&(s=!0),l.COLOR_0!==void 0&&(r=!0),n&&s&&r)break}if(!n&&!s&&!r)return Promise.resolve(d);const o=[],a=[],i=[];for(let c=0,u=t.length;c<u;c++){const l=t[c];if(n){const f=l.POSITION!==void 0?e.getDependency("accessor",l.POSITION):d.attributes.position;o.push(f)}if(s){const f=l.NORMAL!==void 0?e.getDependency("accessor",l.NORMAL):d.attributes.normal;a.push(f)}if(r){const f=l.COLOR_0!==void 0?e.getDependency("accessor",l.COLOR_0):d.attributes.color;i.push(f)}}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(i)]).then(function(c){const u=c[0],l=c[1],f=c[2];return n&&(d.morphAttributes.position=u),s&&(d.morphAttributes.normal=l),r&&(d.morphAttributes.color=f),d.morphTargetsRelative=!0,d})}function Se(d,t){if(d.updateMorphTargets(),t.weights!==void 0)for(let e=0,n=t.weights.length;e<n;e++)d.morphTargetInfluences[e]=t.weights[e];if(t.extras&&Array.isArray(t.extras.targetNames)){const e=t.extras.targetNames;if(d.morphTargetInfluences.length===e.length){d.morphTargetDictionary={};for(let n=0,s=e.length;n<s;n++)d.morphTargetDictionary[e[n]]=n}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function ye(d){let t;const e=d.extensions&&d.extensions[T.KHR_DRACO_MESH_COMPRESSION];if(e?t="draco:"+e.bufferView+":"+e.indices+":"+v(e.attributes):t=d.indices+":"+v(d.attributes)+":"+d.mode,d.targets!==void 0)for(let n=0,s=d.targets.length;n<s;n++)t+=":"+v(d.targets[n]);return t}function v(d){let t="";const e=Object.keys(d).sort();for(let n=0,s=e.length;n<s;n++)t+=e[n]+":"+d[e[n]]+";";return t}function U(d){switch(d){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}function we(d){return d.search(/\.jpe?g($|\?)/i)>0||d.search(/^data\:image\/jpeg/)===0?"image/jpeg":d.search(/\.webp($|\?)/i)>0||d.search(/^data\:image\/webp/)===0?"image/webp":d.search(/\.ktx2($|\?)/i)>0||d.search(/^data\:image\/ktx2/)===0?"image/ktx2":"image/png"}const be=new h.Matrix4;class Ne{constructor(t={},e={}){this.json=t,this.extensions={},this.plugins={},this.options=e,this.cache=new Z,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,s=-1,r=!1,o=-1;if(typeof navigator<"u"&&typeof navigator.userAgent<"u"){const a=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(a)===!0;const i=a.match(/Version\/(\d+)/);s=n&&i?parseInt(i[1],10):-1,r=a.indexOf("Firefox")>-1,o=r?a.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>"u"||n&&s<17||r&&o<98?this.textureLoader=new h.TextureLoader(this.options.manager):this.textureLoader=new h.ImageBitmapLoader(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new h.FileLoader(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(t){this.extensions=t}setPlugins(t){this.plugins=t}parse(t,e){const n=this,s=this.json,r=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(o){return o._markDefs&&o._markDefs()}),Promise.all(this._invokeAll(function(o){return o.beforeRoot&&o.beforeRoot()})).then(function(){return Promise.all([n.getDependencies("scene"),n.getDependencies("animation"),n.getDependencies("camera")])}).then(function(o){const a={scene:o[0][s.scene||0],scenes:o[0],animations:o[1],cameras:o[2],asset:s.asset,parser:n,userData:{}};return I(r,a,s),w(a,s),Promise.all(n._invokeAll(function(i){return i.afterRoot&&i.afterRoot(a)})).then(function(){for(const i of a.scenes)i.updateMatrixWorld();t(a)})}).catch(e)}_markDefs(){const t=this.json.nodes||[],e=this.json.skins||[],n=this.json.meshes||[];for(let s=0,r=e.length;s<r;s++){const o=e[s].joints;for(let a=0,i=o.length;a<i;a++)t[o[a]].isBone=!0}for(let s=0,r=t.length;s<r;s++){const o=t[s];o.mesh!==void 0&&(this._addNodeRef(this.meshCache,o.mesh),o.skin!==void 0&&(n[o.mesh].isSkinnedMesh=!0)),o.camera!==void 0&&this._addNodeRef(this.cameraCache,o.camera)}}_addNodeRef(t,e){e!==void 0&&(t.refs[e]===void 0&&(t.refs[e]=t.uses[e]=0),t.refs[e]++)}_getNodeRef(t,e,n){if(t.refs[e]<=1)return n;const s=n.clone(),r=(o,a)=>{const i=this.associations.get(o);i!=null&&this.associations.set(a,i);for(const[c,u]of o.children.entries())r(u,a.children[c])};return r(n,s),s.name+="_instance_"+t.uses[e]++,s}_invokeOne(t){const e=Object.values(this.plugins);e.push(this);for(let n=0;n<e.length;n++){const s=t(e[n]);if(s)return s}return null}_invokeAll(t){const e=Object.values(this.plugins);e.unshift(this);const n=[];for(let s=0;s<e.length;s++){const r=t(e[s]);r&&n.push(r)}return n}getDependency(t,e){const n=t+":"+e;let s=this.cache.get(n);if(!s){switch(t){case"scene":s=this.loadScene(e);break;case"node":s=this._invokeOne(function(r){return r.loadNode&&r.loadNode(e)});break;case"mesh":s=this._invokeOne(function(r){return r.loadMesh&&r.loadMesh(e)});break;case"accessor":s=this.loadAccessor(e);break;case"bufferView":s=this._invokeOne(function(r){return r.loadBufferView&&r.loadBufferView(e)});break;case"buffer":s=this.loadBuffer(e);break;case"material":s=this._invokeOne(function(r){return r.loadMaterial&&r.loadMaterial(e)});break;case"texture":s=this._invokeOne(function(r){return r.loadTexture&&r.loadTexture(e)});break;case"skin":s=this.loadSkin(e);break;case"animation":s=this._invokeOne(function(r){return r.loadAnimation&&r.loadAnimation(e)});break;case"camera":s=this.loadCamera(e);break;default:if(s=this._invokeOne(function(r){return r!=this&&r.getDependency&&r.getDependency(t,e)}),!s)throw new Error("Unknown type: "+t);break}this.cache.add(n,s)}return s}getDependencies(t){let e=this.cache.get(t);if(!e){const n=this,s=this.json[t+(t==="mesh"?"es":"s")]||[];e=Promise.all(s.map(function(r,o){return n.getDependency(t,o)})),this.cache.add(t,e)}return e}loadBuffer(t){const e=this.json.buffers[t],n=this.fileLoader;if(e.type&&e.type!=="arraybuffer")throw new Error("THREE.GLTFLoader: "+e.type+" buffer type is not supported.");if(e.uri===void 0&&t===0)return Promise.resolve(this.extensions[T.KHR_BINARY_GLTF].body);const s=this.options;return new Promise(function(r,o){n.load(h.LoaderUtils.resolveURL(e.uri,s.path),r,void 0,function(){o(new Error('THREE.GLTFLoader: Failed to load buffer "'+e.uri+'".'))})})}loadBufferView(t){const e=this.json.bufferViews[t];return this.getDependency("buffer",e.buffer).then(function(n){const s=e.byteLength||0,r=e.byteOffset||0;return n.slice(r,r+s)})}loadAccessor(t){const e=this,n=this.json,s=this.json.accessors[t];if(s.bufferView===void 0&&s.sparse===void 0){const o=D[s.type],a=O[s.componentType],i=s.normalized===!0,c=new a(s.count*o);return Promise.resolve(new h.BufferAttribute(c,o,i))}const r=[];return s.bufferView!==void 0?r.push(this.getDependency("bufferView",s.bufferView)):r.push(null),s.sparse!==void 0&&(r.push(this.getDependency("bufferView",s.sparse.indices.bufferView)),r.push(this.getDependency("bufferView",s.sparse.values.bufferView))),Promise.all(r).then(function(o){const a=o[0],i=D[s.type],c=O[s.componentType],u=c.BYTES_PER_ELEMENT,l=u*i,f=s.byteOffset||0,p=s.bufferView!==void 0?n.bufferViews[s.bufferView].byteStride:void 0,m=s.normalized===!0;let M,g;if(p&&p!==l){const R=Math.floor(f/p),A="InterleavedBuffer:"+s.bufferView+":"+s.componentType+":"+R+":"+s.count;let x=e.cache.get(A);x||(M=new c(a,R*p,s.count*p/u),x=new h.InterleavedBuffer(M,p/u),e.cache.add(A,x)),g=new h.InterleavedBufferAttribute(x,i,f%p/u,m)}else a===null?M=new c(s.count*i):M=new c(a,f,s.count*i),g=new h.BufferAttribute(M,i,m);if(s.sparse!==void 0){const R=D.SCALAR,A=O[s.sparse.indices.componentType],x=s.sparse.indices.byteOffset||0,E=s.sparse.values.byteOffset||0,L=new A(o[1],x,s.sparse.count*R),b=new c(o[2],E,s.sparse.count*i);a!==null&&(g=new h.BufferAttribute(g.array.slice(),g.itemSize,g.normalized)),g.normalized=!1;for(let y=0,P=L.length;y<P;y++){const C=L[y];if(g.setX(C,b[y*i]),i>=2&&g.setY(C,b[y*i+1]),i>=3&&g.setZ(C,b[y*i+2]),i>=4&&g.setW(C,b[y*i+3]),i>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}g.normalized=m}return g})}loadTexture(t){const e=this.json,n=this.options,r=e.textures[t].source,o=e.images[r];let a=this.textureLoader;if(o.uri){const i=n.manager.getHandler(o.uri);i!==null&&(a=i)}return this.loadTextureImage(t,r,a)}loadTextureImage(t,e,n){const s=this,r=this.json,o=r.textures[t],a=r.images[e],i=(a.uri||a.bufferView)+":"+o.sampler;if(this.textureCache[i])return this.textureCache[i];const c=this.loadImageSource(e,n).then(function(u){u.flipY=!1,u.name=o.name||a.name||"",u.name===""&&typeof a.uri=="string"&&a.uri.startsWith("data:image/")===!1&&(u.name=a.uri);const f=(r.samplers||{})[o.sampler]||{};return u.magFilter=V[f.magFilter]||h.LinearFilter,u.minFilter=V[f.minFilter]||h.LinearMipmapLinearFilter,u.wrapS=z[f.wrapS]||h.RepeatWrapping,u.wrapT=z[f.wrapT]||h.RepeatWrapping,u.generateMipmaps=!u.isCompressedTexture&&u.minFilter!==h.NearestFilter&&u.minFilter!==h.LinearFilter,s.associations.set(u,{textures:t}),u}).catch(function(){return null});return this.textureCache[i]=c,c}loadImageSource(t,e){const n=this,s=this.json,r=this.options;if(this.sourceCache[t]!==void 0)return this.sourceCache[t].then(l=>l.clone());const o=s.images[t],a=self.URL||self.webkitURL;let i=o.uri||"",c=!1;if(o.bufferView!==void 0)i=n.getDependency("bufferView",o.bufferView).then(function(l){c=!0;const f=new Blob([l],{type:o.mimeType});return i=a.createObjectURL(f),i});else if(o.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+t+" is missing URI and bufferView");const u=Promise.resolve(i).then(function(l){return new Promise(function(f,p){let m=f;e.isImageBitmapLoader===!0&&(m=function(M){const g=new h.Texture(M);g.needsUpdate=!0,f(g)}),e.load(h.LoaderUtils.resolveURL(l,r.path),m,void 0,p)})}).then(function(l){return c===!0&&a.revokeObjectURL(i),w(l,o),l.userData.mimeType=o.mimeType||we(o.uri),l}).catch(function(l){throw console.error("THREE.GLTFLoader: Couldn't load texture",i),l});return this.sourceCache[t]=u,u}assignTexture(t,e,n,s){const r=this;return this.getDependency("texture",n.index).then(function(o){if(!o)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(o=o.clone(),o.channel=n.texCoord),r.extensions[T.KHR_TEXTURE_TRANSFORM]){const a=n.extensions!==void 0?n.extensions[T.KHR_TEXTURE_TRANSFORM]:void 0;if(a){const i=r.associations.get(o);o=r.extensions[T.KHR_TEXTURE_TRANSFORM].extendTexture(o,a),r.associations.set(o,i)}}return s!==void 0&&(o.colorSpace=s),t[e]=o,o})}assignFinalMaterial(t){const e=t.geometry;let n=t.material;const s=e.attributes.tangent===void 0,r=e.attributes.color!==void 0,o=e.attributes.normal===void 0;if(t.isPoints){const a="PointsMaterial:"+n.uuid;let i=this.cache.get(a);i||(i=new h.PointsMaterial,h.Material.prototype.copy.call(i,n),i.color.copy(n.color),i.map=n.map,i.sizeAttenuation=!1,this.cache.add(a,i)),n=i}else if(t.isLine){const a="LineBasicMaterial:"+n.uuid;let i=this.cache.get(a);i||(i=new h.LineBasicMaterial,h.Material.prototype.copy.call(i,n),i.color.copy(n.color),i.map=n.map,this.cache.add(a,i)),n=i}if(s||r||o){let a="ClonedMaterial:"+n.uuid+":";s&&(a+="derivative-tangents:"),r&&(a+="vertex-colors:"),o&&(a+="flat-shading:");let i=this.cache.get(a);i||(i=n.clone(),r&&(i.vertexColors=!0),o&&(i.flatShading=!0),s&&(i.normalScale&&(i.normalScale.y*=-1),i.clearcoatNormalScale&&(i.clearcoatNormalScale.y*=-1)),this.cache.add(a,i),this.associations.set(i,this.associations.get(n))),n=i}t.material=n}getMaterialType(){return h.MeshStandardMaterial}loadMaterial(t){const e=this,n=this.json,s=this.extensions,r=n.materials[t];let o;const a={},i=r.extensions||{},c=[];if(i[T.KHR_MATERIALS_UNLIT]){const l=s[T.KHR_MATERIALS_UNLIT];o=l.getMaterialType(),c.push(l.extendParams(a,r,e))}else{const l=r.pbrMetallicRoughness||{};if(a.color=new h.Color(1,1,1),a.opacity=1,Array.isArray(l.baseColorFactor)){const f=l.baseColorFactor;a.color.setRGB(f[0],f[1],f[2],h.LinearSRGBColorSpace),a.opacity=f[3]}l.baseColorTexture!==void 0&&c.push(e.assignTexture(a,"map",l.baseColorTexture,h.SRGBColorSpace)),a.metalness=l.metallicFactor!==void 0?l.metallicFactor:1,a.roughness=l.roughnessFactor!==void 0?l.roughnessFactor:1,l.metallicRoughnessTexture!==void 0&&(c.push(e.assignTexture(a,"metalnessMap",l.metallicRoughnessTexture)),c.push(e.assignTexture(a,"roughnessMap",l.metallicRoughnessTexture))),o=this._invokeOne(function(f){return f.getMaterialType&&f.getMaterialType(t)}),c.push(Promise.all(this._invokeAll(function(f){return f.extendMaterialParams&&f.extendMaterialParams(t,a)})))}r.doubleSided===!0&&(a.side=h.DoubleSide);const u=r.alphaMode||G.OPAQUE;if(u===G.BLEND?(a.transparent=!0,a.depthWrite=!1):(a.transparent=!1,u===G.MASK&&(a.alphaTest=r.alphaCutoff!==void 0?r.alphaCutoff:.5)),r.normalTexture!==void 0&&o!==h.MeshBasicMaterial&&(c.push(e.assignTexture(a,"normalMap",r.normalTexture)),a.normalScale=new h.Vector2(1,1),r.normalTexture.scale!==void 0)){const l=r.normalTexture.scale;a.normalScale.set(l,l)}if(r.occlusionTexture!==void 0&&o!==h.MeshBasicMaterial&&(c.push(e.assignTexture(a,"aoMap",r.occlusionTexture)),r.occlusionTexture.strength!==void 0&&(a.aoMapIntensity=r.occlusionTexture.strength)),r.emissiveFactor!==void 0&&o!==h.MeshBasicMaterial){const l=r.emissiveFactor;a.emissive=new h.Color().setRGB(l[0],l[1],l[2],h.LinearSRGBColorSpace)}return r.emissiveTexture!==void 0&&o!==h.MeshBasicMaterial&&c.push(e.assignTexture(a,"emissiveMap",r.emissiveTexture,h.SRGBColorSpace)),Promise.all(c).then(function(){const l=new o(a);return r.name&&(l.name=r.name),w(l,r),e.associations.set(l,{materials:t}),r.extensions&&I(s,l,r),l})}createUniqueName(t){const e=h.PropertyBinding.sanitizeNodeName(t||"");return e in this.nodeNamesUsed?e+"_"+ ++this.nodeNamesUsed[e]:(this.nodeNamesUsed[e]=0,e)}loadGeometries(t){const e=this,n=this.extensions,s=this.primitiveCache;function r(a){return n[T.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(a,e).then(function(i){return X(i,a,e)})}const o=[];for(let a=0,i=t.length;a<i;a++){const c=t[a],u=ye(c),l=s[u];if(l)o.push(l.promise);else{let f;c.extensions&&c.extensions[T.KHR_DRACO_MESH_COMPRESSION]?f=r(c):f=X(new h.BufferGeometry,c,e),s[u]={primitive:c,promise:f},o.push(f)}}return Promise.all(o)}loadMesh(t){const e=this,n=this.json,s=this.extensions,r=n.meshes[t],o=r.primitives,a=[];for(let i=0,c=o.length;i<c;i++){const u=o[i].material===void 0?_e(this.cache):this.getDependency("material",o[i].material);a.push(u)}return a.push(e.loadGeometries(o)),Promise.all(a).then(function(i){const c=i.slice(0,i.length-1),u=i[i.length-1],l=[];for(let p=0,m=u.length;p<m;p++){const M=u[p],g=o[p];let R;const A=c[p];if(g.mode===S.TRIANGLES||g.mode===S.TRIANGLE_STRIP||g.mode===S.TRIANGLE_FAN||g.mode===void 0)R=r.isSkinnedMesh===!0?new h.SkinnedMesh(M,A):new h.Mesh(M,A),R.isSkinnedMesh===!0&&R.normalizeSkinWeights(),g.mode===S.TRIANGLE_STRIP?R.geometry=h.toTrianglesDrawMode(R.geometry,h.TriangleStripDrawMode):g.mode===S.TRIANGLE_FAN&&(R.geometry=h.toTrianglesDrawMode(R.geometry,h.TriangleFanDrawMode));else if(g.mode===S.LINES)R=new h.LineSegments(M,A);else if(g.mode===S.LINE_STRIP)R=new h.Line(M,A);else if(g.mode===S.LINE_LOOP)R=new h.LineLoop(M,A);else if(g.mode===S.POINTS)R=new h.Points(M,A);else throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+g.mode);Object.keys(R.geometry.morphAttributes).length>0&&Se(R,r),R.name=e.createUniqueName(r.name||"mesh_"+t),w(R,r),g.extensions&&I(s,R,g),e.assignFinalMaterial(R),l.push(R)}for(let p=0,m=l.length;p<m;p++)e.associations.set(l[p],{meshes:t,primitives:p});if(l.length===1)return r.extensions&&I(s,l[0],r),l[0];const f=new h.Group;r.extensions&&I(s,f,r),e.associations.set(f,{meshes:t});for(let p=0,m=l.length;p<m;p++)f.add(l[p]);return f})}loadCamera(t){let e;const n=this.json.cameras[t],s=n[n.type];if(!s){console.warn("THREE.GLTFLoader: Missing camera parameters.");return}return n.type==="perspective"?e=new h.PerspectiveCamera(h.MathUtils.radToDeg(s.yfov),s.aspectRatio||1,s.znear||1,s.zfar||2e6):n.type==="orthographic"&&(e=new h.OrthographicCamera(-s.xmag,s.xmag,s.ymag,-s.ymag,s.znear,s.zfar)),n.name&&(e.name=this.createUniqueName(n.name)),w(e,n),Promise.resolve(e)}loadSkin(t){const e=this.json.skins[t],n=[];for(let s=0,r=e.joints.length;s<r;s++)n.push(this._loadNodeShallow(e.joints[s]));return e.inverseBindMatrices!==void 0?n.push(this.getDependency("accessor",e.inverseBindMatrices)):n.push(null),Promise.all(n).then(function(s){const r=s.pop(),o=s,a=[],i=[];for(let c=0,u=o.length;c<u;c++){const l=o[c];if(l){a.push(l);const f=new h.Matrix4;r!==null&&f.fromArray(r.array,c*16),i.push(f)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',e.joints[c])}return new h.Skeleton(a,i)})}loadAnimation(t){const e=this.json,n=this,s=e.animations[t],r=s.name?s.name:"animation_"+t,o=[],a=[],i=[],c=[],u=[];for(let l=0,f=s.channels.length;l<f;l++){const p=s.channels[l],m=s.samplers[p.sampler],M=p.target,g=M.node,R=s.parameters!==void 0?s.parameters[m.input]:m.input,A=s.parameters!==void 0?s.parameters[m.output]:m.output;M.node!==void 0&&(o.push(this.getDependency("node",g)),a.push(this.getDependency("accessor",R)),i.push(this.getDependency("accessor",A)),c.push(m),u.push(M))}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(i),Promise.all(c),Promise.all(u)]).then(function(l){const f=l[0],p=l[1],m=l[2],M=l[3],g=l[4],R=[];for(let x=0,E=f.length;x<E;x++){const L=f[x],b=p[x],y=m[x],P=M[x],C=g[x];if(L===void 0)continue;L.updateMatrix&&L.updateMatrix();const k=n._createAnimationTracks(L,b,y,P,C);if(k)for(let H=0;H<k.length;H++)R.push(k[H])}const A=new h.AnimationClip(r,void 0,R);return w(A,s),A})}createNodeMesh(t){const e=this.json,n=this,s=e.nodes[t];return s.mesh===void 0?null:n.getDependency("mesh",s.mesh).then(function(r){const o=n._getNodeRef(n.meshCache,s.mesh,r);return s.weights!==void 0&&o.traverse(function(a){if(a.isMesh)for(let i=0,c=s.weights.length;i<c;i++)a.morphTargetInfluences[i]=s.weights[i]}),o})}loadNode(t){const e=this.json,n=this,s=e.nodes[t],r=n._loadNodeShallow(t),o=[],a=s.children||[];for(let c=0,u=a.length;c<u;c++)o.push(n.getDependency("node",a[c]));const i=s.skin===void 0?Promise.resolve(null):n.getDependency("skin",s.skin);return Promise.all([r,Promise.all(o),i]).then(function(c){const u=c[0],l=c[1],f=c[2];f!==null&&u.traverse(function(p){p.isSkinnedMesh&&p.bind(f,be)});for(let p=0,m=l.length;p<m;p++)u.add(l[p]);if(u.userData.pivot!==void 0&&l.length>0){const p=u.userData.pivot,m=l[0];u.pivot=new h.Vector3().fromArray(p),u.position.x-=p[0],u.position.y-=p[1],u.position.z-=p[2],m.position.set(0,0,0),delete u.userData.pivot}return u})}_loadNodeShallow(t){const e=this.json,n=this.extensions,s=this;if(this.nodeCache[t]!==void 0)return this.nodeCache[t];const r=e.nodes[t],o=r.name?s.createUniqueName(r.name):"",a=[],i=s._invokeOne(function(c){return c.createNodeMesh&&c.createNodeMesh(t)});return i&&a.push(i),r.camera!==void 0&&a.push(s.getDependency("camera",r.camera).then(function(c){return s._getNodeRef(s.cameraCache,r.camera,c)})),s._invokeAll(function(c){return c.createNodeAttachment&&c.createNodeAttachment(t)}).forEach(function(c){a.push(c)}),this.nodeCache[t]=Promise.all(a).then(function(c){let u;if(r.isBone===!0?u=new h.Bone:c.length>1?u=new h.Group:c.length===1?u=c[0]:u=new h.Object3D,u!==c[0])for(let l=0,f=c.length;l<f;l++)u.add(c[l]);if(r.name&&(u.userData.name=r.name,u.name=o),w(u,r),r.extensions&&I(n,u,r),r.matrix!==void 0){const l=new h.Matrix4;l.fromArray(r.matrix),u.applyMatrix4(l)}else r.translation!==void 0&&u.position.fromArray(r.translation),r.rotation!==void 0&&u.quaternion.fromArray(r.rotation),r.scale!==void 0&&u.scale.fromArray(r.scale);if(!s.associations.has(u))s.associations.set(u,{});else if(r.mesh!==void 0&&s.meshCache.refs[r.mesh]>1){const l=s.associations.get(u);s.associations.set(u,{...l})}return s.associations.get(u).nodes=t,u}),this.nodeCache[t]}loadScene(t){const e=this.extensions,n=this.json.scenes[t],s=this,r=new h.Group;n.name&&(r.name=s.createUniqueName(n.name)),w(r,n),n.extensions&&I(e,r,n);const o=n.nodes||[],a=[];for(let i=0,c=o.length;i<c;i++)a.push(s.getDependency("node",o[i]));return Promise.all(a).then(function(i){for(let u=0,l=i.length;u<l;u++){const f=i[u];f.parent!==null?r.add(Q(f)):r.add(f)}const c=u=>{const l=new Map;for(const[f,p]of s.associations)(f instanceof h.Material||f instanceof h.Texture)&&l.set(f,p);return u.traverse(f=>{const p=s.associations.get(f);p!=null&&l.set(f,p)}),l};return s.associations=c(r),r})}_createAnimationTracks(t,e,n,s,r){const o=[],a=t.name?t.name:t.uuid,i=[];N[r.path]===N.weights?t.traverse(function(f){f.morphTargetInfluences&&i.push(f.name?f.name:f.uuid)}):i.push(a);let c;switch(N[r.path]){case N.weights:c=h.NumberKeyframeTrack;break;case N.rotation:c=h.QuaternionKeyframeTrack;break;case N.translation:case N.scale:c=h.VectorKeyframeTrack;break;default:n.itemSize===1?c=h.NumberKeyframeTrack:c=h.VectorKeyframeTrack;break}const u=s.interpolation!==void 0?Ae[s.interpolation]:h.InterpolateLinear,l=this._getArrayFromAccessor(n);for(let f=0,p=i.length;f<p;f++){const m=new c(i[f]+"."+N[r.path],e.array,l,u);s.interpolation==="CUBICSPLINE"&&this._createCubicSplineTrackInterpolant(m),o.push(m)}return o}_getArrayFromAccessor(t){let e=t.array;if(t.normalized){const n=U(e.constructor),s=new Float32Array(e.length);for(let r=0,o=e.length;r<o;r++)s[r]=e[r]*n;e=s}return e}_createCubicSplineTrackInterpolant(t){t.createInterpolant=function(n){const s=this instanceof h.QuaternionKeyframeTrack?xe:Y;return new s(this.times,this.values,this.getValueSize()/3,n)},t.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function Ie(d,t,e){const n=t.attributes,s=new h.Box3;if(n.POSITION!==void 0){const a=e.json.accessors[n.POSITION],i=a.min,c=a.max;if(i!==void 0&&c!==void 0){if(s.set(new h.Vector3(i[0],i[1],i[2]),new h.Vector3(c[0],c[1],c[2])),a.normalized){const u=U(O[a.componentType]);s.min.multiplyScalar(u),s.max.multiplyScalar(u)}}else{console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");return}}else return;const r=t.targets;if(r!==void 0){const a=new h.Vector3,i=new h.Vector3;for(let c=0,u=r.length;c<u;c++){const l=r[c];if(l.POSITION!==void 0){const f=e.json.accessors[l.POSITION],p=f.min,m=f.max;if(p!==void 0&&m!==void 0){if(i.setX(Math.max(Math.abs(p[0]),Math.abs(m[0]))),i.setY(Math.max(Math.abs(p[1]),Math.abs(m[1]))),i.setZ(Math.max(Math.abs(p[2]),Math.abs(m[2]))),f.normalized){const M=U(O[f.componentType]);i.multiplyScalar(M)}a.max(i)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}s.expandByVector(a)}d.boundingBox=s;const o=new h.Sphere;s.getCenter(o.center),o.radius=s.min.distanceTo(s.max)/2,d.boundingSphere=o}function X(d,t,e){const n=t.attributes,s=[];function r(o,a){return e.getDependency("accessor",o).then(function(i){d.setAttribute(a,i)})}for(const o in n){const a=B[o]||o.toLowerCase();a in d.attributes||s.push(r(n[o],a))}if(t.indices!==void 0&&!d.index){const o=e.getDependency("accessor",t.indices).then(function(a){d.setIndex(a)});s.push(o)}return h.ColorManagement.workingColorSpace!==h.LinearSRGBColorSpace&&"COLOR_0"in n&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${h.ColorManagement.workingColorSpace}" not supported.`),w(d,t),Ie(d,t,e),Promise.all(s).then(function(){return t.targets!==void 0?Le(d,t.targets,e):d})}exports.GLTFLoader=J;
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { PlaybackStats } from '../core/playback-stats';
2
3
  import { AxStatus, AndroidElementTreeOptions } from '../core/ax-fetcher';
3
4
  import { AxElement, AxSnapshot } from '../core/ax-tree';
4
5
  import { CameraCaptureInfo } from '../core/camera';
@@ -9,7 +10,7 @@ declare global {
9
10
  }
10
11
  }
11
12
  export interface RemoteControlProps {
12
- /** Receives parsed iOS latency messages. Adding or removing the callback reconnects the stream. */
13
+ /** Receives latency trace messages from supported iOS and Android instances. Adding or removing the callback reconnects the stream. */
13
14
  onTrace?: (message: Record<string, unknown>) => void;
14
15
  url: string;
15
16
  token: string;
@@ -22,6 +23,23 @@ export interface RemoteControlProps {
22
23
  /** Optional prepared Duo GLB, supplied and licensed by the host application. */
23
24
  duoModelUrl?: string;
24
25
  autoReconnect?: boolean;
26
+ /**
27
+ * Preferred playback jitter buffer duration in milliseconds (0–4000), for
28
+ * incoming audio and video. Lower values can reduce latency but increase
29
+ * dropped frames or freezes. This is a preference, not a latency limit.
30
+ * Updates apply without reconnecting. Omit or pass null to use the browser
31
+ * default. Unsupported browsers ignore this prop. Invalid values are ignored
32
+ * with a console warning, leaving the previous target unchanged.
33
+ */
34
+ jitterBufferTargetMs?: number | null;
35
+ /**
36
+ * Incoming playback stats, sampled every two seconds while subscribed,
37
+ * connected, and visible. Works with iOS and Android, including Duo displays.
38
+ * Missing measurements stay undefined; the first sample establishes a baseline.
39
+ * Emits null when collection pauses, disconnects, or fails after a sample.
40
+ * Buffer delay measures receiving-side buffering, not tap-to-screen latency.
41
+ */
42
+ onPlaybackStats?: (stats: PlaybackStats | null) => void;
25
43
  /**
26
44
  * Fires once when the component concludes the instance is permanently
27
45
  * gone rather than suffering a recoverable connection blip.
@@ -0,0 +1,2 @@
1
+ /** Set a playback preference without letting browser support interrupt the stream. */
2
+ export declare function applyJitterBufferTarget(receiver: RTCRtpReceiver, targetMs: number | null | undefined): void;
@@ -0,0 +1,48 @@
1
+ /** Measurements for one incoming RTP stream. Missing browser fields stay undefined. */
2
+ export interface PlaybackTrackStats {
3
+ /** Browser stats identity. Changes when the RTP stream is replaced. */
4
+ id: string;
5
+ trackId: string;
6
+ /** Browser collection time in Unix milliseconds. */
7
+ timestamp: number;
8
+ /** Time between this stream's samples. Absent on the first sample. */
9
+ intervalMs?: number;
10
+ /** Average receiving-side buffer delay over the interval, not end-to-end latency. */
11
+ bufferDelayMs?: number;
12
+ /** Received media bitrate over the interval, in bits per second. */
13
+ bitrateBps?: number;
14
+ }
15
+ export interface PlaybackVideoStats extends PlaybackTrackStats {
16
+ /** The main display, or the independently streamed inner display on iPhone Duo. */
17
+ display: 'primary' | 'inner';
18
+ /** Decoded frames per second over the interval. Static screens may send few frames. */
19
+ fps?: number;
20
+ /** Frames dropped during the interval, as reported by the browser. */
21
+ droppedFrames?: number;
22
+ /** Browser-reported freezes completed during the interval. */
23
+ freezes?: number;
24
+ }
25
+ export type PlaybackAudioStats = PlaybackTrackStats;
26
+ export interface PlaybackStats {
27
+ /** Latest incoming-stream collection time in Unix milliseconds. */
28
+ timestamp: number;
29
+ /** Configured preference; null means automatic. Absent when the prop is invalid. */
30
+ requestedTargetMs?: number | null;
31
+ /** Current round-trip time of the selected ICE pair, when reported by the browser. */
32
+ rttMs?: number;
33
+ /** Separate measurements for each incoming display; never sum their frame rates. */
34
+ video: PlaybackVideoStats[];
35
+ audio: PlaybackAudioStats[];
36
+ }
37
+ export interface PlaybackReceiver {
38
+ trackId: string;
39
+ kind: string;
40
+ mid: string | null;
41
+ display?: PlaybackVideoStats['display'];
42
+ }
43
+ /** Keep baselines per stream so reconnects and Duo displays cannot contaminate each other. */
44
+ export declare class PlaybackStatsReader {
45
+ private previous;
46
+ reset(): void;
47
+ read(report: RTCStatsReport, receivers: PlaybackReceiver[], target: number | null | undefined): PlaybackStats | null;
48
+ }
@@ -0,0 +1,7 @@
1
+ import { PlaybackStats, PlaybackVideoStats } from './playback-stats';
2
+ export interface PlaybackConnection {
3
+ peer: RTCPeerConnection;
4
+ displays: Map<RTCRtpReceiver, PlaybackVideoStats['display']>;
5
+ }
6
+ /** Sample only subscribed, visible, connected players; never overlap browser stats requests. */
7
+ export declare function usePlaybackStats(connection: PlaybackConnection | null, callback: ((stats: PlaybackStats | null) => void) | undefined, target: number | null | undefined): void;