@codefluss/plugin-configurator-3d 0.0.2-alpha.1 → 0.0.2-alpha.3

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.
@@ -0,0 +1,11 @@
1
+ import{t as e}from"./configurator-store-xTXosVLi.mjs";import{useEffect as t,useRef as r,useState as a}from"react";import{Fragment as n,jsx as i,jsxs as o}from"react/jsx-runtime";import*as s from"three";import{Canvas as l,useFrame as c,useThree as d}from"@react-three/fiber";import{Environment as m,OrbitControls as h}from"@react-three/drei";import{useStore as f}from"zustand";import{InstanceProvider as u,POIMarker as g}from"@codefluss/threejs-shared";var p=/* @__PURE__ */new Map;function b({instanceId:r,data:n,isEditorMode:s}){const[c]=a(()=>{const t=e(r);return p.set(r,t),t}),d=f(c,e=>e.isReady),h=f(c,e=>e.isLoading),g=f(c,e=>e.loadingProgress);return t(()=>{if(n.model?.url){const e=c.getState();if(e.gltf)return;e.loadModel(n.model.url)}else c.getState().setFallbackGeometry(n.model?.fallbackGeometry||"box")},[n.model?.url,n.model?.fallbackGeometry,c]),t(()=>()=>{c.getState().dispose(),p.delete(r)},[r,c]),/* @__PURE__ */o("div",{style:{width:"100%",height:"100%",position:"relative"},children:[h&&/* @__PURE__ */i(w,{progress:g}),
2
+ /* @__PURE__ */i(u,{instanceId:r,createStore:()=>c,children:/* @__PURE__ */o(l,{shadows:!0,camera:{position:[5,5,5],fov:n.camera?.fov||50,near:n.camera?.near||.1,far:n.camera?.far||2e3},frameloop:"demand",gl:{preserveDrawingBuffer:!0,antialias:!0,powerPreference:"high-performance"},children:[
3
+ /* @__PURE__ */i("color",{attach:"background",args:["#f0f0f0"]}),
4
+ /* @__PURE__ */i("ambientLight",{intensity:n.lighting?.ambientIntensity||.5}),
5
+ /* @__PURE__ */i("directionalLight",{position:n.lighting?.directionalPosition||[10,10,5],intensity:n.lighting?.directionalIntensity||1,castShadow:n.lighting?.enableShadows}),d&&/* @__PURE__ */i(y,{store:c,data:n}),d&&n.pois?.enabled&&/* @__PURE__ */i(v,{store:c}),
6
+ /* @__PURE__ */i(x,{store:c,enabled:!1!==n.camera?.enableOrbit,enableZoom:!1!==n.camera?.enableZoom,enablePan:!1!==n.camera?.enablePan}),
7
+ /* @__PURE__ */i(m,{preset:"city"})]},r)}),s&&d&&/* @__PURE__ */i(M,{instanceId:r,store:c})]})}function y({store:e,data:a}){const n=f(e,e=>e.gltf),l=f(e,e=>e.fallbackGeometry),d=r(null);if(c(({invalidate:e})=>{d.current&&a.model&&(d.current.position.set(...a.model.position||[0,0,0]),d.current.rotation.set(...a.model.rotation||[0,0,0]),d.current.scale.setScalar(a.model.scale||1),e())}),t(()=>{if(!n||!d.current)return;const t=(new s.Box3).setFromObject(d.current),r=t.getCenter(new s.Vector3),i=t.getSize(new s.Vector3),o=Math.max(i.x,i.y,i.z),l=(a.camera?.fov||50)*Math.PI/180,c=o/(2*Math.tan(l/2))*2.5;e.setState({cameraTarget:[r.x,r.y,r.z],cameraDistance:c})},[n,a.camera?.fov,e]),!n)return null;if(n?.scene)/* @__PURE__ */return i("primitive",{ref:d,object:n.scene});const m=l||"box",h=/* @__PURE__ */i("meshStandardMaterial",{color:"#4a90e2",metalness:.3,roughness:.4});switch(m){case"box":default:/* @__PURE__ */return o("mesh",{ref:d,children:[/* @__PURE__ */i("boxGeometry",{args:[2,2,2]}),h]});case"sphere":/* @__PURE__ */return o("mesh",{ref:d,children:[/* @__PURE__ */i("sphereGeometry",{args:[1.5,32,32]}),h]});case"cylinder":/* @__PURE__ */return o("mesh",{ref:d,children:[/* @__PURE__ */i("cylinderGeometry",{args:[1,1,2,32]}),h]});case"torus":/* @__PURE__ */return o("mesh",{ref:d,children:[/* @__PURE__ */i("torusGeometry",{args:[1,.4,16,32]}),h]})}}function x({store:e,enabled:a,enableZoom:n,enablePan:o}){const s=r(null),{camera:l,invalidate:c}=d(),m=f(e,e=>e.cameraTarget),u=f(e,e=>e.cameraDistance);return t(()=>{if(!m||!u)return;const e=Math.PI/4,t=Math.PI/6,r=m[0]+u*Math.cos(t)*Math.cos(e),a=m[1]+u*Math.sin(t),n=m[2]+u*Math.cos(t)*Math.sin(e);l.position.set(r,a,n),l.lookAt(m[0],m[1],m[2]),s.current&&(s.current.target.set(...m),s.current.update()),c()},[m,u,l,c]),/* @__PURE__ */i(h,{ref:s,enabled:a,enableZoom:n,enablePan:o,onChange:()=>c()})}function v({store:e}){/* @__PURE__ */
8
+ return i(n,{children:f(e,e=>e.pois).map(e=>/* @__PURE__ */i(g,{...e},e.id))})}function w({progress:e}){/* @__PURE__ */
9
+ return i("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)",zIndex:10},children:/* @__PURE__ */o("div",{style:{textAlign:"center",color:"white"},children:[/* @__PURE__ */i("div",{style:{width:200,height:4,background:"#333",borderRadius:2,overflow:"hidden"},children:/* @__PURE__ */i("div",{style:{width:`${e}%`,height:"100%",background:"#4CAF50",transition:"width 0.3s"}})}),/* @__PURE__ */o("p",{style:{marginTop:10,fontSize:14},children:[Math.round(e),"%"]})]})})}function M({instanceId:e,store:t}){const r=f(t,e=>e.setMaterialVariant),a=f(t,e=>e.setCameraPreset),n=f(t,e=>e.materialVariants),s=f(t,e=>e.cameraPresets);/* @__PURE__ */
10
+ return o("div",{style:{position:"absolute",top:10,left:10,background:"white",padding:10,borderRadius:8,boxShadow:"0 2px 10px rgba(0,0,0,0.1)"},children:[n.length>0&&/* @__PURE__ */o("div",{style:{marginBottom:10},children:[/* @__PURE__ */i("label",{style:{fontSize:12,fontWeight:"bold"},children:"Materials:"}),n.map(e=>/* @__PURE__ */i("button",{onClick:()=>r(e.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:e.name},e.id))]}),s.length>0&&/* @__PURE__ */o("div",{children:[/* @__PURE__ */i("label",{style:{fontSize:12,fontWeight:"bold"},children:"Camera:"}),s.map(e=>/* @__PURE__ */i("button",{onClick:()=>a(e.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:e.name},e.id))]})]})}export{b as default};
11
+ //# sourceMappingURL=model-viewer-BgioySt-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-viewer-BgioySt-.mjs","names":[],"sources":["../src/components/model-viewer.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from 'react';\nimport { Canvas, useFrame, useThree } from '@react-three/fiber';\nimport { OrbitControls, Environment } from '@react-three/drei';\nimport { useStore } from 'zustand';\nimport { InstanceProvider, POIMarker } from '@codefluss/threejs-shared';\nimport { createConfiguratorInstance } from '../store/configurator-store';\nimport type { ModelViewerProps } from '../types';\nimport type { StoreApi } from 'zustand/vanilla';\nimport type { ConfiguratorStore } from '../types';\nimport * as THREE from 'three';\n\nconst configuratorStores = new Map<string, StoreApi<ConfiguratorStore>>();\n\nexport default function ModelViewer({ instanceId, data, isEditorMode }: ModelViewerProps) {\n const [store] = useState(() => {\n // Always create a fresh store for this instance\n const newStore = createConfiguratorInstance(instanceId);\n configuratorStores.set(instanceId, newStore);\n return newStore;\n });\n\n const isReady = useStore(store, (state) => state.isReady);\n const isLoading = useStore(store, (state) => state.isLoading);\n const loadingProgress = useStore(store, (state) => state.loadingProgress);\n\n // Load model\n useEffect(() => {\n if (data.model?.url) {\n const state = store.getState();\n if (state.gltf) return; // Already loaded\n\n state.loadModel(data.model.url);\n } else {\n // Fallback to built-in geometry\n const state = store.getState();\n state.setFallbackGeometry(data.model?.fallbackGeometry || 'box');\n }\n }, [data.model?.url, data.model?.fallbackGeometry, store]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n const state = store.getState();\n state.dispose();\n configuratorStores.delete(instanceId);\n };\n }, [instanceId, store]);\n\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {isLoading && <LoadingOverlay progress={loadingProgress} />}\n\n <InstanceProvider instanceId={instanceId} createStore={() => store}>\n <Canvas\n key={instanceId}\n shadows\n camera={{\n position: [5, 5, 5],\n fov: data.camera?.fov || 50,\n near: data.camera?.near || 0.1,\n far: data.camera?.far || 2000\n }}\n frameloop=\"demand\"\n gl={{\n preserveDrawingBuffer: true,\n antialias: true,\n powerPreference: \"high-performance\"\n }}\n >\n <color attach=\"background\" args={['#f0f0f0']} />\n\n <ambientLight intensity={data.lighting?.ambientIntensity || 0.5} />\n <directionalLight\n position={data.lighting?.directionalPosition || [10, 10, 5]}\n intensity={data.lighting?.directionalIntensity || 1}\n castShadow={data.lighting?.enableShadows}\n />\n\n {isReady && <Model store={store} data={data} />}\n {isReady && data.pois?.enabled && <POIMarkers store={store} />}\n\n <CameraController\n store={store}\n enabled={data.camera?.enableOrbit !== false}\n enableZoom={data.camera?.enableZoom !== false}\n enablePan={data.camera?.enablePan !== false}\n />\n <Environment preset=\"city\" />\n </Canvas>\n </InstanceProvider>\n\n {isEditorMode && isReady && <EditorControls instanceId={instanceId} store={store} />}\n </div>\n );\n}\n\nfunction Model({ store, data }: { store: StoreApi<ConfiguratorStore>; data: ModelViewerProps['data'] }) {\n const gltf = useStore(store, (state) => state.gltf);\n const fallbackGeometry = useStore(store, (state) => state.fallbackGeometry);\n const ref = useRef<THREE.Group>(null);\n\n useFrame(({ invalidate }) => {\n if (!ref.current || !data.model) return;\n ref.current.position.set(...(data.model.position || [0, 0, 0]));\n ref.current.rotation.set(...(data.model.rotation || [0, 0, 0]));\n ref.current.scale.setScalar(data.model.scale || 1);\n invalidate(); // Trigger re-render for frameloop=\"demand\"\n });\n\n // Auto-focus and auto-zoom on model load\n useEffect(() => {\n if (!gltf || !ref.current) return;\n\n // Calculate bounding box\n const box = new THREE.Box3().setFromObject(ref.current);\n const center = box.getCenter(new THREE.Vector3());\n const size = box.getSize(new THREE.Vector3());\n\n // Get the max dimension to determine zoom\n const maxDim = Math.max(size.x, size.y, size.z);\n const fov = data.camera?.fov || 50;\n const fovRad = (fov * Math.PI) / 180;\n\n // Calculate camera distance to fit the object\n const cameraDistance = maxDim / (2 * Math.tan(fovRad / 2));\n\n // Add padding (2.5x for better framing and full visibility)\n const finalDistance = cameraDistance * 2.5;\n\n // Store camera info for OrbitControls\n store.setState({\n cameraTarget: [center.x, center.y, center.z] as [number, number, number],\n cameraDistance: finalDistance\n });\n }, [gltf, data.camera?.fov, store]);\n\n if (!gltf) return null;\n\n if (gltf?.scene) {\n return <primitive ref={ref} object={gltf.scene} />;\n }\n\n // Fallback geometry when no GLTF model is loaded\n const geometry = fallbackGeometry || 'box';\n const material = (\n <meshStandardMaterial\n color=\"#4a90e2\"\n metalness={0.3}\n roughness={0.4}\n />\n );\n\n switch (geometry) {\n case 'box':\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n case 'sphere':\n return (\n <mesh ref={ref}>\n <sphereGeometry args={[1.5, 32, 32]} />\n {material}\n </mesh>\n );\n case 'cylinder':\n return (\n <mesh ref={ref}>\n <cylinderGeometry args={[1, 1, 2, 32]} />\n {material}\n </mesh>\n );\n case 'torus':\n return (\n <mesh ref={ref}>\n <torusGeometry args={[1, 0.4, 16, 32]} />\n {material}\n </mesh>\n );\n default:\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n }\n}\n\nfunction CameraController({\n store,\n enabled,\n enableZoom,\n enablePan\n}: {\n store: StoreApi<ConfiguratorStore>;\n enabled: boolean;\n enableZoom: boolean;\n enablePan: boolean;\n}) {\n const controlsRef = useRef<any>(null);\n const { camera, invalidate } = useThree();\n const cameraTarget = useStore(store, (state) => state.cameraTarget);\n const cameraDistance = useStore(store, (state) => state.cameraDistance);\n\n useEffect(() => {\n if (!cameraTarget || !cameraDistance) return;\n\n // Calculate camera position (angle: 45 degrees horizontal, 30 degrees vertical)\n const angleH = Math.PI / 4; // 45 degrees\n const angleV = Math.PI / 6; // 30 degrees\n\n const x = cameraTarget[0] + cameraDistance * Math.cos(angleV) * Math.cos(angleH);\n const y = cameraTarget[1] + cameraDistance * Math.sin(angleV);\n const z = cameraTarget[2] + cameraDistance * Math.cos(angleV) * Math.sin(angleH);\n\n camera.position.set(x, y, z);\n camera.lookAt(cameraTarget[0], cameraTarget[1], cameraTarget[2]);\n\n // Update OrbitControls target\n if (controlsRef.current) {\n controlsRef.current.target.set(...cameraTarget);\n controlsRef.current.update();\n }\n\n invalidate();\n }, [cameraTarget, cameraDistance, camera, invalidate]);\n\n return (\n <OrbitControls\n ref={controlsRef}\n enabled={enabled}\n enableZoom={enableZoom}\n enablePan={enablePan}\n onChange={() => invalidate()}\n />\n );\n}\n\nfunction POIMarkers({ store }: { store: StoreApi<ConfiguratorStore> }) {\n const pois = useStore(store, (state) => state.pois);\n\n return (\n <>\n {pois.map((poi) => (\n <POIMarker key={poi.id} {...poi} />\n ))}\n </>\n );\n}\n\nfunction LoadingOverlay({ progress }: { progress: number }) {\n return (\n <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)', zIndex: 10 }}>\n <div style={{ textAlign: 'center', color: 'white' }}>\n <div style={{ width: 200, height: 4, background: '#333', borderRadius: 2, overflow: 'hidden' }}>\n <div style={{ width: `${progress}%`, height: '100%', background: '#4CAF50', transition: 'width 0.3s' }} />\n </div>\n <p style={{ marginTop: 10, fontSize: 14 }}>{Math.round(progress)}%</p>\n </div>\n </div>\n );\n}\n\nfunction EditorControls({ instanceId: _, store }: { instanceId: string; store: StoreApi<ConfiguratorStore> }) {\n const setMaterialVariant = useStore(store, (s) => s.setMaterialVariant);\n const setCameraPreset = useStore(store, (s) => s.setCameraPreset);\n const materialVariants = useStore(store, (s) => s.materialVariants);\n const cameraPresets = useStore(store, (s) => s.cameraPresets);\n\n return (\n <div style={{ position: 'absolute', top: 10, left: 10, background: 'white', padding: 10, borderRadius: 8, boxShadow: '0 2px 10px rgba(0,0,0,0.1)' }}>\n {materialVariants.length > 0 && (\n <div style={{ marginBottom: 10 }}>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Materials:</label>\n {materialVariants.map(v => (\n <button key={v.id} onClick={() => setMaterialVariant(v.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {v.name}\n </button>\n ))}\n </div>\n )}\n {cameraPresets.length > 0 && (\n <div>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Camera:</label>\n {cameraPresets.map(p => (\n <button key={p.id} onClick={() => setCameraPreset(p.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {p.name}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"ocAaA,IAAM,iBAAqB,IAAI,IAE/B,SAAwB,GAAY,WAAE,EAAA,KAAY,EAAA,aAAM,IACtD,MAAO,GAAS,EAAA,KAEd,MAAM,EAAW,EAA2B,GAE5C,OADA,EAAmB,IAAI,EAAY,GAC5B,IAGH,EAAU,EAAS,EAAQ,GAAU,EAAM,SAC3C,EAAY,EAAS,EAAQ,GAAU,EAAM,WAC7C,EAAkB,EAAS,EAAQ,GAAU,EAAM,iBAyBzD,OAtBA,EAAA,KACE,GAAI,EAAK,OAAO,IAAK,CACnB,MAAM,EAAQ,EAAM,WACpB,GAAI,EAAM,KAAM,OAEhB,EAAM,UAAU,EAAK,MAAM,UAGb,EAAM,WACd,oBAAoB,EAAK,OAAO,kBAAoB,QAE3D,CAAC,EAAK,OAAO,IAAK,EAAK,OAAO,iBAAkB,IAGnD,EAAA,IACE,KACgB,EAAM,WACd,UACN,EAAmB,OAAO,IAE3B,CAAC,EAAY,mBAGd,EAAC,MAAD,CAAK,MAAO,CAAE,MAAO,OAAQ,OAAQ,OAAQ,SAAU,qBAAvD,CACG,kBAAa,EAAC,EAAD,CAAgB,SAAU;eAExC,EAAC,EAAD,CAA8B,aAAY,YAAA,IAAmB,0BAC3D,EAAC,EAAD,CAEE,SAAA,EACA,OAAQ,CACN,SAAU,CAAC,EAAG,EAAG,GACjB,IAAK,EAAK,QAAQ,KAAO,GACzB,KAAM,EAAK,QAAQ,MAAQ,GAC3B,IAAK,EAAK,QAAQ,KAAO,KAE3B,UAAU,SACV,GAAI,CACF,uBAAuB,EACvB,WAAW,EACX,gBAAiB,6BAbrB;eAgBE,EAAC,QAAD,CAAO,OAAO,aAAa,KAAM,CAAC;eAElC,EAAC,eAAD,CAAc,UAAW,EAAK,UAAU,kBAAoB;eAC5D,EAAC,mBAAD,CACE,SAAU,EAAK,UAAU,qBAAuB,CAAC,GAAI,GAAI,GACzD,UAAW,EAAK,UAAU,sBAAwB,EAClD,WAAY,EAAK,UAAU,gBAG5B,kBAAW,EAAC,EAAD,CAAc,QAAa,SACtC,GAAW,EAAK,MAAM,wBAAW,EAAC,EAAD,CAAmB;eAErD,EAAC,EAAD,CACS,QACP,SAAsC,IAA7B,EAAK,QAAQ,YACtB,YAAwC,IAA5B,EAAK,QAAQ,WACzB,WAAsC,IAA3B,EAAK,QAAQ;eAE1B,EAAC,EAAD,CAAa,OAAO,WAjCf,KAqCR,GAAgB,kBAAW,EAAC,EAAD,CAA4B,aAAmB,aAKjF,SAAS,GAAM,MAAE,EAAA,KAAO,IACtB,MAAM,EAAO,EAAS,EAAQ,GAAU,EAAM,MACxC,EAAmB,EAAS,EAAQ,GAAU,EAAM,kBACpD,EAAM,EAAoB,MAqChC,GAnCA,EAAA,EAAY,iBACL,EAAI,SAAY,EAAK,QAC1B,EAAI,QAAQ,SAAS,OAAQ,EAAK,MAAM,UAAY,CAAC,EAAG,EAAG,IAC3D,EAAI,QAAQ,SAAS,OAAQ,EAAK,MAAM,UAAY,CAAC,EAAG,EAAG,IAC3D,EAAI,QAAQ,MAAM,UAAU,EAAK,MAAM,OAAS,GAChD,OAIF,EAAA,KACE,IAAK,IAAS,EAAI,QAAS,OAG3B,MAAM,GAAM,IAAI,EAAM,MAAO,cAAc,EAAI,SACzC,EAAS,EAAI,UAAU,IAAI,EAAM,SACjC,EAAO,EAAI,QAAQ,IAAI,EAAM,SAG7B,EAAS,KAAK,IAAI,EAAK,EAAG,EAAK,EAAG,EAAK,GAEvC,GADM,EAAK,QAAQ,KAAO,IACV,KAAK,GAAM,IAM3B,EAHiB,GAAU,EAAI,KAAK,IAAI,EAAS,IAGhB,IAGvC,EAAM,SAAS,CACb,aAAc,CAAC,EAAO,EAAG,EAAO,EAAG,EAAO,GAC1C,eAAgB,KAEjB,CAAC,EAAM,EAAK,QAAQ,IAAK,KAEvB,EAAM,OAAO,KAElB,GAAI,GAAM,qBACR,OAAO,EAAC,YAAD,CAAgB,MAAK,OAAQ,EAAK,QAI3C,MAAM,EAAW,GAAoB,MAC/B,iBACJ,EAAC,uBAAD,CACE,MAAM,UACN,UAAW,GACX,UAAW,KAIf,OAAQ,GACN,IAAK,MA4BL,uBACE,OACE,EAAC,OAAD,CAAW,eAAX,gBACE,EAAC,cAAD,CAAa,KAAM,CAAC,EAAG,EAAG,KACzB,KAzBP,IAAK,wBACH,OACE,EAAC,OAAD,CAAW,eAAX,gBACE,EAAC,iBAAD,CAAgB,KAAM,CAAC,IAAK,GAAI,MAC/B,KAGP,IAAK,0BACH,OACE,EAAC,OAAD,CAAW,eAAX,gBACE,EAAC,mBAAD,CAAkB,KAAM,CAAC,EAAG,EAAG,EAAG,MACjC,KAGP,IAAK,uBACH,OACE,EAAC,OAAD,CAAW,eAAX,gBACE,EAAC,gBAAD,CAAe,KAAM,CAAC,EAAG,GAAK,GAAI,MACjC,MAaX,SAAS,GAAiB,MACxB,EAAA,QACA,EAAA,WACA,EAAA,UACA,IAOA,MAAM,EAAc,EAAY,OAC1B,OAAE,EAAA,WAAQ,GAAe,IACzB,EAAe,EAAS,EAAQ,GAAU,EAAM,cAChD,EAAiB,EAAS,EAAQ,GAAU,EAAM,gBAyBxD,OAvBA,EAAA,KACE,IAAK,IAAiB,EAAgB,OAGtC,MAAM,EAAS,KAAK,GAAK,EACnB,EAAS,KAAK,GAAK,EAEnB,EAAI,EAAa,GAAK,EAAiB,KAAK,IAAI,GAAU,KAAK,IAAI,GACnE,EAAI,EAAa,GAAK,EAAiB,KAAK,IAAI,GAChD,EAAI,EAAa,GAAK,EAAiB,KAAK,IAAI,GAAU,KAAK,IAAI,GAEzE,EAAO,SAAS,IAAI,EAAG,EAAG,GAC1B,EAAO,OAAO,EAAa,GAAI,EAAa,GAAI,EAAa,IAGzD,EAAY,UACd,EAAY,QAAQ,OAAO,OAAO,GAClC,EAAY,QAAQ,UAGtB,KACC,CAAC,EAAc,EAAgB,EAAQ,mBAGxC,EAAC,EAAD,CACE,IAAK,EACI,UACG,aACD,YACX,SAAA,IAAgB,MAKtB,SAAS,GAAW,MAAE;AAGpB,OACE,EAAA,EAAA,CAAA,SAHW,EAAS,EAAQ,GAAU,EAAM,MAIpC,IAAK,kBACT,EAAC,EAAD,IAA4B,GAAZ,EAAI,OAM5B,SAAS,GAAe,SAAE;AACxB,OACE,EAAC,MAAD,CAAK,MAAO,CAAE,SAAU,WAAY,MAAO,EAAG,QAAS,OAAQ,WAAY,SAAU,eAAgB,SAAU,WAAY,kBAAmB,OAAQ,4BACpJ,EAAC,MAAD,CAAK,MAAO,CAAE,UAAW,SAAU,MAAO,kBAA1C,gBACE,EAAC,MAAD,CAAK,MAAO,CAAE,MAAO,IAAK,OAAQ,EAAG,WAAY,OAAQ,aAAc,EAAG,SAAU,kCAClF,EAAC,MAAD,CAAK,MAAO,CAAE,MAAO,GAAG,KAAa,OAAQ,OAAQ,WAAY,UAAW,WAAY,iCAE1F,EAAC,IAAD,CAAG,MAAO,CAAE,UAAW,GAAI,SAAU,aAArC,CAA4C,KAAK,MAAM,GAAU,YAMzE,SAAS,GAAiB,WAAY,EAAA,MAAG,IACvC,MAAM,EAAqB,EAAS,EAAQ,GAAM,EAAE,oBAC9C,EAAkB,EAAS,EAAQ,GAAM,EAAE,iBAC3C,EAAmB,EAAS,EAAQ,GAAM,EAAE,kBAC5C,EAAgB,EAAS,EAAQ,GAAM,EAAE;AAE/C,OACE,EAAC,MAAD,CAAK,MAAO,CAAE,SAAU,WAAY,IAAK,GAAI,KAAM,GAAI,WAAY,QAAS,QAAS,GAAI,aAAc,EAAG,UAAW,uCAArH,CACG,EAAiB,OAAS,kBACzB,EAAC,MAAD,CAAK,MAAO,CAAE,aAAc,aAA5B,gBACE,EAAC,QAAD,CAAO,MAAO,CAAE,SAAU,GAAI,WAAY,iBAAU,eACnD,EAAiB,IAAI,kBACpB,EAAC,SAAD,CAAmB,QAAA,IAAe,EAAmB,EAAE,IAAK,MAAO,CAAE,QAAS,QAAS,QAAS,UAAW,OAAQ,QAAS,SAAU,aACnI,EAAE,MADQ,EAAE,QAMpB,EAAc,OAAS,kBACtB,EAAC,MAAD,CAAA,SAAA,gBACE,EAAC,QAAD,CAAO,MAAO,CAAE,SAAU,GAAI,WAAY,iBAAU,YACnD,EAAc,IAAI,kBACjB,EAAC,SAAD,CAAmB,QAAA,IAAe,EAAgB,EAAE,IAAK,MAAO,CAAE,QAAS,QAAS,QAAS,UAAW,OAAQ,QAAS,SAAU,aAChI,EAAE,MADQ,EAAE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codefluss/plugin-configurator-3d",
3
- "version": "0.0.2-alpha.1",
3
+ "version": "0.0.2-alpha.3",
4
4
  "description": "3D model configurator with POI system and material variants",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -20,31 +20,36 @@
20
20
  "files": [
21
21
  "dist"
22
22
  ],
23
+ "scripts": {
24
+ "dev": "vite build --watch",
25
+ "build": "vite build",
26
+ "typecheck": "tsc --noEmit"
27
+ },
23
28
  "dependencies": {
24
- "@codefluss/base-types": "0.0.1-alpha.1",
25
- "@codefluss/threejs-shared": "0.0.1-alpha.1",
29
+ "@codefluss/base-types": "0.0.2-alpha.5",
30
+ "@codefluss/threejs-shared": "0.0.2-alpha.3",
26
31
  "@react-three/drei": "^10.7.7",
27
- "@react-three/fiber": "^9.4.2",
28
- "react": "^19.2.3",
29
- "react-dom": "^19.2.3",
30
- "three": "^0.181.2",
31
- "zustand": "^5.0.9"
32
+ "@react-three/fiber": "^9.5.0",
33
+ "react": "^19.2.4",
34
+ "react-dom": "^19.2.4",
35
+ "three": "^0.183.2",
36
+ "zustand": "^5.0.12"
32
37
  },
33
38
  "devDependencies": {
34
- "@codefluss/vite-config-lib": "0.0.1-alpha.4",
35
- "@types/react": "19.2.4",
36
- "@types/react-dom": "^19.2.3",
37
- "@types/three": "^0.181.0",
38
- "@vitejs/plugin-react": "^5.1.2",
39
- "lucide-react": "^0.553.0",
40
- "terser": "^5.44.1",
39
+ "@codefluss/vite-config-lib": "0.0.2-alpha.3",
40
+ "@types/react": "19.2.14",
41
+ "@types/react-dom": "19.2.3",
42
+ "@types/three": "^0.183.1",
43
+ "@vitejs/plugin-react": "^6.0.1",
44
+ "lucide-react": "^0.577.0",
45
+ "terser": "^5.46.1",
41
46
  "typescript": "^5.9.3",
42
- "vite": "^7.2.7",
47
+ "vite": "^8.0.1",
43
48
  "vite-plugin-dts": "^4.5.4"
44
49
  },
45
50
  "peerDependencies": {
46
- "react": "^19.2.0",
47
- "react-dom": "^19.2.0"
51
+ "react": "^19.2.4",
52
+ "react-dom": "^19.2.4"
48
53
  },
49
54
  "keywords": [
50
55
  "3d",
@@ -59,10 +64,5 @@
59
64
  "license": "MIT",
60
65
  "publishConfig": {
61
66
  "access": "public"
62
- },
63
- "scripts": {
64
- "dev": "vite build --watch",
65
- "build": "vite build",
66
- "typecheck": "tsc --noEmit"
67
67
  }
68
- }
68
+ }
@@ -1,14 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,20 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,3 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,13 +0,0 @@
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
@@ -1 +0,0 @@
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"}
package/dist/index.d.ts DELETED
@@ -1,16 +0,0 @@
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
@@ -1 +0,0 @@
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 DELETED
@@ -1,2 +0,0 @@
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