@codefluss/plugin-configurator-3d 0.0.1-alpha.1

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 ADDED
@@ -0,0 +1,377 @@
1
+ # @codefluss/plugin-configurator-3d
2
+
3
+ Interactive 3D product configurator with material variants, camera presets, and Point of Interest
4
+ markers.
5
+
6
+ ## Features
7
+
8
+ - **GLTF Model Loading**: Load 3D models with Draco compression support
9
+ - **Material Variants**: Real-time material customization (color, metalness, roughness)
10
+ - **Camera Presets**: Predefined camera positions with smooth transitions
11
+ - **POI System**: Point of Interest markers in 3D space (integrated with @codefluss/threejs-shared)
12
+ - **Dynamic Lighting**: Configurable ambient and directional lighting
13
+ - **Multi-Instance Support**: Multiple configurators per page with isolated state
14
+ - **SEO Optimized**: JSON-LD structured data + accessible content
15
+ - **Performance**: Lazy loading, dynamic imports, SSR-safe
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ pnpm add @codefluss/plugin-configurator-3d
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ### Basic Example
26
+
27
+ ```typescript
28
+ import { configurator3DConfig } from '@codefluss/plugin-configurator-3d';
29
+
30
+ const data = {
31
+ model: {
32
+ url: '/models/product.glb',
33
+ scale: 1,
34
+ position: [0, 0, 0],
35
+ rotation: [0, 0, 0],
36
+ description: 'Interactive product configurator',
37
+ keywords: ['3D', 'product', 'WebGL'],
38
+ },
39
+ camera: {
40
+ fov: 50,
41
+ enableOrbit: true,
42
+ enableZoom: true,
43
+ enablePan: true,
44
+ },
45
+ lighting: {
46
+ ambientIntensity: 0.5,
47
+ directionalIntensity: 1,
48
+ directionalPosition: [10, 10, 5],
49
+ enableShadows: true,
50
+ },
51
+ layout: {
52
+ height: '600px',
53
+ position: 'relative',
54
+ },
55
+ };
56
+ ```
57
+
58
+ ### Material Variants
59
+
60
+ ```typescript
61
+ const data = {
62
+ model: {
63
+ url: '/models/chair.glb',
64
+ },
65
+ materials: {
66
+ enabled: true,
67
+ variants: [
68
+ {
69
+ id: 'red-metallic',
70
+ name: 'Red Metallic',
71
+ materialName: 'chair_material',
72
+ properties: {
73
+ color: '#ff0000',
74
+ metalness: 0.9,
75
+ roughness: 0.2,
76
+ },
77
+ },
78
+ {
79
+ id: 'blue-matte',
80
+ name: 'Blue Matte',
81
+ materialName: 'chair_material',
82
+ properties: {
83
+ color: '#0000ff',
84
+ metalness: 0.1,
85
+ roughness: 0.8,
86
+ },
87
+ },
88
+ {
89
+ id: 'wood-texture',
90
+ name: 'Wood Finish',
91
+ materialName: 'chair_material',
92
+ properties: {
93
+ color: '#8b4513',
94
+ metalness: 0,
95
+ roughness: 0.7,
96
+ map: '/textures/wood.jpg', // Optional texture
97
+ },
98
+ },
99
+ ],
100
+ activeVariant: 'red-metallic',
101
+ },
102
+ };
103
+ ```
104
+
105
+ ### Camera Presets
106
+
107
+ ```typescript
108
+ const data = {
109
+ model: {
110
+ url: '/models/car.glb',
111
+ },
112
+ camera: {
113
+ presets: [
114
+ {
115
+ id: 'front',
116
+ name: 'Front View',
117
+ position: [0, 1, 5],
118
+ target: [0, 0.5, 0],
119
+ fov: 50,
120
+ },
121
+ {
122
+ id: 'side',
123
+ name: 'Side View',
124
+ position: [5, 1, 0],
125
+ target: [0, 0.5, 0],
126
+ fov: 45,
127
+ },
128
+ {
129
+ id: 'top',
130
+ name: 'Top View',
131
+ position: [0, 8, 0],
132
+ target: [0, 0, 0],
133
+ fov: 60,
134
+ },
135
+ ],
136
+ activePreset: 'front',
137
+ enableOrbit: true,
138
+ },
139
+ };
140
+ ```
141
+
142
+ ### POI Markers
143
+
144
+ ```typescript
145
+ const data = {
146
+ model: {
147
+ url: '/models/product.glb',
148
+ },
149
+ pois: {
150
+ enabled: true,
151
+ markers: [
152
+ {
153
+ id: 'poi-1',
154
+ position: [1, 2, 0],
155
+ label: 'Premium Material',
156
+ description: 'High-quality carbon fiber construction',
157
+ icon: 'star',
158
+ },
159
+ {
160
+ id: 'poi-2',
161
+ position: [-1, 1.5, 0],
162
+ label: 'Ergonomic Design',
163
+ description: 'Scientifically designed for comfort',
164
+ icon: 'info',
165
+ },
166
+ ],
167
+ },
168
+ };
169
+ ```
170
+
171
+ ### Multi-Instance Example
172
+
173
+ ```typescript
174
+ // Each instance has isolated state
175
+ <Configurator3DComponent
176
+ elementId="configurator-1"
177
+ data={productAData}
178
+ isEditorMode={false}
179
+ />
180
+
181
+ <Configurator3DComponent
182
+ elementId="configurator-2"
183
+ data={productBData}
184
+ isEditorMode={false}
185
+ />
186
+ ```
187
+
188
+ ## API Reference
189
+
190
+ ### Configurator3DData
191
+
192
+ ```typescript
193
+ interface Configurator3DData {
194
+ model?: {
195
+ url?: string; // GLTF/GLB model URL
196
+ scale?: number; // Uniform scale factor
197
+ position?: [number, number, number]; // [x, y, z]
198
+ rotation?: [number, number, number]; // [x, y, z] in radians
199
+ description?: string; // SEO description
200
+ keywords?: string[]; // SEO keywords
201
+ };
202
+
203
+ pois?: {
204
+ enabled?: boolean;
205
+ markers?: POI[]; // From @codefluss/threejs-shared
206
+ };
207
+
208
+ materials?: {
209
+ enabled?: boolean;
210
+ variants?: MaterialVariant[];
211
+ activeVariant?: string;
212
+ };
213
+
214
+ camera?: {
215
+ presets?: CameraPreset[];
216
+ activePreset?: string;
217
+ enableOrbit?: boolean;
218
+ enableZoom?: boolean;
219
+ enablePan?: boolean;
220
+ fov?: number;
221
+ near?: number;
222
+ far?: number;
223
+ };
224
+
225
+ lighting?: {
226
+ ambientIntensity?: number;
227
+ directionalIntensity?: number;
228
+ directionalPosition?: [number, number, number];
229
+ enableShadows?: boolean;
230
+ };
231
+
232
+ layout?: {
233
+ height?: string; // CSS height value
234
+ position?: 'relative' | 'absolute' | 'fixed' | 'sticky';
235
+ };
236
+ }
237
+ ```
238
+
239
+ ### MaterialVariant
240
+
241
+ ```typescript
242
+ interface MaterialVariant {
243
+ id: string;
244
+ name: string;
245
+ materialName: string; // Name of material in GLTF scene
246
+ properties: {
247
+ color?: string; // Hex color (#ff0000)
248
+ metalness?: number; // 0-1
249
+ roughness?: number; // 0-1
250
+ emissive?: string; // Hex color
251
+ emissiveIntensity?: number;
252
+ map?: string; // Texture URL
253
+ };
254
+ }
255
+ ```
256
+
257
+ ### CameraPreset
258
+
259
+ ```typescript
260
+ interface CameraPreset {
261
+ id: string;
262
+ name: string;
263
+ position: [number, number, number];
264
+ target: [number, number, number];
265
+ fov?: number;
266
+ }
267
+ ```
268
+
269
+ ## Store API
270
+
271
+ ### createConfiguratorInstance
272
+
273
+ Creates isolated store per configurator instance:
274
+
275
+ ```typescript
276
+ import { createConfiguratorInstance } from '@codefluss/plugin-configurator-3d';
277
+
278
+ const store = createConfiguratorInstance('my-configurator-id');
279
+
280
+ // Store methods
281
+ store.getState().loadModel(url);
282
+ store.getState().setMaterialVariant(variantId);
283
+ store.getState().setCameraPreset(presetId);
284
+ store.getState().addPOI(poi);
285
+ store.getState().dispose(); // Cleanup
286
+ ```
287
+
288
+ ## Configuration Properties
289
+
290
+ | Property | Type | Default | Description |
291
+ | ------------------------------- | ------- | ------- | ----------------------- |
292
+ | `model.url` | text | - | GLTF/GLB model URL |
293
+ | `model.scale` | range | 1 | Uniform scale (0.1-10) |
294
+ | `model.position` | vector3 | [0,0,0] | Position [x,y,z] |
295
+ | `model.rotation` | vector3 | [0,0,0] | Rotation [x,y,z] |
296
+ | `pois.enabled` | boolean | false | Enable POI markers |
297
+ | `camera.fov` | range | 50 | Field of view (20-120°) |
298
+ | `camera.enableOrbit` | boolean | true | Enable orbit controls |
299
+ | `camera.enableZoom` | boolean | true | Enable zoom |
300
+ | `camera.enablePan` | boolean | true | Enable panning |
301
+ | `lighting.ambientIntensity` | range | 0.5 | Ambient light (0-2) |
302
+ | `lighting.directionalIntensity` | range | 1 | Directional light (0-3) |
303
+ | `lighting.enableShadows` | boolean | true | Render shadows |
304
+ | `layout.height` | text | 600px | Container height |
305
+
306
+ ## Performance Optimization
307
+
308
+ ### Draco Compression
309
+
310
+ Place Draco decoder files in `/public/draco/`:
311
+
312
+ ```bash
313
+ # Download Draco decoder
314
+ https://github.com/google/draco/tree/master/javascript/example
315
+
316
+ # Place files:
317
+ /public/draco/draco_decoder.js
318
+ /public/draco/draco_decoder.wasm
319
+ ```
320
+
321
+ ### Model Optimization Tips
322
+
323
+ 1. **Compress models**: Use GLTF with Draco compression
324
+ 2. **Optimize geometry**: Reduce polygon count when possible
325
+ 3. **Texture optimization**: Use appropriate texture sizes
326
+ 4. **Material reuse**: Share materials across meshes
327
+ 5. **LOD levels**: Consider level-of-detail for complex models
328
+
329
+ ### Instance Limits
330
+
331
+ - **Recommended**: 1-2 configurators per page
332
+ - **Maximum**: 5 configurators (resource intensive)
333
+ - **Monitor**: Check FPS and memory usage
334
+
335
+ ## SEO Features
336
+
337
+ ### JSON-LD Structured Data
338
+
339
+ Automatically includes 3DModel schema:
340
+
341
+ ```json
342
+ {
343
+ "@context": "https://schema.org",
344
+ "@type": "3DModel",
345
+ "name": "3D Product Configurator",
346
+ "description": "Interactive 3D model configurator",
347
+ "interactionType": "Interactive",
348
+ "technology": "WebGL"
349
+ }
350
+ ```
351
+
352
+ ### Accessibility
353
+
354
+ - Hidden semantic content for screen readers
355
+ - Keyboard navigation support
356
+ - ARIA labels on interactive elements
357
+
358
+ ## Browser Support
359
+
360
+ - Chrome 90+
361
+ - Firefox 88+
362
+ - Safari 14+
363
+ - Edge 90+
364
+
365
+ Requires WebGL 2.0 support.
366
+
367
+ ## Dependencies
368
+
369
+ - `three` ^0.160.0
370
+ - `@react-three/fiber` ^9.0.0
371
+ - `@react-three/drei` ^9.92.0
372
+ - `@codefluss/threejs-shared` (POI system)
373
+ - `zustand` ^4.4.7
374
+
375
+ ## License
376
+
377
+ MIT
@@ -0,0 +1,14 @@
1
+ import { Configurator3DComponentProps } from '../types';
2
+ /**
3
+ * Configurator 3D Component - Main plugin component
4
+ *
5
+ * Features:
6
+ * - GLTF model loading with Draco compression
7
+ * - POI system integration
8
+ * - Material variants
9
+ * - Camera presets
10
+ * - SEO metadata
11
+ * - SSR-safe with dynamic import
12
+ */
13
+ export declare function Configurator3DComponent({ data, elementId, isEditorMode }: Configurator3DComponentProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=configurator-3d-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configurator-3d-component.d.ts","sourceRoot":"","sources":["../../src/components/configurator-3d-component.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAK7D;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,SAAS,EACT,YAAoB,EACrB,EAAE,4BAA4B,2CAyB9B"}
@@ -0,0 +1,20 @@
1
+ import { RendererProps } from '@codefluss/base-types';
2
+ import { Configurator3DData } from '../types';
3
+ export interface ConfiguratorRendererProps extends RendererProps<Configurator3DData> {
4
+ }
5
+ /**
6
+ * Configurator Renderer
7
+ *
8
+ * Renders the interactive 3D model configurator with all features:
9
+ * - GLTF model loading
10
+ * - Material variants
11
+ * - Camera presets
12
+ * - POI system
13
+ *
14
+ * This component works client-side and loads Three.js dynamically.
15
+ */
16
+ export declare function ConfiguratorRenderer({ elementId, data, dependencies, }: ConfiguratorRendererProps): import("react/jsx-runtime").JSX.Element;
17
+ export declare namespace ConfiguratorRenderer {
18
+ var displayName: string;
19
+ }
20
+ //# sourceMappingURL=configurator-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configurator-renderer.d.ts","sourceRoot":"","sources":["../../src/components/configurator-renderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,MAAM,WAAW,yBAChB,SAAQ,aAAa,CAAC,kBAAkB,CAAC;CAAG;AAE7C;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,EACpC,SAAS,EACT,IAAI,EACJ,YAAY,GACZ,EAAE,yBAAyB,2CAS3B;yBAbe,oBAAoB"}
@@ -0,0 +1,3 @@
1
+ import { ModelViewerProps } from '../types';
2
+ export default function ModelViewer({ instanceId, data, isEditorMode }: ModelViewerProps): import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=model-viewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-viewer.d.ts","sourceRoot":"","sources":["../../src/components/model-viewer.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAOjD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,gBAAgB,2CAiFvF"}
@@ -0,0 +1,13 @@
1
+ import { PluginConfig } from '@codefluss/base-types';
2
+ /**
3
+ * Configurator 3D Plugin Configuration
4
+ *
5
+ * Interactive 3D product configurator with:
6
+ * - GLTF model loading with Draco compression
7
+ * - Point of Interest (POI) markers
8
+ * - Material variants for customization
9
+ * - Camera presets
10
+ * - Real-time lighting controls
11
+ */
12
+ export declare const configurator3DConfig: PluginConfig;
13
+ //# sourceMappingURL=configurator-3d-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configurator-3d-config.d.ts","sourceRoot":"","sources":["../src/configurator-3d-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAK1D;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,YA4alC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Configurator 3D Plugin
3
+ *
4
+ * Interactive 3D product configurator with:
5
+ * - GLTF/GLB model loading with Draco compression
6
+ * - Point of Interest (POI) system
7
+ * - Material variants for real-time customization
8
+ * - Camera presets and smooth transitions
9
+ * - Dynamic lighting controls
10
+ * - SEO-optimized with JSON-LD structured data
11
+ */
12
+ export { configurator3DConfig } from './configurator-3d-config';
13
+ export { Configurator3DComponent } from './components/configurator-3d-component';
14
+ export { createConfiguratorInstance } from './store/configurator-store';
15
+ export type { Configurator3DData, Configurator3DComponentProps, ConfiguratorStore, CameraPreset, MaterialVariant, ModelViewerProps, POIEditorProps, MaterialEditorProps, CameraEditorProps, } from './types';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAExE,YAAY,EACV,kBAAkB,EAClB,4BAA4B,EAC5B,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),r=require("lucide-react"),s=require("zustand/vanilla"),n=require("three");function o(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const a=o(n),i=t.lazy(()=>Promise.resolve().then(()=>require("./model-viewer-DQiZ9csY.js")));function l({data:r,elementId:s,isEditorMode:n=!1}){return e.jsxs("div",{className:"configurator-3d-wrapper",style:{width:"100%",height:r.layout?.height||"600px",position:r.layout?.position||"relative",overflow:"hidden"},children:[e.jsx(c,{data:r}),e.jsx(t.Suspense,{fallback:e.jsx(d,{}),children:e.jsx(i,{instanceId:s,data:r,isEditorMode:n})})]})}function c({data:t}){return e.jsxs(e.Fragment,{children:[e.jsx("script",{type:"application/ld+json",dangerouslySetInnerHTML:{__html:JSON.stringify({"@context":"https://schema.org","@type":"3DModel",name:"3D Product Configurator",description:t.model?.description||"Interactive 3D model configurator",interactionType:"Interactive",technology:"WebGL",keywords:t.model?.keywords||[]})}}),e.jsxs("div",{className:"sr-only","aria-hidden":"true",children:[e.jsx("h2",{children:"3D Product Configurator"}),e.jsx("p",{children:t.model?.description||"Interactive 3D model configurator"}),t.model?.keywords&&e.jsx("meta",{name:"keywords",content:t.model.keywords.join(", ")})]})]})}function d(){return e.jsxs("div",{style:{width:"100%",height:"100%",background:"linear-gradient(135deg, #667eea 0%, #764ba2 100%)",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",position:"absolute",top:0,left:0,color:"white"},role:"img","aria-label":"3D Model Loading",children:[e.jsx("div",{style:{width:"60px",height:"60px",border:"6px solid rgba(255, 255, 255, 0.3)",borderTop:"6px solid white",borderRadius:"50%",animation:"spin 1s linear infinite"}}),e.jsx("p",{style:{marginTop:"20px",fontSize:"14px"},children:"Loading 3D Model..."}),e.jsx("style",{children:"\n @keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n "})]})}const u={en:{plugin:{name:"Configurator 3D",description:"Interactive 3D product configurator with GLTF models"},properties:{"model.url":{label:"Model URL",placeholder:"https://example.com/model.glb",description:"URL to 3D model (GLB/GLTF)"},"model.scale":{label:"Model Scale",description:"Model scaling factor"},"model.position":{label:"Model Position",placeholder:"x,y,z",description:"3D position of the model"},"model.rotation":{label:"Model Rotation",placeholder:"x,y,z (radians)",description:"3D rotation of the model"},"pois.enabled":{label:"Enable POI Markers",description:"Enable Point of Interest markers"},"camera.fov":{label:"Camera FOV",description:"Camera field of view"},"camera.enableOrbit":{label:"Enable Orbit Controls",description:"Enable camera orbit controls"},"camera.enableZoom":{label:"Enable Zoom",description:"Enable camera zoom"},"camera.enablePan":{label:"Enable Pan",description:"Enable camera panning"},"camera.near":{label:"Camera Near Plane",description:"Camera near plane distance"},"camera.far":{label:"Camera Far Plane",description:"Camera far plane distance"},"lighting.ambientIntensity":{label:"Ambient Light Intensity",description:"Ambient light intensity"}},categories:{content:"Content",style:"Style",layout:"Layout",advanced:"Advanced"}},de:{plugin:{name:"Konfigurator 3D",description:"Interaktiver 3D-Produkt-Konfigurator mit GLTF-Modellen"},properties:{"model.url":{label:"Modell-URL",placeholder:"https://example.com/model.glb",description:"URL zum 3D-Modell (GLB/GLTF)"},"model.scale":{label:"Modell-Skalierung",description:"Skalierungsfaktor des Modells"},"model.position":{label:"Modell-Position",placeholder:"x,y,z",description:"3D-Position des Modells"},"model.rotation":{label:"Modell-Rotation",placeholder:"x,y,z (radians)",description:"3D-Rotation des Modells"},"pois.enabled":{label:"POI-Marker aktivieren",description:"Point of Interest Marker aktivieren"},"camera.fov":{label:"Kamera-FOV",description:"Kamera-Sichtfeld (Field of View)"},"camera.enableOrbit":{label:"Orbit-Steuerung aktivieren",description:"Kamera-Orbit-Steuerung aktivieren"},"camera.enableZoom":{label:"Zoom aktivieren",description:"Kamera-Zoom aktivieren"},"camera.enablePan":{label:"Schwenken aktivieren",description:"Kamera-Schwenken aktivieren"},"camera.near":{label:"Kamera Nahebene",description:"Kamera Near Plane"},"camera.far":{label:"Kamera Fernebene",description:"Kamera Far Plane"},"lighting.ambientIntensity":{label:"Umgebungslicht-Intensität",description:"Intensität des Umgebungslichts"}},categories:{content:"Inhalt",style:"Stil",layout:"Layout",advanced:"Erweitert"}},fr:{plugin:{name:"Configurateur 3D",description:"Configurateur de produits 3D interactif avec modèles GLTF"},properties:{"model.url":{label:"URL du Modèle",placeholder:"https://example.com/model.glb",description:"URL vers le modèle 3D (GLB/GLTF)"},"model.scale":{label:"Échelle du Modèle",description:"Facteur d'échelle du modèle"},"model.position":{label:"Position du Modèle",placeholder:"x,y,z",description:"Position 3D du modèle"},"model.rotation":{label:"Rotation du Modèle",placeholder:"x,y,z (radians)",description:"Rotation 3D du modèle"},"pois.enabled":{label:"Activer Marqueurs POI",description:"Activer les marqueurs de Point d'Intérêt"},"camera.fov":{label:"FOV Caméra",description:"Champ de vision de la caméra"},"camera.enableOrbit":{label:"Activer Contrôles Orbital",description:"Activer les contrôles orbitaux de la caméra"},"camera.enableZoom":{label:"Activer Zoom",description:"Activer le zoom de la caméra"},"camera.enablePan":{label:"Activer Déplacement",description:"Activer le déplacement de la caméra"},"camera.near":{label:"Plan Proche Caméra",description:"Distance du plan proche"},"camera.far":{label:"Plan Lointain Caméra",description:"Distance du plan lointain"},"lighting.ambientIntensity":{label:"Intensité Lumière Ambiante",description:"Intensité de la lumière ambiante"}},categories:{content:"Contenu",style:"Style",layout:"Disposition",advanced:"Avancé"}},es:{plugin:{name:"Configurador 3D",description:"Configurador de productos 3D interactivo con modelos GLTF"},properties:{"model.url":{label:"URL del Modelo",placeholder:"https://example.com/model.glb",description:"URL al modelo 3D (GLB/GLTF)"},"model.scale":{label:"Escala del Modelo",description:"Factor de escala del modelo"},"model.position":{label:"Posición del Modelo",placeholder:"x,y,z",description:"Posición 3D del modelo"},"model.rotation":{label:"Rotación del Modelo",placeholder:"x,y,z (radianes)",description:"Rotación 3D del modelo"},"pois.enabled":{label:"Activar Marcadores POI",description:"Activar marcadores de Punto de Interés"},"camera.fov":{label:"FOV de Cámara",description:"Campo de visión de la cámara"},"camera.enableOrbit":{label:"Activar Controles Orbital",description:"Activar controles orbitales de cámara"},"camera.enableZoom":{label:"Activar Zoom",description:"Activar zoom de cámara"},"camera.enablePan":{label:"Activar Desplazamiento",description:"Activar desplazamiento de cámara"},"camera.near":{label:"Plano Cercano de Cámara",description:"Distancia del plano cercano"},"camera.far":{label:"Plano Lejano de Cámara",description:"Distancia del plano lejano"},"lighting.ambientIntensity":{label:"Intensidad Luz Ambiente",description:"Intensidad de la luz ambiente"}},categories:{content:"Contenido",style:"Estilo",layout:"Diseño",advanced:"Avanzado"}},it:{plugin:{name:"Configuratore 3D",description:"Configuratore prodotti 3D interattivo con modelli GLTF"},properties:{"model.url":{label:"URL del Modello",placeholder:"https://example.com/model.glb",description:"URL al modello 3D (GLB/GLTF)"},"model.scale":{label:"Scala del Modello",description:"Fattore di scala del modello"},"model.position":{label:"Posizione del Modello",placeholder:"x,y,z",description:"Posizione 3D del modello"},"model.rotation":{label:"Rotazione del Modello",placeholder:"x,y,z (radianti)",description:"Rotazione 3D del modello"},"pois.enabled":{label:"Attiva Marcatori POI",description:"Attiva marcatori Punto di Interesse"},"camera.fov":{label:"FOV Fotocamera",description:"Campo visivo della fotocamera"},"camera.enableOrbit":{label:"Attiva Controlli Orbitali",description:"Attiva controlli orbitali fotocamera"},"camera.enableZoom":{label:"Attiva Zoom",description:"Attiva zoom fotocamera"},"camera.enablePan":{label:"Attiva Spostamento",description:"Attiva spostamento fotocamera"},"camera.near":{label:"Piano Vicino Fotocamera",description:"Distanza piano vicino"},"camera.far":{label:"Piano Lontano Fotocamera",description:"Distanza piano lontano"},"lighting.ambientIntensity":{label:"Intensità Luce Ambiente",description:"Intensità della luce ambiente"}},categories:{content:"Contenuto",style:"Stile",layout:"Layout",advanced:"Avanzato"}}},h={id:"configurator-3d",name:"Configurator 3D",version:"0.0.2",category:"advanced",icon:r.Box,component:l,capabilities:{supportsChildren:!1,isRootComponent:!1,requiresParent:!0,childrenType:null,allowedChildPlugins:[],maxChildren:null,minChildren:0},ssr:!1,responsive:!0,properties:[{key:"model.url",label:"Model URL",type:"text",category:"content",default:"",ui:{control:"input",input:{placeholder:"https://example.com/model.glb"}}},{key:"model.scale",label:"Model Scale",type:"range",category:"style",default:1,ui:{control:"slider",slider:{min:.1,max:10,step:.1,showValue:!0}}},{key:"model.position",label:"Model Position",type:"text",category:"advanced",default:"0,0,0",ui:{control:"input",input:{placeholder:"x,y,z"}}},{key:"model.rotation",label:"Model Rotation",type:"text",category:"advanced",default:"0,0,0",ui:{control:"input",input:{placeholder:"x,y,z (radians)"}}},{key:"pois.enabled",label:"Enable POI Markers",type:"toggle",category:"content",default:!1,ui:{control:"toggle"}},{key:"camera.fov",label:"Camera FOV",type:"range",category:"advanced",default:50,ui:{control:"slider",slider:{min:20,max:120,step:1,showValue:!0}}},{key:"camera.enableOrbit",label:"Enable Orbit Controls",type:"toggle",category:"content",default:!0,ui:{control:"toggle"}},{key:"camera.enableZoom",label:"Enable Zoom",type:"toggle",category:"content",default:!0,ui:{control:"toggle"}},{key:"camera.enablePan",label:"Enable Pan",type:"toggle",category:"content",default:!0,ui:{control:"toggle"}},{key:"camera.near",label:"Camera Near Plane",type:"range",category:"advanced",default:.1,ui:{control:"slider",slider:{min:.01,max:10,step:.01,showValue:!0}}},{key:"camera.far",label:"Camera Far Plane",type:"range",category:"advanced",default:1e3,ui:{control:"slider",slider:{min:100,max:1e4,step:100,showValue:!0}}},{key:"lighting.ambientIntensity",label:"Ambient Light Intensity",type:"range",category:"style",default:.5,ui:{control:"slider",slider:{min:0,max:2,step:.1,showValue:!0}}},{key:"lighting.directionalIntensity",label:"Directional Light Intensity",type:"range",category:"style",default:1,ui:{control:"slider",slider:{min:0,max:3,step:.1,showValue:!0}}},{key:"lighting.directionalPosition",label:"Directional Light Position",type:"text",category:"style",default:"10,10,5",ui:{control:"input",input:{placeholder:"x,y,z"}}},{key:"lighting.enableShadows",label:"Enable Shadows",type:"toggle",category:"style",default:!0,ui:{control:"toggle"}},{key:"layout.height",label:"Container Height",type:"text",category:"layout",default:"600px",ui:{control:"input",input:{placeholder:"600px, 100vh, 50%"}}},{key:"layout.position",label:"Position Type",type:"select",category:"layout",default:"relative",ui:{control:"select",select:{options:[{value:"relative",label:"Relative"},{value:"absolute",label:"Absolute"},{value:"fixed",label:"Fixed"},{value:"sticky",label:"Sticky"}]}}},{key:"model.description",label:"Description (SEO)",type:"text",category:"advanced",default:"",ui:{control:"textarea",textarea:{rows:3,placeholder:"Description for search engines and accessibility"}}},{key:"model.keywords",label:"Keywords (SEO)",type:"text",category:"advanced",default:"",ui:{control:"input",input:{placeholder:"3D, product, configurator"}}}],defaults:{model:{url:"",scale:1,position:"0,0,0",rotation:"0,0,0",description:"Interactive 3D model configurator",keywords:"3D,configurator,interactive"},pois:{enabled:!1,markers:[]},camera:{fov:50,enableOrbit:!0,enableZoom:!0,enablePan:!0,near:.1,far:1e3,presets:[]},lighting:{ambientIntensity:.5,directionalIntensity:1,directionalPosition:"10,10,5",enableShadows:!0},layout:{height:"600px",position:"relative"}},locales:u,meta:{description:"3D product configurator with GLTF models, material variants, POI markers, and camera presets",tags:["3d","configurator","gltf","poi","materials","threejs"]}};function p(e,t){if(t===n.TrianglesDrawMode)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),e;if(t===n.TriangleFanDrawMode||t===n.TriangleStripDrawMode){let r=e.getIndex();if(null===r){const t=[],s=e.getAttribute("position");if(void 0===s)return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),e;for(let e=0;e<s.count;e++)t.push(e);e.setIndex(t),r=e.getIndex()}const s=r.count-2,o=[];if(t===n.TriangleFanDrawMode)for(let e=1;e<=s;e++)o.push(r.getX(0)),o.push(r.getX(e)),o.push(r.getX(e+1));else for(let e=0;e<s;e++)e%2==0?(o.push(r.getX(e)),o.push(r.getX(e+1)),o.push(r.getX(e+2))):(o.push(r.getX(e+2)),o.push(r.getX(e+1)),o.push(r.getX(e)));o.length/3!==s&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const a=e.clone();return a.setIndex(o),a.clearGroups(),a}return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",t),e}class m extends n.Loader{constructor(e){super(e),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new x(e)}),this.register(function(e){return new v(e)}),this.register(function(e){return new I(e)}),this.register(function(e){return new P(e)}),this.register(function(e){return new C(e)}),this.register(function(e){return new M(e)}),this.register(function(e){return new w(e)}),this.register(function(e){return new L(e)}),this.register(function(e){return new _(e)}),this.register(function(e){return new b(e)}),this.register(function(e){return new A(e)}),this.register(function(e){return new R(e)}),this.register(function(e){return new S(e)}),this.register(function(e){return new E(e)}),this.register(function(e){return new y(e)}),this.register(function(e){return new k(e)}),this.register(function(e){return new O(e)})}load(e,t,r,s){const o=this;let a;if(""!==this.resourcePath)a=this.resourcePath;else if(""!==this.path){const t=n.LoaderUtils.extractUrlBase(e);a=n.LoaderUtils.resolveURL(t,this.path)}else a=n.LoaderUtils.extractUrlBase(e);this.manager.itemStart(e);const i=function(t){s?s(t):console.error(t),o.manager.itemError(e),o.manager.itemEnd(e)},l=new n.FileLoader(this.manager);l.setPath(this.path),l.setResponseType("arraybuffer"),l.setRequestHeader(this.requestHeader),l.setWithCredentials(this.withCredentials),l.load(e,function(r){try{o.parse(r,a,function(r){t(r),o.manager.itemEnd(e)},i)}catch(s){i(s)}},r,i)}setDRACOLoader(e){return this.dracoLoader=e,this}setKTX2Loader(e){return this.ktx2Loader=e,this}setMeshoptDecoder(e){return this.meshoptDecoder=e,this}register(e){return-1===this.pluginCallbacks.indexOf(e)&&this.pluginCallbacks.push(e),this}unregister(e){return-1!==this.pluginCallbacks.indexOf(e)&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(e),1),this}parse(e,t,r,s){let n;const o={},a={},i=new TextDecoder;if("string"==typeof e)n=JSON.parse(e);else if(e instanceof ArrayBuffer){if(i.decode(new Uint8Array(e,0,4))===D){try{o[g.KHR_BINARY_GLTF]=new H(e)}catch(c){return void(s&&s(c))}n=JSON.parse(o[g.KHR_BINARY_GLTF].content)}else n=JSON.parse(i.decode(e))}else n=e;if(void 0===n.asset||n.asset.version[0]<2)return void(s&&s(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.")));const l=new de(n,{path:t||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});l.fileLoader.setRequestHeader(this.requestHeader);for(let d=0;d<this.pluginCallbacks.length;d++){const e=this.pluginCallbacks[d](l);e.name||console.error("THREE.GLTFLoader: Invalid plugin found: missing name"),a[e.name]=e,o[e.name]=!0}if(n.extensionsUsed)for(let d=0;d<n.extensionsUsed.length;++d){const e=n.extensionsUsed[d],t=n.extensionsRequired||[];switch(e){case g.KHR_MATERIALS_UNLIT:o[e]=new T;break;case g.KHR_DRACO_MESH_COMPRESSION:o[e]=new U(n,this.dracoLoader);break;case g.KHR_TEXTURE_TRANSFORM:o[e]=new G;break;case g.KHR_MESH_QUANTIZATION:o[e]=new B;break;default:t.indexOf(e)>=0&&void 0===a[e]&&console.warn('THREE.GLTFLoader: Unknown extension "'+e+'".')}}l.setExtensions(o),l.setPlugins(a),l.parse(r,s)}parseAsync(e,t){const r=this;return new Promise(function(s,n){r.parse(e,t,s,n)})}}function f(){let e={};return{get:function(t){return e[t]},add:function(t,r){e[t]=r},remove:function(t){delete e[t]},removeAll:function(){e={}}}}const g={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",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class y{constructor(e){this.parser=e,this.name=g.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const e=this.parser,t=this.parser.json.nodes||[];for(let r=0,s=t.length;r<s;r++){const s=t[r];s.extensions&&s.extensions[this.name]&&void 0!==s.extensions[this.name].light&&e._addNodeRef(this.cache,s.extensions[this.name].light)}}_loadLight(e){const t=this.parser,r="light:"+e;let s=t.cache.get(r);if(s)return s;const o=t.json,a=((o.extensions&&o.extensions[this.name]||{}).lights||[])[e];let i;const l=new n.Color(16777215);void 0!==a.color&&l.setRGB(a.color[0],a.color[1],a.color[2],n.LinearSRGBColorSpace);const c=void 0!==a.range?a.range:0;switch(a.type){case"directional":i=new n.DirectionalLight(l),i.target.position.set(0,0,-1),i.add(i.target);break;case"point":i=new n.PointLight(l),i.distance=c;break;case"spot":i=new n.SpotLight(l),i.distance=c,a.spot=a.spot||{},a.spot.innerConeAngle=void 0!==a.spot.innerConeAngle?a.spot.innerConeAngle:0,a.spot.outerConeAngle=void 0!==a.spot.outerConeAngle?a.spot.outerConeAngle:Math.PI/4,i.angle=a.spot.outerConeAngle,i.penumbra=1-a.spot.innerConeAngle/a.spot.outerConeAngle,i.target.position.set(0,0,-1),i.add(i.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+a.type)}return i.position.set(0,0,0),ne(i,a),void 0!==a.intensity&&(i.intensity=a.intensity),i.name=t.createUniqueName(a.name||"light_"+e),s=Promise.resolve(i),t.cache.add(r,s),s}getDependency(e,t){if("light"===e)return this._loadLight(t)}createNodeAttachment(e){const t=this,r=this.parser,s=r.json.nodes[e],n=(s.extensions&&s.extensions[this.name]||{}).light;return void 0===n?null:this._loadLight(n).then(function(e){return r._getNodeRef(t.cache,n,e)})}}class T{constructor(){this.name=g.KHR_MATERIALS_UNLIT}getMaterialType(){return n.MeshBasicMaterial}extendParams(e,t,r){const s=[];e.color=new n.Color(1,1,1),e.opacity=1;const o=t.pbrMetallicRoughness;if(o){if(Array.isArray(o.baseColorFactor)){const t=o.baseColorFactor;e.color.setRGB(t[0],t[1],t[2],n.LinearSRGBColorSpace),e.opacity=t[3]}void 0!==o.baseColorTexture&&s.push(r.assignTexture(e,"map",o.baseColorTexture,n.SRGBColorSpace))}return Promise.all(s)}}class b{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(e,t){const r=this.parser.json.materials[e];if(!r.extensions||!r.extensions[this.name])return Promise.resolve();const s=r.extensions[this.name].emissiveStrength;return void 0!==s&&(t.emissiveIntensity=s),Promise.resolve()}}class x{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_CLEARCOAT}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const o=[],a=s.extensions[this.name];if(void 0!==a.clearcoatFactor&&(t.clearcoat=a.clearcoatFactor),void 0!==a.clearcoatTexture&&o.push(r.assignTexture(t,"clearcoatMap",a.clearcoatTexture)),void 0!==a.clearcoatRoughnessFactor&&(t.clearcoatRoughness=a.clearcoatRoughnessFactor),void 0!==a.clearcoatRoughnessTexture&&o.push(r.assignTexture(t,"clearcoatRoughnessMap",a.clearcoatRoughnessTexture)),void 0!==a.clearcoatNormalTexture&&(o.push(r.assignTexture(t,"clearcoatNormalMap",a.clearcoatNormalTexture)),void 0!==a.clearcoatNormalTexture.scale)){const e=a.clearcoatNormalTexture.scale;t.clearcoatNormalScale=new n.Vector2(e,e)}return Promise.all(o)}}class v{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_DISPERSION}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser.json.materials[e];if(!r.extensions||!r.extensions[this.name])return Promise.resolve();const s=r.extensions[this.name];return t.dispersion=void 0!==s.dispersion?s.dispersion:0,Promise.resolve()}}class R{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_IRIDESCENCE}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const n=[],o=s.extensions[this.name];return void 0!==o.iridescenceFactor&&(t.iridescence=o.iridescenceFactor),void 0!==o.iridescenceTexture&&n.push(r.assignTexture(t,"iridescenceMap",o.iridescenceTexture)),void 0!==o.iridescenceIor&&(t.iridescenceIOR=o.iridescenceIor),void 0===t.iridescenceThicknessRange&&(t.iridescenceThicknessRange=[100,400]),void 0!==o.iridescenceThicknessMinimum&&(t.iridescenceThicknessRange[0]=o.iridescenceThicknessMinimum),void 0!==o.iridescenceThicknessMaximum&&(t.iridescenceThicknessRange[1]=o.iridescenceThicknessMaximum),void 0!==o.iridescenceThicknessTexture&&n.push(r.assignTexture(t,"iridescenceThicknessMap",o.iridescenceThicknessTexture)),Promise.all(n)}}class M{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_SHEEN}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const o=[];t.sheenColor=new n.Color(0,0,0),t.sheenRoughness=0,t.sheen=1;const a=s.extensions[this.name];if(void 0!==a.sheenColorFactor){const e=a.sheenColorFactor;t.sheenColor.setRGB(e[0],e[1],e[2],n.LinearSRGBColorSpace)}return void 0!==a.sheenRoughnessFactor&&(t.sheenRoughness=a.sheenRoughnessFactor),void 0!==a.sheenColorTexture&&o.push(r.assignTexture(t,"sheenColorMap",a.sheenColorTexture,n.SRGBColorSpace)),void 0!==a.sheenRoughnessTexture&&o.push(r.assignTexture(t,"sheenRoughnessMap",a.sheenRoughnessTexture)),Promise.all(o)}}class w{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_TRANSMISSION}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const n=[],o=s.extensions[this.name];return void 0!==o.transmissionFactor&&(t.transmission=o.transmissionFactor),void 0!==o.transmissionTexture&&n.push(r.assignTexture(t,"transmissionMap",o.transmissionTexture)),Promise.all(n)}}class L{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_VOLUME}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const o=[],a=s.extensions[this.name];t.thickness=void 0!==a.thicknessFactor?a.thicknessFactor:0,void 0!==a.thicknessTexture&&o.push(r.assignTexture(t,"thicknessMap",a.thicknessTexture)),t.attenuationDistance=a.attenuationDistance||1/0;const i=a.attenuationColor||[1,1,1];return t.attenuationColor=(new n.Color).setRGB(i[0],i[1],i[2],n.LinearSRGBColorSpace),Promise.all(o)}}class _{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_IOR}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser.json.materials[e];if(!r.extensions||!r.extensions[this.name])return Promise.resolve();const s=r.extensions[this.name];return t.ior=void 0!==s.ior?s.ior:1.5,Promise.resolve()}}class A{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_SPECULAR}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const o=[],a=s.extensions[this.name];t.specularIntensity=void 0!==a.specularFactor?a.specularFactor:1,void 0!==a.specularTexture&&o.push(r.assignTexture(t,"specularIntensityMap",a.specularTexture));const i=a.specularColorFactor||[1,1,1];return t.specularColor=(new n.Color).setRGB(i[0],i[1],i[2],n.LinearSRGBColorSpace),void 0!==a.specularColorTexture&&o.push(r.assignTexture(t,"specularColorMap",a.specularColorTexture,n.SRGBColorSpace)),Promise.all(o)}}class E{constructor(e){this.parser=e,this.name=g.EXT_MATERIALS_BUMP}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const n=[],o=s.extensions[this.name];return t.bumpScale=void 0!==o.bumpFactor?o.bumpFactor:1,void 0!==o.bumpTexture&&n.push(r.assignTexture(t,"bumpMap",o.bumpTexture)),Promise.all(n)}}class S{constructor(e){this.parser=e,this.name=g.KHR_MATERIALS_ANISOTROPY}getMaterialType(e){const t=this.parser.json.materials[e];return t.extensions&&t.extensions[this.name]?n.MeshPhysicalMaterial:null}extendMaterialParams(e,t){const r=this.parser,s=r.json.materials[e];if(!s.extensions||!s.extensions[this.name])return Promise.resolve();const n=[],o=s.extensions[this.name];return void 0!==o.anisotropyStrength&&(t.anisotropy=o.anisotropyStrength),void 0!==o.anisotropyRotation&&(t.anisotropyRotation=o.anisotropyRotation),void 0!==o.anisotropyTexture&&n.push(r.assignTexture(t,"anisotropyMap",o.anisotropyTexture)),Promise.all(n)}}class I{constructor(e){this.parser=e,this.name=g.KHR_TEXTURE_BASISU}loadTexture(e){const t=this.parser,r=t.json,s=r.textures[e];if(!s.extensions||!s.extensions[this.name])return null;const n=s.extensions[this.name],o=t.options.ktx2Loader;if(!o){if(r.extensionsRequired&&r.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return t.loadTextureImage(e,n.source,o)}}class P{constructor(e){this.parser=e,this.name=g.EXT_TEXTURE_WEBP}loadTexture(e){const t=this.name,r=this.parser,s=r.json,n=s.textures[e];if(!n.extensions||!n.extensions[t])return null;const o=n.extensions[t],a=s.images[o.source];let i=r.textureLoader;if(a.uri){const e=r.options.manager.getHandler(a.uri);null!==e&&(i=e)}return r.loadTextureImage(e,o.source,i)}}class C{constructor(e){this.parser=e,this.name=g.EXT_TEXTURE_AVIF}loadTexture(e){const t=this.name,r=this.parser,s=r.json,n=s.textures[e];if(!n.extensions||!n.extensions[t])return null;const o=n.extensions[t],a=s.images[o.source];let i=r.textureLoader;if(a.uri){const e=r.options.manager.getHandler(a.uri);null!==e&&(i=e)}return r.loadTextureImage(e,o.source,i)}}class k{constructor(e){this.name=g.EXT_MESHOPT_COMPRESSION,this.parser=e}loadBufferView(e){const t=this.parser.json,r=t.bufferViews[e];if(r.extensions&&r.extensions[this.name]){const e=r.extensions[this.name],s=this.parser.getDependency("buffer",e.buffer),n=this.parser.options.meshoptDecoder;if(!n||!n.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return s.then(function(t){const r=e.byteOffset||0,s=e.byteLength||0,o=e.count,a=e.byteStride,i=new Uint8Array(t,r,s);return n.decodeGltfBufferAsync?n.decodeGltfBufferAsync(o,a,i,e.mode,e.filter).then(function(e){return e.buffer}):n.ready.then(function(){const t=new ArrayBuffer(o*a);return n.decodeGltfBuffer(new Uint8Array(t),o,a,i,e.mode,e.filter),t})})}return null}}class O{constructor(e){this.name=g.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){const t=this.parser.json,r=t.nodes[e];if(!r.extensions||!r.extensions[this.name]||void 0===r.mesh)return null;const s=t.meshes[r.mesh];for(const n of s.primitives)if(n.mode!==z.TRIANGLES&&n.mode!==z.TRIANGLE_STRIP&&n.mode!==z.TRIANGLE_FAN&&void 0!==n.mode)return null;const o=r.extensions[this.name].attributes,a=[],i={};for(const n in o)a.push(this.parser.getDependency("accessor",o[n]).then(e=>(i[n]=e,i[n])));return a.length<1?null:(a.push(this.parser.createNodeMesh(e)),Promise.all(a).then(e=>{const t=e.pop(),r=t.isGroup?t.children:[t],s=e[0].count,o=[];for(const a of r){const e=new n.Matrix4,t=new n.Vector3,r=new n.Quaternion,l=new n.Vector3(1,1,1),c=new n.InstancedMesh(a.geometry,a.material,s);for(let n=0;n<s;n++)i.TRANSLATION&&t.fromBufferAttribute(i.TRANSLATION,n),i.ROTATION&&r.fromBufferAttribute(i.ROTATION,n),i.SCALE&&l.fromBufferAttribute(i.SCALE,n),c.setMatrixAt(n,e.compose(t,r,l));for(const s in i)if("_COLOR_0"===s){const e=i[s];c.instanceColor=new n.InstancedBufferAttribute(e.array,e.itemSize,e.normalized)}else"TRANSLATION"!==s&&"ROTATION"!==s&&"SCALE"!==s&&a.geometry.setAttribute(s,i[s]);n.Object3D.prototype.copy.call(c,a),this.parser.assignFinalMaterial(c),o.push(c)}return t.isGroup?(t.clear(),t.add(...o),t):o[0]}))}}const D="glTF",N=1313821514,F=5130562;class H{constructor(e){this.name=g.KHR_BINARY_GLTF,this.content=null,this.body=null;const t=new DataView(e,0,12),r=new TextDecoder;if(this.header={magic:r.decode(new Uint8Array(e.slice(0,4))),version:t.getUint32(4,!0),length:t.getUint32(8,!0)},this.header.magic!==D)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-12,n=new DataView(e,12);let o=0;for(;o<s;){const t=n.getUint32(o,!0);o+=4;const s=n.getUint32(o,!0);if(o+=4,s===N){const s=new Uint8Array(e,12+o,t);this.content=r.decode(s)}else if(s===F){const r=12+o;this.body=e.slice(r,r+t)}o+=t}if(null===this.content)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class U{constructor(e,t){if(!t)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=g.KHR_DRACO_MESH_COMPRESSION,this.json=e,this.dracoLoader=t,this.dracoLoader.preload()}decodePrimitive(e,t){const r=this.json,s=this.dracoLoader,o=e.extensions[this.name].bufferView,a=e.extensions[this.name].attributes,i={},l={},c={};for(const n in a){const e=Y[n]||n.toLowerCase();i[e]=a[n]}for(const n in e.attributes){const t=Y[n]||n.toLowerCase();if(void 0!==a[n]){const s=r.accessors[e.attributes[n]],o=X[s.componentType];c[t]=o.name,l[t]=!0===s.normalized}}return t.getDependency("bufferView",o).then(function(e){return new Promise(function(t,r){s.decodeDracoFile(e,function(e){for(const t in e.attributes){const r=e.attributes[t],s=l[t];void 0!==s&&(r.normalized=s)}t(e)},i,c,n.LinearSRGBColorSpace,r)})})}}class G{constructor(){this.name=g.KHR_TEXTURE_TRANSFORM}extendTexture(e,t){return void 0!==t.texCoord&&t.texCoord!==e.channel||void 0!==t.offset||void 0!==t.rotation||void 0!==t.scale?(e=e.clone(),void 0!==t.texCoord&&(e.channel=t.texCoord),void 0!==t.offset&&e.offset.fromArray(t.offset),void 0!==t.rotation&&(e.rotation=t.rotation),void 0!==t.scale&&e.repeat.fromArray(t.scale),e.needsUpdate=!0,e):e}}class B{constructor(){this.name=g.KHR_MESH_QUANTIZATION}}class j extends n.Interpolant{constructor(e,t,r,s){super(e,t,r,s)}copySampleValue_(e){const t=this.resultBuffer,r=this.sampleValues,s=this.valueSize,n=e*s*3+s;for(let o=0;o!==s;o++)t[o]=r[n+o];return t}interpolate_(e,t,r,s){const n=this.resultBuffer,o=this.sampleValues,a=this.valueSize,i=2*a,l=3*a,c=s-t,d=(r-t)/c,u=d*d,h=u*d,p=e*l,m=p-l,f=-2*h+3*u,g=h-u,y=1-f,T=g-u+d;for(let b=0;b!==a;b++){const e=o[m+b+a],t=o[m+b+i]*c,r=o[p+b+a],s=o[p+b]*c;n[b]=y*e+T*t+f*r+g*s}return n}}const K=new n.Quaternion;class V extends j{interpolate_(e,t,r,s){const n=super.interpolate_(e,t,r,s);return K.fromArray(n).normalize().toArray(n),n}}const z={POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6},X={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},q={9728:n.NearestFilter,9729:n.LinearFilter,9984:n.NearestMipmapNearestFilter,9985:n.LinearMipmapNearestFilter,9986:n.NearestMipmapLinearFilter,9987:n.LinearMipmapLinearFilter},W={33071:n.ClampToEdgeWrapping,33648:n.MirroredRepeatWrapping,10497:n.RepeatWrapping},Z={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Y={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"},J={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},Q={CUBICSPLINE:void 0,LINEAR:n.InterpolateLinear,STEP:n.InterpolateDiscrete},$="OPAQUE",ee="MASK",te="BLEND";function re(e){return void 0===e.DefaultMaterial&&(e.DefaultMaterial=new n.MeshStandardMaterial({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:n.FrontSide})),e.DefaultMaterial}function se(e,t,r){for(const s in r.extensions)void 0===e[s]&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[s]=r.extensions[s])}function ne(e,t){void 0!==t.extras&&("object"==typeof t.extras?Object.assign(e.userData,t.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+t.extras))}function oe(e,t){if(e.updateMorphTargets(),void 0!==t.weights)for(let r=0,s=t.weights.length;r<s;r++)e.morphTargetInfluences[r]=t.weights[r];if(t.extras&&Array.isArray(t.extras.targetNames)){const r=t.extras.targetNames;if(e.morphTargetInfluences.length===r.length){e.morphTargetDictionary={};for(let t=0,s=r.length;t<s;t++)e.morphTargetDictionary[r[t]]=t}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function ae(e){let t;const r=e.extensions&&e.extensions[g.KHR_DRACO_MESH_COMPRESSION];if(t=r?"draco:"+r.bufferView+":"+r.indices+":"+ie(r.attributes):e.indices+":"+ie(e.attributes)+":"+e.mode,void 0!==e.targets)for(let s=0,n=e.targets.length;s<n;s++)t+=":"+ie(e.targets[s]);return t}function ie(e){let t="";const r=Object.keys(e).sort();for(let s=0,n=r.length;s<n;s++)t+=r[s]+":"+e[r[s]]+";";return t}function le(e){switch(e){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.")}}const ce=new n.Matrix4;class de{constructor(e={},t={}){this.json=e,this.extensions={},this.plugins={},this.options=t,this.cache=new f,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 r=!1,s=-1,o=!1,a=-1;if("undefined"!=typeof navigator){const e=navigator.userAgent;r=!0===/^((?!chrome|android).)*safari/i.test(e);const t=e.match(/Version\/(\d+)/);s=r&&t?parseInt(t[1],10):-1,o=e.indexOf("Firefox")>-1,a=o?e.match(/Firefox\/([0-9]+)\./)[1]:-1}"undefined"==typeof createImageBitmap||r&&s<17||o&&a<98?this.textureLoader=new n.TextureLoader(this.options.manager):this.textureLoader=new n.ImageBitmapLoader(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new n.FileLoader(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),"use-credentials"===this.options.crossOrigin&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){const r=this,s=this.json,n=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([r.getDependencies("scene"),r.getDependencies("animation"),r.getDependencies("camera")])}).then(function(t){const o={scene:t[0][s.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:s.asset,parser:r,userData:{}};return se(n,o,s),ne(o,s),Promise.all(r._invokeAll(function(e){return e.afterRoot&&e.afterRoot(o)})).then(function(){for(const e of o.scenes)e.updateMatrixWorld();e(o)})}).catch(t)}_markDefs(){const e=this.json.nodes||[],t=this.json.skins||[],r=this.json.meshes||[];for(let s=0,n=t.length;s<n;s++){const r=t[s].joints;for(let t=0,s=r.length;t<s;t++)e[r[t]].isBone=!0}for(let s=0,n=e.length;s<n;s++){const t=e[s];void 0!==t.mesh&&(this._addNodeRef(this.meshCache,t.mesh),void 0!==t.skin&&(r[t.mesh].isSkinnedMesh=!0)),void 0!==t.camera&&this._addNodeRef(this.cameraCache,t.camera)}}_addNodeRef(e,t){void 0!==t&&(void 0===e.refs[t]&&(e.refs[t]=e.uses[t]=0),e.refs[t]++)}_getNodeRef(e,t,r){if(e.refs[t]<=1)return r;const s=r.clone(),n=(e,t)=>{const r=this.associations.get(e);null!=r&&this.associations.set(t,r);for(const[s,o]of e.children.entries())n(o,t.children[s])};return n(r,s),s.name+="_instance_"+e.uses[t]++,s}_invokeOne(e){const t=Object.values(this.plugins);t.push(this);for(let r=0;r<t.length;r++){const s=e(t[r]);if(s)return s}return null}_invokeAll(e){const t=Object.values(this.plugins);t.unshift(this);const r=[];for(let s=0;s<t.length;s++){const n=e(t[s]);n&&r.push(n)}return r}getDependency(e,t){const r=e+":"+t;let s=this.cache.get(r);if(!s){switch(e){case"scene":s=this.loadScene(t);break;case"node":s=this._invokeOne(function(e){return e.loadNode&&e.loadNode(t)});break;case"mesh":s=this._invokeOne(function(e){return e.loadMesh&&e.loadMesh(t)});break;case"accessor":s=this.loadAccessor(t);break;case"bufferView":s=this._invokeOne(function(e){return e.loadBufferView&&e.loadBufferView(t)});break;case"buffer":s=this.loadBuffer(t);break;case"material":s=this._invokeOne(function(e){return e.loadMaterial&&e.loadMaterial(t)});break;case"texture":s=this._invokeOne(function(e){return e.loadTexture&&e.loadTexture(t)});break;case"skin":s=this.loadSkin(t);break;case"animation":s=this._invokeOne(function(e){return e.loadAnimation&&e.loadAnimation(t)});break;case"camera":s=this.loadCamera(t);break;default:if(s=this._invokeOne(function(r){return r!=this&&r.getDependency&&r.getDependency(e,t)}),!s)throw new Error("Unknown type: "+e)}this.cache.add(r,s)}return s}getDependencies(e){let t=this.cache.get(e);if(!t){const r=this,s=this.json[e+("mesh"===e?"es":"s")]||[];t=Promise.all(s.map(function(t,s){return r.getDependency(e,s)})),this.cache.add(e,t)}return t}loadBuffer(e){const t=this.json.buffers[e],r=this.fileLoader;if(t.type&&"arraybuffer"!==t.type)throw new Error("THREE.GLTFLoader: "+t.type+" buffer type is not supported.");if(void 0===t.uri&&0===e)return Promise.resolve(this.extensions[g.KHR_BINARY_GLTF].body);const s=this.options;return new Promise(function(e,o){r.load(n.LoaderUtils.resolveURL(t.uri,s.path),e,void 0,function(){o(new Error('THREE.GLTFLoader: Failed to load buffer "'+t.uri+'".'))})})}loadBufferView(e){const t=this.json.bufferViews[e];return this.getDependency("buffer",t.buffer).then(function(e){const r=t.byteLength||0,s=t.byteOffset||0;return e.slice(s,s+r)})}loadAccessor(e){const t=this,r=this.json,s=this.json.accessors[e];if(void 0===s.bufferView&&void 0===s.sparse){const e=Z[s.type],t=X[s.componentType],r=!0===s.normalized,o=new t(s.count*e);return Promise.resolve(new n.BufferAttribute(o,e,r))}const o=[];return void 0!==s.bufferView?o.push(this.getDependency("bufferView",s.bufferView)):o.push(null),void 0!==s.sparse&&(o.push(this.getDependency("bufferView",s.sparse.indices.bufferView)),o.push(this.getDependency("bufferView",s.sparse.values.bufferView))),Promise.all(o).then(function(e){const o=e[0],a=Z[s.type],i=X[s.componentType],l=i.BYTES_PER_ELEMENT,c=l*a,d=s.byteOffset||0,u=void 0!==s.bufferView?r.bufferViews[s.bufferView].byteStride:void 0,h=!0===s.normalized;let p,m;if(u&&u!==c){const e=Math.floor(d/u),r="InterleavedBuffer:"+s.bufferView+":"+s.componentType+":"+e+":"+s.count;let c=t.cache.get(r);c||(p=new i(o,e*u,s.count*u/l),c=new n.InterleavedBuffer(p,u/l),t.cache.add(r,c)),m=new n.InterleavedBufferAttribute(c,a,d%u/l,h)}else p=null===o?new i(s.count*a):new i(o,d,s.count*a),m=new n.BufferAttribute(p,a,h);if(void 0!==s.sparse){const t=Z.SCALAR,r=X[s.sparse.indices.componentType],l=s.sparse.indices.byteOffset||0,c=s.sparse.values.byteOffset||0,d=new r(e[1],l,s.sparse.count*t),u=new i(e[2],c,s.sparse.count*a);null!==o&&(m=new n.BufferAttribute(m.array.slice(),m.itemSize,m.normalized)),m.normalized=!1;for(let e=0,s=d.length;e<s;e++){const t=d[e];if(m.setX(t,u[e*a]),a>=2&&m.setY(t,u[e*a+1]),a>=3&&m.setZ(t,u[e*a+2]),a>=4&&m.setW(t,u[e*a+3]),a>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}m.normalized=h}return m})}loadTexture(e){const t=this.json,r=this.options,s=t.textures[e].source,n=t.images[s];let o=this.textureLoader;if(n.uri){const e=r.manager.getHandler(n.uri);null!==e&&(o=e)}return this.loadTextureImage(e,s,o)}loadTextureImage(e,t,r){const s=this,o=this.json,a=o.textures[e],i=o.images[t],l=(i.uri||i.bufferView)+":"+a.sampler;if(this.textureCache[l])return this.textureCache[l];const c=this.loadImageSource(t,r).then(function(t){t.flipY=!1,t.name=a.name||i.name||"",""===t.name&&"string"==typeof i.uri&&!1===i.uri.startsWith("data:image/")&&(t.name=i.uri);const r=(o.samplers||{})[a.sampler]||{};return t.magFilter=q[r.magFilter]||n.LinearFilter,t.minFilter=q[r.minFilter]||n.LinearMipmapLinearFilter,t.wrapS=W[r.wrapS]||n.RepeatWrapping,t.wrapT=W[r.wrapT]||n.RepeatWrapping,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==n.NearestFilter&&t.minFilter!==n.LinearFilter,s.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[l]=c,c}loadImageSource(e,t){const r=this,s=this.json,o=this.options;if(void 0!==this.sourceCache[e])return this.sourceCache[e].then(e=>e.clone());const a=s.images[e],i=self.URL||self.webkitURL;let l=a.uri||"",c=!1;if(void 0!==a.bufferView)l=r.getDependency("bufferView",a.bufferView).then(function(e){c=!0;const t=new Blob([e],{type:a.mimeType});return l=i.createObjectURL(t),l});else if(void 0===a.uri)throw new Error("THREE.GLTFLoader: Image "+e+" is missing URI and bufferView");const d=Promise.resolve(l).then(function(e){return new Promise(function(r,s){let a=r;!0===t.isImageBitmapLoader&&(a=function(e){const t=new n.Texture(e);t.needsUpdate=!0,r(t)}),t.load(n.LoaderUtils.resolveURL(e,o.path),a,void 0,s)})}).then(function(e){var t;return!0===c&&i.revokeObjectURL(l),ne(e,a),e.userData.mimeType=a.mimeType||((t=a.uri).search(/\.jpe?g($|\?)/i)>0||0===t.search(/^data\:image\/jpeg/)?"image/jpeg":t.search(/\.webp($|\?)/i)>0||0===t.search(/^data\:image\/webp/)?"image/webp":t.search(/\.ktx2($|\?)/i)>0||0===t.search(/^data\:image\/ktx2/)?"image/ktx2":"image/png"),e}).catch(function(e){throw console.error("THREE.GLTFLoader: Couldn't load texture",l),e});return this.sourceCache[e]=d,d}assignTexture(e,t,r,s){const n=this;return this.getDependency("texture",r.index).then(function(o){if(!o)return null;if(void 0!==r.texCoord&&r.texCoord>0&&((o=o.clone()).channel=r.texCoord),n.extensions[g.KHR_TEXTURE_TRANSFORM]){const e=void 0!==r.extensions?r.extensions[g.KHR_TEXTURE_TRANSFORM]:void 0;if(e){const t=n.associations.get(o);o=n.extensions[g.KHR_TEXTURE_TRANSFORM].extendTexture(o,e),n.associations.set(o,t)}}return void 0!==s&&(o.colorSpace=s),e[t]=o,o})}assignFinalMaterial(e){const t=e.geometry;let r=e.material;const s=void 0===t.attributes.tangent,o=void 0!==t.attributes.color,a=void 0===t.attributes.normal;if(e.isPoints){const e="PointsMaterial:"+r.uuid;let t=this.cache.get(e);t||(t=new n.PointsMaterial,n.Material.prototype.copy.call(t,r),t.color.copy(r.color),t.map=r.map,t.sizeAttenuation=!1,this.cache.add(e,t)),r=t}else if(e.isLine){const e="LineBasicMaterial:"+r.uuid;let t=this.cache.get(e);t||(t=new n.LineBasicMaterial,n.Material.prototype.copy.call(t,r),t.color.copy(r.color),t.map=r.map,this.cache.add(e,t)),r=t}if(s||o||a){let e="ClonedMaterial:"+r.uuid+":";s&&(e+="derivative-tangents:"),o&&(e+="vertex-colors:"),a&&(e+="flat-shading:");let t=this.cache.get(e);t||(t=r.clone(),o&&(t.vertexColors=!0),a&&(t.flatShading=!0),s&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(r))),r=t}e.material=r}getMaterialType(){return n.MeshStandardMaterial}loadMaterial(e){const t=this,r=this.json,s=this.extensions,o=r.materials[e];let a;const i={},l=[];if((o.extensions||{})[g.KHR_MATERIALS_UNLIT]){const e=s[g.KHR_MATERIALS_UNLIT];a=e.getMaterialType(),l.push(e.extendParams(i,o,t))}else{const r=o.pbrMetallicRoughness||{};if(i.color=new n.Color(1,1,1),i.opacity=1,Array.isArray(r.baseColorFactor)){const e=r.baseColorFactor;i.color.setRGB(e[0],e[1],e[2],n.LinearSRGBColorSpace),i.opacity=e[3]}void 0!==r.baseColorTexture&&l.push(t.assignTexture(i,"map",r.baseColorTexture,n.SRGBColorSpace)),i.metalness=void 0!==r.metallicFactor?r.metallicFactor:1,i.roughness=void 0!==r.roughnessFactor?r.roughnessFactor:1,void 0!==r.metallicRoughnessTexture&&(l.push(t.assignTexture(i,"metalnessMap",r.metallicRoughnessTexture)),l.push(t.assignTexture(i,"roughnessMap",r.metallicRoughnessTexture))),a=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),l.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,i)})))}!0===o.doubleSided&&(i.side=n.DoubleSide);const c=o.alphaMode||$;if(c===te?(i.transparent=!0,i.depthWrite=!1):(i.transparent=!1,c===ee&&(i.alphaTest=void 0!==o.alphaCutoff?o.alphaCutoff:.5)),void 0!==o.normalTexture&&a!==n.MeshBasicMaterial&&(l.push(t.assignTexture(i,"normalMap",o.normalTexture)),i.normalScale=new n.Vector2(1,1),void 0!==o.normalTexture.scale)){const e=o.normalTexture.scale;i.normalScale.set(e,e)}if(void 0!==o.occlusionTexture&&a!==n.MeshBasicMaterial&&(l.push(t.assignTexture(i,"aoMap",o.occlusionTexture)),void 0!==o.occlusionTexture.strength&&(i.aoMapIntensity=o.occlusionTexture.strength)),void 0!==o.emissiveFactor&&a!==n.MeshBasicMaterial){const e=o.emissiveFactor;i.emissive=(new n.Color).setRGB(e[0],e[1],e[2],n.LinearSRGBColorSpace)}return void 0!==o.emissiveTexture&&a!==n.MeshBasicMaterial&&l.push(t.assignTexture(i,"emissiveMap",o.emissiveTexture,n.SRGBColorSpace)),Promise.all(l).then(function(){const r=new a(i);return o.name&&(r.name=o.name),ne(r,o),t.associations.set(r,{materials:e}),o.extensions&&se(s,r,o),r})}createUniqueName(e){const t=n.PropertyBinding.sanitizeNodeName(e||"");return t in this.nodeNamesUsed?t+"_"+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){const t=this,r=this.extensions,s=this.primitiveCache;function o(e){return r[g.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(r){return ue(r,e,t)})}const a=[];for(let i=0,l=e.length;i<l;i++){const r=e[i],l=ae(r),c=s[l];if(c)a.push(c.promise);else{let e;e=r.extensions&&r.extensions[g.KHR_DRACO_MESH_COMPRESSION]?o(r):ue(new n.BufferGeometry,r,t),s[l]={primitive:r,promise:e},a.push(e)}}return Promise.all(a)}loadMesh(e){const t=this,r=this.json,s=this.extensions,o=r.meshes[e],a=o.primitives,i=[];for(let n=0,l=a.length;n<l;n++){const e=void 0===a[n].material?re(this.cache):this.getDependency("material",a[n].material);i.push(e)}return i.push(t.loadGeometries(a)),Promise.all(i).then(function(r){const i=r.slice(0,r.length-1),l=r[r.length-1],c=[];for(let u=0,h=l.length;u<h;u++){const r=l[u],d=a[u];let h;const m=i[u];if(d.mode===z.TRIANGLES||d.mode===z.TRIANGLE_STRIP||d.mode===z.TRIANGLE_FAN||void 0===d.mode)h=!0===o.isSkinnedMesh?new n.SkinnedMesh(r,m):new n.Mesh(r,m),!0===h.isSkinnedMesh&&h.normalizeSkinWeights(),d.mode===z.TRIANGLE_STRIP?h.geometry=p(h.geometry,n.TriangleStripDrawMode):d.mode===z.TRIANGLE_FAN&&(h.geometry=p(h.geometry,n.TriangleFanDrawMode));else if(d.mode===z.LINES)h=new n.LineSegments(r,m);else if(d.mode===z.LINE_STRIP)h=new n.Line(r,m);else if(d.mode===z.LINE_LOOP)h=new n.LineLoop(r,m);else{if(d.mode!==z.POINTS)throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+d.mode);h=new n.Points(r,m)}Object.keys(h.geometry.morphAttributes).length>0&&oe(h,o),h.name=t.createUniqueName(o.name||"mesh_"+e),ne(h,o),d.extensions&&se(s,h,d),t.assignFinalMaterial(h),c.push(h)}for(let s=0,n=c.length;s<n;s++)t.associations.set(c[s],{meshes:e,primitives:s});if(1===c.length)return o.extensions&&se(s,c[0],o),c[0];const d=new n.Group;o.extensions&&se(s,d,o),t.associations.set(d,{meshes:e});for(let e=0,t=c.length;e<t;e++)d.add(c[e]);return d})}loadCamera(e){let t;const r=this.json.cameras[e],s=r[r.type];if(s)return"perspective"===r.type?t=new n.PerspectiveCamera(n.MathUtils.radToDeg(s.yfov),s.aspectRatio||1,s.znear||1,s.zfar||2e6):"orthographic"===r.type&&(t=new n.OrthographicCamera(-s.xmag,s.xmag,s.ymag,-s.ymag,s.znear,s.zfar)),r.name&&(t.name=this.createUniqueName(r.name)),ne(t,r),Promise.resolve(t);console.warn("THREE.GLTFLoader: Missing camera parameters.")}loadSkin(e){const t=this.json.skins[e],r=[];for(let s=0,n=t.joints.length;s<n;s++)r.push(this._loadNodeShallow(t.joints[s]));return void 0!==t.inverseBindMatrices?r.push(this.getDependency("accessor",t.inverseBindMatrices)):r.push(null),Promise.all(r).then(function(e){const r=e.pop(),s=e,o=[],a=[];for(let i=0,l=s.length;i<l;i++){const e=s[i];if(e){o.push(e);const t=new n.Matrix4;null!==r&&t.fromArray(r.array,16*i),a.push(t)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',t.joints[i])}return new n.Skeleton(o,a)})}loadAnimation(e){const t=this.json,r=this,s=t.animations[e],o=s.name?s.name:"animation_"+e,a=[],i=[],l=[],c=[],d=[];for(let n=0,u=s.channels.length;n<u;n++){const e=s.channels[n],t=s.samplers[e.sampler],r=e.target,o=r.node,u=void 0!==s.parameters?s.parameters[t.input]:t.input,h=void 0!==s.parameters?s.parameters[t.output]:t.output;void 0!==r.node&&(a.push(this.getDependency("node",o)),i.push(this.getDependency("accessor",u)),l.push(this.getDependency("accessor",h)),c.push(t),d.push(r))}return Promise.all([Promise.all(a),Promise.all(i),Promise.all(l),Promise.all(c),Promise.all(d)]).then(function(e){const t=e[0],a=e[1],i=e[2],l=e[3],c=e[4],d=[];for(let s=0,n=t.length;s<n;s++){const e=t[s],n=a[s],o=i[s],u=l[s],h=c[s];if(void 0===e)continue;e.updateMatrix&&e.updateMatrix();const p=r._createAnimationTracks(e,n,o,u,h);if(p)for(let t=0;t<p.length;t++)d.push(p[t])}const u=new n.AnimationClip(o,void 0,d);return ne(u,s),u})}createNodeMesh(e){const t=this.json,r=this,s=t.nodes[e];return void 0===s.mesh?null:r.getDependency("mesh",s.mesh).then(function(e){const t=r._getNodeRef(r.meshCache,s.mesh,e);return void 0!==s.weights&&t.traverse(function(e){if(e.isMesh)for(let t=0,r=s.weights.length;t<r;t++)e.morphTargetInfluences[t]=s.weights[t]}),t})}loadNode(e){const t=this,r=this.json.nodes[e],s=t._loadNodeShallow(e),n=[],o=r.children||[];for(let i=0,l=o.length;i<l;i++)n.push(t.getDependency("node",o[i]));const a=void 0===r.skin?Promise.resolve(null):t.getDependency("skin",r.skin);return Promise.all([s,Promise.all(n),a]).then(function(e){const t=e[0],r=e[1],s=e[2];null!==s&&t.traverse(function(e){e.isSkinnedMesh&&e.bind(s,ce)});for(let n=0,o=r.length;n<o;n++)t.add(r[n]);return t})}_loadNodeShallow(e){const t=this.json,r=this.extensions,s=this;if(void 0!==this.nodeCache[e])return this.nodeCache[e];const o=t.nodes[e],a=o.name?s.createUniqueName(o.name):"",i=[],l=s._invokeOne(function(t){return t.createNodeMesh&&t.createNodeMesh(e)});return l&&i.push(l),void 0!==o.camera&&i.push(s.getDependency("camera",o.camera).then(function(e){return s._getNodeRef(s.cameraCache,o.camera,e)})),s._invokeAll(function(t){return t.createNodeAttachment&&t.createNodeAttachment(e)}).forEach(function(e){i.push(e)}),this.nodeCache[e]=Promise.all(i).then(function(t){let i;if(i=!0===o.isBone?new n.Bone:t.length>1?new n.Group:1===t.length?t[0]:new n.Object3D,i!==t[0])for(let e=0,r=t.length;e<r;e++)i.add(t[e]);if(o.name&&(i.userData.name=o.name,i.name=a),ne(i,o),o.extensions&&se(r,i,o),void 0!==o.matrix){const e=new n.Matrix4;e.fromArray(o.matrix),i.applyMatrix4(e)}else void 0!==o.translation&&i.position.fromArray(o.translation),void 0!==o.rotation&&i.quaternion.fromArray(o.rotation),void 0!==o.scale&&i.scale.fromArray(o.scale);if(s.associations.has(i)){if(void 0!==o.mesh&&s.meshCache.refs[o.mesh]>1){const e=s.associations.get(i);s.associations.set(i,{...e})}}else s.associations.set(i,{});return s.associations.get(i).nodes=e,i}),this.nodeCache[e]}loadScene(e){const t=this.extensions,r=this.json.scenes[e],s=this,o=new n.Group;r.name&&(o.name=s.createUniqueName(r.name)),ne(o,r),r.extensions&&se(t,o,r);const a=r.nodes||[],i=[];for(let n=0,l=a.length;n<l;n++)i.push(s.getDependency("node",a[n]));return Promise.all(i).then(function(e){for(let t=0,r=e.length;t<r;t++)o.add(e[t]);return s.associations=(e=>{const t=new Map;for(const[r,o]of s.associations)(r instanceof n.Material||r instanceof n.Texture)&&t.set(r,o);return e.traverse(e=>{const r=s.associations.get(e);null!=r&&t.set(e,r)}),t})(o),o})}_createAnimationTracks(e,t,r,s,o){const a=[],i=e.name?e.name:e.uuid,l=[];let c;switch(J[o.path]===J.weights?e.traverse(function(e){e.morphTargetInfluences&&l.push(e.name?e.name:e.uuid)}):l.push(i),J[o.path]){case J.weights:c=n.NumberKeyframeTrack;break;case J.rotation:c=n.QuaternionKeyframeTrack;break;case J.translation:case J.scale:c=n.VectorKeyframeTrack;break;default:if(1===r.itemSize)c=n.NumberKeyframeTrack;else c=n.VectorKeyframeTrack}const d=void 0!==s.interpolation?Q[s.interpolation]:n.InterpolateLinear,u=this._getArrayFromAccessor(r);for(let n=0,h=l.length;n<h;n++){const e=new c(l[n]+"."+J[o.path],t.array,u,d);"CUBICSPLINE"===s.interpolation&&this._createCubicSplineTrackInterpolant(e),a.push(e)}return a}_getArrayFromAccessor(e){let t=e.array;if(e.normalized){const e=le(t.constructor),r=new Float32Array(t.length);for(let s=0,n=t.length;s<n;s++)r[s]=t[s]*e;t=r}return t}_createCubicSplineTrackInterpolant(e){e.createInterpolant=function(e){return new(this instanceof n.QuaternionKeyframeTrack?V:j)(this.times,this.values,this.getValueSize()/3,e)},e.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function ue(e,t,r){const s=t.attributes,o=[];function a(t,s){return r.getDependency("accessor",t).then(function(t){e.setAttribute(s,t)})}for(const n in s){const t=Y[n]||n.toLowerCase();t in e.attributes||o.push(a(s[n],t))}if(void 0!==t.indices&&!e.index){const s=r.getDependency("accessor",t.indices).then(function(t){e.setIndex(t)});o.push(s)}return n.ColorManagement.workingColorSpace!==n.LinearSRGBColorSpace&&"COLOR_0"in s&&console.warn(`THREE.GLTFLoader: Converting vertex colors from "srgb-linear" to "${n.ColorManagement.workingColorSpace}" not supported.`),ne(e,t),function(e,t,r){const s=t.attributes,o=new n.Box3;if(void 0===s.POSITION)return;{const e=r.json.accessors[s.POSITION],t=e.min,a=e.max;if(void 0===t||void 0===a)return void console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");if(o.set(new n.Vector3(t[0],t[1],t[2]),new n.Vector3(a[0],a[1],a[2])),e.normalized){const t=le(X[e.componentType]);o.min.multiplyScalar(t),o.max.multiplyScalar(t)}}const a=t.targets;if(void 0!==a){const e=new n.Vector3,t=new n.Vector3;for(let s=0,n=a.length;s<n;s++){const n=a[s];if(void 0!==n.POSITION){const s=r.json.accessors[n.POSITION],o=s.min,a=s.max;if(void 0!==o&&void 0!==a){if(t.setX(Math.max(Math.abs(o[0]),Math.abs(a[0]))),t.setY(Math.max(Math.abs(o[1]),Math.abs(a[1]))),t.setZ(Math.max(Math.abs(o[2]),Math.abs(a[2]))),s.normalized){const e=le(X[s.componentType]);t.multiplyScalar(e)}e.max(t)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}o.expandByVector(e)}e.boundingBox=o;const i=new n.Sphere;o.getCenter(i.center),i.radius=o.min.distanceTo(o.max)/2,e.boundingSphere=i}(e,t,r),Promise.all(o).then(function(){return void 0!==t.targets?function(e,t,r){let s=!1,n=!1,o=!1;for(let c=0,d=t.length;c<d;c++){const e=t[c];if(void 0!==e.POSITION&&(s=!0),void 0!==e.NORMAL&&(n=!0),void 0!==e.COLOR_0&&(o=!0),s&&n&&o)break}if(!s&&!n&&!o)return Promise.resolve(e);const a=[],i=[],l=[];for(let c=0,d=t.length;c<d;c++){const d=t[c];if(s){const t=void 0!==d.POSITION?r.getDependency("accessor",d.POSITION):e.attributes.position;a.push(t)}if(n){const t=void 0!==d.NORMAL?r.getDependency("accessor",d.NORMAL):e.attributes.normal;i.push(t)}if(o){const t=void 0!==d.COLOR_0?r.getDependency("accessor",d.COLOR_0):e.attributes.color;l.push(t)}}return Promise.all([Promise.all(a),Promise.all(i),Promise.all(l)]).then(function(t){const r=t[0],a=t[1],i=t[2];return s&&(e.morphAttributes.position=r),n&&(e.morphAttributes.normal=a),o&&(e.morphAttributes.color=i),e.morphTargetsRelative=!0,e})}(e,t.targets,r):e})}const he=new WeakMap;class pe extends n.Loader{constructor(e){super(e),this.decoderPath="",this.decoderConfig={},this.decoderBinary=null,this.decoderPending=null,this.workerLimit=4,this.workerPool=[],this.workerNextTaskID=1,this.workerSourceURL="",this.defaultAttributeIDs={position:"POSITION",normal:"NORMAL",color:"COLOR",uv:"TEX_COORD"},this.defaultAttributeTypes={position:"Float32Array",normal:"Float32Array",color:"Float32Array",uv:"Float32Array"}}setDecoderPath(e){return this.decoderPath=e,this}setDecoderConfig(e){return this.decoderConfig=e,this}setWorkerLimit(e){return this.workerLimit=e,this}load(e,t,r,s){const o=new n.FileLoader(this.manager);o.setPath(this.path),o.setResponseType("arraybuffer"),o.setRequestHeader(this.requestHeader),o.setWithCredentials(this.withCredentials),o.load(e,e=>{this.parse(e,t,s)},r,s)}parse(e,t,r=()=>{}){this.decodeDracoFile(e,t,null,null,n.SRGBColorSpace,r).catch(r)}decodeDracoFile(e,t,r,s,o=n.LinearSRGBColorSpace,a=()=>{}){const i={attributeIDs:r||this.defaultAttributeIDs,attributeTypes:s||this.defaultAttributeTypes,useUniqueIDs:!!r,vertexColorSpace:o};return this.decodeGeometry(e,i).then(t).catch(a)}decodeGeometry(e,t){const r=JSON.stringify(t);if(he.has(e)){const t=he.get(e);if(t.key===r)return t.promise;if(0===e.byteLength)throw new Error("THREE.DRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred.")}let s;const n=this.workerNextTaskID++,o=e.byteLength,a=this._getWorker(n,o).then(r=>(s=r,new Promise((r,o)=>{s._callbacks[n]={resolve:r,reject:o},s.postMessage({type:"decode",id:n,taskConfig:t,buffer:e},[e])}))).then(e=>this._createGeometry(e.geometry));return a.catch(()=>!0).then(()=>{s&&n&&this._releaseTask(s,n)}),he.set(e,{key:r,promise:a}),a}_createGeometry(e){const t=new n.BufferGeometry;e.index&&t.setIndex(new n.BufferAttribute(e.index.array,1));for(let r=0;r<e.attributes.length;r++){const{name:s,array:o,itemSize:a,stride:i,vertexColorSpace:l}=e.attributes[r];let c;if(a===i)c=new n.BufferAttribute(o,a);else{const e=new n.InterleavedBuffer(o,i);c=new n.InterleavedBufferAttribute(e,a,0)}"color"===s&&(this._assignVertexColorSpace(c,l),c.normalized=o instanceof Float32Array==!1),t.setAttribute(s,c)}return t}_assignVertexColorSpace(e,t){if(t!==n.SRGBColorSpace)return;const r=new n.Color;for(let s=0,o=e.count;s<o;s++)r.fromBufferAttribute(e,s),n.ColorManagement.colorSpaceToWorking(r,n.SRGBColorSpace),e.setXYZ(s,r.r,r.g,r.b)}_loadLibrary(e,t){const r=new n.FileLoader(this.manager);return r.setPath(this.decoderPath),r.setResponseType(t),r.setWithCredentials(this.withCredentials),new Promise((t,s)=>{r.load(e,t,void 0,s)})}preload(){return this._initDecoder(),this}_initDecoder(){if(this.decoderPending)return this.decoderPending;const e="object"!=typeof WebAssembly||"js"===this.decoderConfig.type,t=[];return e?t.push(this._loadLibrary("draco_decoder.js","text")):(t.push(this._loadLibrary("draco_wasm_wrapper.js","text")),t.push(this._loadLibrary("draco_decoder.wasm","arraybuffer"))),this.decoderPending=Promise.all(t).then(t=>{const r=t[0];e||(this.decoderConfig.wasmBinary=t[1]);const s=me.toString(),n=["/* draco decoder */",r,"","/* worker */",s.substring(s.indexOf("{")+1,s.lastIndexOf("}"))].join("\n");this.workerSourceURL=URL.createObjectURL(new Blob([n]))}),this.decoderPending}_getWorker(e,t){return this._initDecoder().then(()=>{if(this.workerPool.length<this.workerLimit){const e=new Worker(this.workerSourceURL);e._callbacks={},e._taskCosts={},e._taskLoad=0,e.postMessage({type:"init",decoderConfig:this.decoderConfig}),e.onmessage=function(t){const r=t.data;switch(r.type){case"decode":e._callbacks[r.id].resolve(r);break;case"error":e._callbacks[r.id].reject(r);break;default:console.error('THREE.DRACOLoader: Unexpected message, "'+r.type+'"')}},this.workerPool.push(e)}else this.workerPool.sort(function(e,t){return e._taskLoad>t._taskLoad?-1:1});const r=this.workerPool[this.workerPool.length-1];return r._taskCosts[e]=t,r._taskLoad+=t,r})}_releaseTask(e,t){e._taskLoad-=e._taskCosts[t],delete e._callbacks[t],delete e._taskCosts[t]}debug(){console.log("Task load: ",this.workerPool.map(e=>e._taskLoad))}dispose(){for(let e=0;e<this.workerPool.length;++e)this.workerPool[e].terminate();return this.workerPool.length=0,""!==this.workerSourceURL&&URL.revokeObjectURL(this.workerSourceURL),this}}function me(){let e,t;function r(e,t,r,s,n,o){const a=r.num_points(),i=o.num_components(),l=function(e,t){switch(t){case Float32Array:return e.DT_FLOAT32;case Int8Array:return e.DT_INT8;case Int16Array:return e.DT_INT16;case Int32Array:return e.DT_INT32;case Uint8Array:return e.DT_UINT8;case Uint16Array:return e.DT_UINT16;case Uint32Array:return e.DT_UINT32}}(e,n),c=i*n.BYTES_PER_ELEMENT,d=4*Math.ceil(c/4),u=d/n.BYTES_PER_ELEMENT,h=a*c,p=a*d,m=e._malloc(h);t.GetAttributeDataArrayForAllPoints(r,o,l,h,m);const f=new n(e.HEAPF32.buffer,m,h/n.BYTES_PER_ELEMENT);let g;if(c===d)g=f.slice();else{g=new n(p/n.BYTES_PER_ELEMENT);let e=0;for(let t=0,r=f.length;t<r;t++){for(let r=0;r<i;r++)g[e+r]=f[t*i+r];e+=u}}return e._free(m),{name:s,count:a,itemSize:i,array:g,stride:u}}onmessage=function(s){const n=s.data;switch(n.type){case"init":e=n.decoderConfig,t=new Promise(function(t){e.onModuleLoaded=function(e){t({draco:e})},DracoDecoderModule(e)});break;case"decode":const s=n.buffer,o=n.taskConfig;t.then(e=>{const t=e.draco,a=new t.Decoder;try{const e=function(e,t,s,n){const o=n.attributeIDs,a=n.attributeTypes;let i,l;const c=t.GetEncodedGeometryType(s);if(c===e.TRIANGULAR_MESH)i=new e.Mesh,l=t.DecodeArrayToMesh(s,s.byteLength,i);else{if(c!==e.POINT_CLOUD)throw new Error("THREE.DRACOLoader: Unexpected geometry type.");i=new e.PointCloud,l=t.DecodeArrayToPointCloud(s,s.byteLength,i)}if(!l.ok()||0===i.ptr)throw new Error("THREE.DRACOLoader: Decoding failed: "+l.error_msg());const d={index:null,attributes:[]};for(const u in o){const s=self[a[u]];let l,c;if(n.useUniqueIDs)c=o[u],l=t.GetAttributeByUniqueId(i,c);else{if(c=t.GetAttributeId(i,e[o[u]]),-1===c)continue;l=t.GetAttribute(i,c)}const h=r(e,t,i,u,s,l);"color"===u&&(h.vertexColorSpace=n.vertexColorSpace),d.attributes.push(h)}c===e.TRIANGULAR_MESH&&(d.index=function(e,t,r){const s=r.num_faces(),n=3*s,o=4*n,a=e._malloc(o);t.GetTrianglesUInt32Array(r,o,a);const i=new Uint32Array(e.HEAPF32.buffer,a,n).slice();return e._free(a),{array:i,itemSize:1}}(e,t,i));return e.destroy(i),d}(t,a,new Int8Array(s),o),i=e.attributes.map(e=>e.array.buffer);e.index&&i.push(e.index.array.buffer),self.postMessage({type:"decode",id:n.id,geometry:e},i)}catch(i){console.error(i),self.postMessage({type:"error",id:n.id,error:i.message})}finally{t.destroy(a)}})}}}exports.Configurator3DComponent=l,exports.configurator3DConfig=h,exports.createConfiguratorInstance=function(e){return s.createStore()((t,r)=>({instanceId:e,gltf:null,fallbackGeometry:"box",isLoading:!1,loadingProgress:0,error:null,isReady:!0,pois:[],activePOI:null,materialVariants:[],activeMaterialVariant:null,cameraPresets:[],activeCameraPreset:null,cameraTarget:void 0,cameraDistance:void 0,setFallbackGeometry:e=>{t({fallbackGeometry:e})},loadModel:async(e,r)=>{t({isLoading:!0,error:null,loadingProgress:0});try{const s=new m,n=new pe;n.setDecoderPath("/draco/"),s.setDRACOLoader(n);const o=await new Promise((n,o)=>{s.load(e,e=>n(e),e=>{if(e.lengthComputable){const s=e.loaded/e.total*100;t({loadingProgress:s}),r?.(s)}},e=>o(e))});return o.scene.traverse(e=>{e instanceof a.Mesh&&(e.castShadow=!0,e.receiveShadow=!0)}),t({gltf:o,isLoading:!1,isReady:!0,loadingProgress:100}),o}catch(s){throw t({error:s instanceof Error?s.message:"Failed to load model",isLoading:!1,isReady:!1}),s}},addPOI:e=>{const r=`poi-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,s={...e,id:r};return t(e=>({pois:[...e.pois,s]})),r},updatePOI:(e,r)=>{t(t=>({pois:t.pois.map(t=>t.id===e?{...t,...r}:t)}))},removePOI:e=>{t(t=>({pois:t.pois.filter(t=>t.id!==e),activePOI:t.activePOI===e?null:t.activePOI}))},setActivePOI:e=>{t({activePOI:e})},setMaterialVariant:e=>{const{gltf:s,materialVariants:n}=r();if(!s)return;const o=n.find(t=>t.id===e);o&&(s.scene.traverse(e=>{if(e instanceof a.Mesh&&e.material){const t=e.material;if(t.name===o.materialName||!o.materialName){if(o.properties.color&&(t.color=new a.Color(o.properties.color)),void 0!==o.properties.metalness&&(t.metalness=o.properties.metalness),void 0!==o.properties.roughness&&(t.roughness=o.properties.roughness),o.properties.emissive&&(t.emissive=new a.Color(o.properties.emissive)),void 0!==o.properties.emissiveIntensity&&(t.emissiveIntensity=o.properties.emissiveIntensity),o.properties.map){(new a.TextureLoader).load(o.properties.map,e=>{t.map=e,t.needsUpdate=!0})}t.needsUpdate=!0}}}),t({activeMaterialVariant:e}))},addMaterialVariant:e=>{t(t=>({materialVariants:[...t.materialVariants,e]}))},setCameraPreset:e=>{t({activeCameraPreset:e})},addCameraPreset:e=>{t(t=>({cameraPresets:[...t.cameraPresets,e]}))},dispose:()=>{const{gltf:e}=r();e&&e.scene.traverse(e=>{if(e instanceof a.Mesh){e.geometry?.dispose();(Array.isArray(e.material)?e.material:[e.material]).forEach(e=>{e&&(e.map&&e.map.dispose(),e.lightMap&&e.lightMap.dispose(),e.bumpMap&&e.bumpMap.dispose(),e.normalMap&&e.normalMap.dispose(),e.specularMap&&e.specularMap.dispose(),e.envMap&&e.envMap.dispose(),e.aoMap&&e.aoMap.dispose(),e.emissiveMap&&e.emissiveMap.dispose(),e.metalnessMap&&e.metalnessMap.dispose(),e.roughnessMap&&e.roughnessMap.dispose(),e.dispose())})}}),t({gltf:null,isReady:!1,isLoading:!1,loadingProgress:0,error:null,pois:[],activePOI:null,materialVariants:[],activeMaterialVariant:null,cameraPresets:[],activeCameraPreset:null,cameraTarget:void 0,cameraDistance:void 0})}}))};
2
+ //# sourceMappingURL=index.js.map