@liveroom-tech/react-immersive 5.3.0 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/binding-builder.css +1 -1
  2. package/dist/binding-builder.d.mts +5 -1
  3. package/dist/binding-builder.d.ts +5 -1
  4. package/dist/binding-builder.js +23 -20
  5. package/dist/binding-builder.mjs +1 -1
  6. package/dist/chunk-2JFUMJUP.mjs +1 -0
  7. package/dist/chunk-4JMJALRO.mjs +2 -0
  8. package/dist/chunk-OTSCPJWF.mjs +1 -0
  9. package/dist/chunk-P2JZ5Z7I.mjs +1 -0
  10. package/dist/chunk-UGPR4EPP.mjs +81 -0
  11. package/dist/chunk-V7WZUWJ5.mjs +1 -0
  12. package/dist/chunk-VQGYZOMX.mjs +3 -0
  13. package/dist/hosted.css +1 -1
  14. package/dist/hosted.d.mts +44 -17
  15. package/dist/hosted.d.ts +44 -17
  16. package/dist/hosted.js +22 -19
  17. package/dist/hosted.mjs +1 -1
  18. package/dist/index.css +1 -1
  19. package/dist/index.d.mts +70 -12
  20. package/dist/index.d.ts +70 -12
  21. package/dist/index.js +21 -18
  22. package/dist/index.mjs +1 -1
  23. package/dist/{materialVariants-DjTuiWmN.d.mts → modelFileResolver-Co7j1tdQ.d.mts} +122 -29
  24. package/dist/{materialVariants-DjTuiWmN.d.ts → modelFileResolver-Co7j1tdQ.d.ts} +122 -29
  25. package/dist/modelViewerProps-BibuMND7.d.ts +1988 -0
  26. package/dist/modelViewerProps-Ce4-wb57.d.mts +1988 -0
  27. package/dist/{publicProps-tJuWZgT3.d.ts → publicProps-BaJHCDa_.d.mts} +7 -0
  28. package/dist/{publicProps-tJuWZgT3.d.mts → publicProps-CP18d_mt.d.ts} +7 -0
  29. package/dist/simple-model-viewer.d.mts +2 -4
  30. package/dist/simple-model-viewer.d.ts +2 -4
  31. package/dist/simple-model-viewer.js +3 -3
  32. package/dist/simple-model-viewer.mjs +1 -1
  33. package/dist/utils.d.mts +62 -4
  34. package/dist/utils.d.ts +62 -4
  35. package/dist/utils.js +2 -1
  36. package/dist/utils.mjs +1 -1
  37. package/package.json +1 -1
  38. package/dist/chunk-4FDMYUGT.mjs +0 -3
  39. package/dist/chunk-CV4E7DOO.mjs +0 -79
  40. package/dist/chunk-F4WT3HEK.mjs +0 -1
  41. package/dist/chunk-FPJZDEON.mjs +0 -1
  42. package/dist/chunk-JHKMRMJH.mjs +0 -1
  43. package/dist/chunk-TW2M4UXT.mjs +0 -1
  44. package/dist/chunk-W24UP6NM.mjs +0 -1
  45. package/dist/modelInfo-BQ5UZu95.d.ts +0 -43
  46. package/dist/modelInfo-CcYpydB7.d.mts +0 -43
  47. package/dist/modelViewerProps-BalkRDni.d.ts +0 -618
  48. package/dist/modelViewerProps-DdsJDRB7.d.mts +0 -618
  49. package/dist/rendererBackend-C_Jb4_Jy.d.mts +0 -917
  50. package/dist/rendererBackend-C_Jb4_Jy.d.ts +0 -917
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- "use client";import{b as Ye,d as qe}from"./chunk-TW2M4UXT.mjs";import{a as Qe}from"./chunk-MMO7KCYU.mjs";import{a as ce,b as je,c as Se,d as Be,e as kt}from"./chunk-FPJZDEON.mjs";import{A as Ze,B as Oe,C as et,D as ve,b as $e,d as St,r as ye,z as Xe}from"./chunk-CV4E7DOO.mjs";import{a as ze,b as Ge,u as We}from"./chunk-F4WT3HEK.mjs";import{A as Pt,B as At,C as Et,E as Tt,F as Lt,G as It,H as Je,K as Dt,L as Ut,a as Bt,c as vt,g as W,p as Mt,q as pe,v as Ke,w as ne,x as Ce,z as xt}from"./chunk-W24UP6NM.mjs";import{a as jt,w as Rt}from"./chunk-JHKMRMJH.mjs";import"./chunk-JR557W27.mjs";import{jsx as Ht}from"react/jsx-runtime";function le(e){return Qe("model-viewer","ModelViewer"),Ht(Xe,{...qe(e,Ye)})}import{useCallback as _t,useEffect as tt,useMemo as nt,useRef as Ft,useState as it}from"react";import{jsx as K,jsxs as rt}from"react/jsx-runtime";function ot(e){return K(ze,{labels:e.labels,children:K(Nt,{...e})})}function Nt({before:e,after:t,layout:n="slider",split:s,onSplitChange:c,reveal:b="auto",...l}){let O=Ge(),[w,p]=it(b==="auto");tt(()=>{b==="auto"&&p(!0)},[b]);let[j,m]=it(.5),A=Oe(s??j),x=_t(I=>{let E=Oe(I);s===void 0&&m(E),c?.(E)},[s,c]),M=nt(()=>Ze(),[]);tt(()=>()=>M.detach(),[M]);let T=[e,t],_=nt(()=>[0,1].map(I=>E=>{M.attach(I,E.raw.controls,E.invalidate)}),[M]),u=T.map((I,E)=>{let{label:U,...h}=I,F={preset:"minimal",...l,...h},V=h.onViewerReady??l.onViewerReady;return{...F,onViewerReady:o=>{_[E](o),V?.(o)}}}),y=[e.label??O("compareBefore"),t.label??O("compareAfter")];(!u[0].modelUrl||!u[1].modelUrl)&&console.error("[react-immersive] CompareViewer needs a modelUrl, shared or on each side.");let R=Ft(null);if(!w)return K(We,{className:"ri-compare",background:$e(l.backgroundColor,l.sceneConfig),poster:l.poster??t.poster??e.poster,onReveal:()=>p(!0)});if(n==="side-by-side")return K("div",{className:"ri-compare ri-compare--sideBySide",children:u.map((I,E)=>rt("div",{className:"ri-compare__pane",children:[K(le,{...I}),K("span",{className:"ri-compare__label",children:y[E]})]},E))});let C=`${A*100}%`;return rt("div",{ref:R,className:"ri-compare ri-compare--slider",style:{"--ri-compare-split":C},children:[K("div",{className:"ri-compare__layer",children:K(le,{...u[0]})}),K("div",{className:"ri-compare__layer ri-compare__layer--after",children:K(le,{...u[1]})}),K(et,{split:A,onSplitChange:x,labels:[y[0],y[1]],containerRef:R})]})}import{useCallback as Ve,useRef as mt}from"react";import{useCallback as k,useMemo as st,useState as zt}from"react";var at={baseColor:"texture",metalness:"metalnessMap",roughness:"roughnessMap",emissive:"emissiveMap",alpha:"alphaMap",normal:"normalMap",bump:"bumpMap",ao:"aoMap",displacement:"displacementMap",clearcoat:"clearcoatMap",clearcoatRoughness:"clearcoatRoughnessMap",clearcoatNormal:"clearcoatNormalMap",anisotropy:"anisotropyMap",transmission:"transmissionMap",thickness:"thicknessMap",sheenColor:"sheenColorMap",sheenRoughness:"sheenRoughnessMap",specularIntensity:"specularIntensityMap",specularColor:"specularColorMap"};function ct(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n&&typeof n=="object"?{...n}:n]))}function Gt(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t.visible===!1).map(([t])=>[t,!0]))}function Me(e){let[t,n]=zt(e),s=k((o,a)=>{n(g=>a===void 0?ce(g,o):ce(g,o,a))},[]),c=k((o,a)=>s(o,je(a)),[s]),b=k((o,a)=>c(o,{baseColor:a}),[c]),l=k((o,a,g="baseColor")=>{let S=at[g],B=typeof a=="string"?{path:a}:a;s(o,{style:{material:{[S]:B}}})},[s]),O=k((o,a="baseColor")=>{let g=at[a];s(o,{style:{material:{[g]:void 0}}})},[s]),w=k((o,a)=>{n(g=>{let S=W(g,o);if(!S)return g;let B=ct(g[S]?.style?.material),N=ne(g,a);if(N.length===0)return g;let Y=g;for(let i of N){let r=g[i];r&&(Y===g&&(Y={...g}),Y[i]={...r,style:{...r.style,material:ct(B)}})}return Y})},[]),p=k(o=>s(o,{style:{material:void 0}}),[s]),j=k((o,a)=>s(o,{transform:a}),[s]),m=k(o=>s(o,{transform:void 0}),[s]),A=k((o,a)=>s(o,{metadata:a}),[s]),x=k((o,a)=>{n(g=>{let S=g;for(let B of ne(g,o)){let N=g[B],Y=a(N.decals??[]);S===g&&(S={...g}),S[B]={...N,decals:Y.length>0?Y:void 0}}return S})},[]),M=k((o,a)=>{let g=a.id??`decal-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;return x(o,S=>[...S.filter(B=>B.id!==g),{...a,id:g}]),g},[x]),T=k((o,a,g)=>x(o,S=>S.map(B=>B.id===a?{...B,...g}:B)),[x]),_=k((o,a)=>x(o,g=>g.filter(S=>S.id!==a)),[x]),u=k(o=>Ce(t,o),[t]),y=k(o=>ne(t,o).map(a=>t[a]?.id??a),[t]),R=k(o=>{let a=W(t,o);return a?t[a]?.style?.material??null:null},[t]),C=k(o=>s(o,{visible:!1}),[s]),I=k(o=>s(o,{visible:!0}),[s]),E=k(o=>{n(a=>{let g=ne(a,o).reduce((S,B)=>{let N=a[B];return N&&S.push({ids:B,patch:{visible:N.visible===!1}}),S},[]);return ce(a,g)})},[n]),U=k(()=>{n(o=>ce(o,Object.keys(o),{visible:!0}))},[n]),h=st(()=>Gt(t),[t]),F=st(()=>Object.keys(h).map(o=>t[o]?.id??o),[h,t]),V=k(o=>{let a=W(t,o);return a?t[a]?.visible===!1:!1},[t]);return{objectBindings:t,setObjectBindings:n,updateObjectBindings:s,setMaterial:c,setBaseColor:b,setTexture:l,clearTexture:O,copyMaterial:w,resetMaterial:p,getMaterial:R,setTransform:j,resetTransform:m,updateMetadata:A,addDecal:M,updateDecal:T,removeDecal:_,selectObjectBindings:u,selectObjectBindingIds:y,hiddenObjects:h,hiddenObjectIds:F,hideObject:C,showObject:I,toggleObjectVisibility:E,isObjectHidden:V,clearHiddenObjects:U}}import{useCallback as $,useMemo as Wt,useRef as $t,useState as Kt}from"react";function Re(e){let t=$t(null),[n,s]=Kt(()=>{let u=typeof e=="function"?e():e;return t.current=u,u}),c=$(u=>{s(y=>{let R=typeof u=="function"?u(y):u;return Se(y,R)})},[]),b=$(()=>{let u=t.current;u&&s(u)},[]),l=$((u,y)=>{c(R=>({lighting:{lights:R.lighting.lights.map(C=>C.id===u?{...C,...y}:C)}}))},[c]),O=$(u=>{c(y=>y.lighting.lights.some(R=>R.id===u.id)?{}:{lighting:{lights:[...y.lighting.lights,Be(u)]}})},[c]),w=$(u=>{c(y=>({lighting:{lights:y.lighting.lights.filter(R=>R.id!==u)}}))},[c]),p=$((u,y)=>l(u,{intensity:y}),[l]),j=$((u,y)=>l(u,{color:y}),[l]),m=$(u=>l(u,{visible:!0}),[l]),A=$(u=>l(u,{visible:!1}),[l]),x=$(u=>{c(y=>({lighting:{lights:y.lighting.lights.map(R=>R.id===u?{...R,visible:!R.visible}:R)}}))},[c]),M=$((u,y)=>l(u,{attachment:y,attachedToCamera:!1}),[l]),T=$(u=>l(u,{attachment:void 0}),[l]),_=Wt(()=>({items:n.lighting.lights,get:u=>n.lighting.lights.find(y=>y.id===u),add:O,update:l,remove:w,setIntensity:p,setColor:j,show:m,hide:A,toggle:x,attach:M,detach:T}),[n.lighting.lights,O,l,w,p,j,m,A,x,M,T]);return{sceneConfig:n,setSceneConfig:s,updateSceneConfig:c,resetSceneConfig:b,lights:_}}import{useCallback as xe}from"react";function Pe({bindings:e,scene:t,camera:n,animations:s,isolation:c,onAction:b}){let{objectBindings:l,updateObjectBindings:O,showObject:w,hideObject:p,toggleObjectVisibility:j}=e,m=t?.updateSceneConfig,A=n?.focusObject,x=n?.fitScene,M=n?.resetView,T=n?.setCameraTarget,_=n?.setCameraState,u=s?.play,y=s?.pause,R=s?.stop,C=s?.setSpeed,I=s?.seek,E=c?.handleIsolationChange,U=xe(V=>{let o=W(l,V);return o?l[o]?.actions??[]:[]},[l]),h=xe(async V=>{for(let o of V.action.effects??[]){if("objectBindings"in o){O(o.target,o.objectBindings);continue}if("sceneConfig"in o){m?.(o.sceneConfig);continue}if("isolation"in o){E?.(o.isolation);continue}if("visibility"in o){o.visibility==="show"?w(o.target):o.visibility==="hide"?p(o.target):j(o.target);continue}if("camera"in o){let g=o.camera;g.type==="focus-object"?await A?.(g.objectId??V.objectId):g.type==="fit-scene"?await x?.():g.type==="reset"?await M?.():g.type==="set-target"?await T?.(g.target,g.transition??!0):await _?.(g.state,g.transition??!0);continue}let a=o.animation;if(a.type==="play"){let{type:g,clip:S,...B}=a;u?.(S,B)}else a.type==="pause"?y?.(a.clip):a.type==="stop"?R?.(a.clip):a.type==="set-speed"?C?.(a.speed,a.clip):I?.(a.time,a.clip)}await b?.(V)},[x,A,p,b,y,u,M,I,C,_,T,E,w,R,j,O,m]),F=xe(async(V,o)=>{let a=W(l,V);if(!a)return null;let g=l[a],S=g?.actions?.find(N=>N.id===o);if(!g||!S)return null;let B={objectId:a,action:S,binding:g};return await h(B),B},[h,l]);return{getActionsForObject:U,handleAction:h,runAction:F}}import{useCallback as ue,useRef as lt}from"react";function Jt(e){return typeof e=="function"?e:e?.handleViewerReady??null}function Ae(...e){let t=lt(null),n=lt(e);n.current=e;let s=ue(w=>{t.current=w;let p=new Set;for(let j of n.current){let m=Jt(j);m&&!p.has(m)&&(p.add(m),m(w))}},[]),c=ue(()=>t.current,[]),b=ue(w=>{let p=t.current;return p?p.captureImage(w):Promise.reject(new Error("ModelViewer is not ready yet."))},[]),l=ue(()=>{let w=t.current;return w?(w.invalidate(),!0):!1},[]),O=ue(w=>{let p=t.current;return p?p.captureVideo(w):Promise.reject(new Error("ModelViewer is not ready yet."))},[]);return{handleViewerReady:s,getViewer:c,captureImage:b,captureVideo:O,invalidate:l}}import{useCallback as L,useEffect as Xt,useRef as X}from"react";import{Material as Yt,PointLight as qt,Vector3 as Qt}from"three";var Le=["emissiveIntensity","opacity","metalness","roughness","transmission","clearcoat","clearcoatRoughness","ior","thickness"],me=1;function be(e){return typeof e=="string"?[e]:e}function we(e,t=0,n=1){return Math.min(n,Math.max(t,e))}function Ee(e,t){return e+Math.random()*(t-e)}function dt([e,t],n){return e+(t-e)*n}function Te([e,t],n){return[e[0]+(t[0]-e[0])*n,e[1]+(t[1]-e[1])*n,e[2]+(t[2]-e[2])*n]}function ut(e,t){let n=we(e);switch(t){case"ease-in":return n*n;case"ease-out":return 1-(1-n)*(1-n);case"ease-in-out":return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2;default:return n}}function Zt(e){let t=e.material;return t?(Array.isArray(t)?t:[t]).filter(n=>n instanceof Yt):[]}function en(e){let t={opacity:e.opacity,transparent:e.transparent};e.color&&(t.baseColor=`#${e.color.getHexString()}`),e.emissive&&(t.emissive=`#${e.emissive.getHexString()}`);for(let n of Le){let s=e[n];typeof s=="number"&&(t[n]=s)}return t}function ft(e,t){t.baseColor!==void 0&&e.color&&e.color.set(t.baseColor),t.emissive!==void 0&&e.emissive&&e.emissive.set(t.emissive);for(let n of Le){let s=t[n];s!==void 0&&typeof e[n]=="number"&&(e[n]=s)}t.transparent!==void 0&&(e.transparent=t.transparent),e.needsUpdate=!0}function tn(e){return{position:[e.position.x,e.position.y,e.position.z],rotation:[e.rotation.x,e.rotation.y,e.rotation.z],scale:[e.scale.x,e.scale.y,e.scale.z],visible:e.visible}}function nn(e,t){if(t.position&&e.position.set(...t.position),t.rotation&&e.rotation.set(...t.rotation),t.scale!==void 0){let n=typeof t.scale=="number"?[t.scale,t.scale,t.scale]:t.scale;e.scale.set(...n)}t.visible!==void 0&&(e.visible=t.visible),e.updateMatrix(),e.updateMatrixWorld(!0)}function Ie(e={}){let t=X(e);t.current=e;let n=X(null),s=X(null),c=X(null),b=X(new Map),l=X(new Map),O=X(new Map),w=X(new Map),p=L(i=>{let r=n.current;if(!r)return null;let f=W(r.objectBindings,i);return r.raw.nodes[i]??(f?r.raw.nodes[f]:null)??(r.raw.scene?Ke(r.raw.scene,i):null)??null},[]),j=L(i=>{let r=n.current;return r?typeof i=="object"&&!Array.isArray(i)?ne(r.objectBindings,i):be(i).map(f=>W(r.objectBindings,f)??f):typeof i=="string"?[i]:Array.isArray(i)?i:[]},[]),m=L(()=>{n.current?.invalidate()},[]),A=L((i,r)=>{let f=!1;for(let d of j(i)){let v=p(d);if(v)for(let D of Zt(v))O.current.has(D)||O.current.set(D,en(D)),ft(D,r),f=!0}return f},[p,j]),x=L((i,r)=>{let f=A(i,r);return f&&m(),f},[m,A]),M=L((i,r)=>{let f=!1;for(let d of j(i)){let v=p(d);v&&(w.current.has(v)||w.current.set(v,tn(v)),nn(v,r),f=!0)}return f},[p,j]),T=L((i,r)=>{let f=M(i,r);return f&&m(),f},[m,M]),_=L(i=>{let r=p(i);if(!r)return null;r.updateWorldMatrix(!0,!1);let f=r.getWorldPosition(new Qt);return[f.x,f.y,f.z]},[p]),u=L(i=>{let r=l.current.get(i);return r?(r.light.removeFromParent(),r.light.dispose(),l.current.delete(i),m(),!0):!1},[m]),y=L(i=>{let r=p(i.target);if(!r)return!1;let f=l.current.get(i.id),d=f?.light??new qt;return f&&f.target!==i.target&&d.removeFromParent(),d.name=`react-immersive-runtime-light:${i.id}`,d.color.set(i.color??"#ffffff"),d.intensity=i.intensity??1,d.distance=i.distance??0,d.decay=i.decay??2,d.castShadow=i.castShadow??!1,d.position.set(...i.offset??[0,0,0]),d.parent!==r&&r.add(d),l.current.set(i.id,{light:d,target:i.target}),m(),!0},[m,p]),R=L((i,r)=>{let f=l.current.get(i);if(!f)return!1;if(r.target&&r.target!==f.target){let d=p(r.target);if(!d)return!1;f.light.removeFromParent(),d.add(f.light),f.target=r.target}return r.color!==void 0&&f.light.color.set(r.color),r.intensity!==void 0&&(f.light.intensity=r.intensity),r.distance!==void 0&&(f.light.distance=r.distance),r.decay!==void 0&&(f.light.decay=r.decay),r.offset!==void 0&&f.light.position.set(...r.offset),r.castShadow!==void 0&&(f.light.castShadow=r.castShadow),m(),!0},[m,p]),C=L((i,r)=>{let f=d=>r[d%r.length]??0;for(let d of i.materials??[])j(d.targets).forEach((v,D)=>{let P=f(D),H={};for(let J of Le){let z=d.values[J];z&&(H[J]=dt(z,P))}A(v,H)});for(let d of i.transforms??[])j(d.targets).forEach((v,D)=>{let P=f(D),H={};d.values.position&&(H.position=Te(d.values.position,P)),d.values.rotation&&(H.rotation=Te(d.values.rotation,P)),d.values.scale&&(H.scale=Te(d.values.scale,P)),M(v,H)});for(let d of i.lights??[])be(d.lights).forEach((v,D)=>{let P=l.current.get(v);P&&(P.light.intensity=dt(d.intensity,f(D)))})},[j,A,M]),I=X(()=>{}),E=X(()=>{});E.current=i=>{c.current=null;let r=!1;for(let[f,d]of b.current){d.startedAt===null&&(d.startedAt=i);let v=d.lastFrameAt??i;d.lastFrameAt=i;let D=d.override&&d.override.until>i?d.override.level:null;d.override&&D===null&&(d.override=null);let P=d.update(i,i-d.startedAt,Math.min(100,i-v),D);r=!0,P||(b.current.delete(f),d.onComplete?.())}r&&m(),b.current.size>0&&I.current()},I.current=()=>{c.current!==null||typeof requestAnimationFrame>"u"||(c.current=requestAnimationFrame(i=>E.current(i)))};let U=L(i=>(b.current.set(i.id,i),I.current(),i.id),[]),h=L((i,r={})=>{let f=r.id??`transition-${me++}`,d=Math.max(1,r.duration??400),v=r.easing??"ease-in-out";return U({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(D,P,H,J)=>{let z=J??ut(P/d,v);return C(i,[z]),P<d}})},[C,U]),F=L((i,r={})=>{let f=r.id??`pulse-${me++}`,d=Math.max(1,r.duration??1e3),v=r.minLevel??0,D=r.maxLevel??1,P=r.repeat??1/0,H=r.synchronized??!0,J=Math.max(1,...[...i.materials??[],...i.transforms??[]].map(z=>j(z.targets).length),...(i.lights??[]).map(z=>be(z.lights).length));return U({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(z,oe,se,q)=>{let G=oe/d,Q=Array.from({length:H?1:J},(ae,re)=>{if(q!==null)return q;let ge=G+(H?0:re/J),te=.5-Math.cos(ge%1*Math.PI*2)/2;return v+(D-v)*te});return C(i,Q),P===1/0||G<P}})},[C,U,j]),V=L((i,r={})=>{let f=r.id??`timeline-${me++}`,d=r.repeat??1,v=i.map(P=>({...P,duration:Math.max(1,P.duration),hold:Math.max(0,P.hold??0)})),D=Math.max(1,v.reduce((P,H)=>P+H.duration+H.hold,0));return U({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(P,H,J,z)=>{if(v.length===0||d<=0)return!1;let oe=H/D;if(d!==1/0&&oe>=d){for(let G of v)C(G.channels,[1]);return!1}let se=H%D,q=0;for(let G of v){let Q=q+G.duration,ae=Q+G.hold;if(se>=Q){C(G.channels,[z??1]),q=ae;continue}if(se>=q){let re=z??ut((se-q)/G.duration,G.easing??"ease-in-out");C(G.channels,[re]);break}}return!0}})},[C,U]),o=L((i,r={})=>{let f=r.id??`flicker-${me++}`,d=r.synchronized??!0,v=r.minLevel??.15,D=r.maxLevel??1,P=r.interval??[45,160],H=typeof P=="number"?[P,P]:P,J=[Math.max(1,Math.min(...H)),Math.max(1,Math.max(...H))],z=we(r.response??.7,.01,1),oe=we(r.blackoutChance??.08),se=we(r.flashChance??.12),q=r.flashLevel??1.15,G=Math.max(1,...[...i.materials??[],...i.transforms??[]].map(te=>j(te.targets).length),...(i.lights??[]).map(te=>be(te.lights).length)),Q=d?1:G,ae=Array.from({length:Q},()=>v),re=Array.from({length:Q},()=>v),ge=Array.from({length:Q},()=>0);return U({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(te,yt,Ct,Fe)=>{for(let Z=0;Z<Q;Z+=1){if(Fe!==null)re[Z]=Fe;else if(te>=ge[Z]){let Ne=Math.random();re[Z]=Ne<oe?Ee(0,Math.min(.04,v)):Ne<oe+se?q:Ee(v,D),ge[Z]=te+Ee(...J)}let Ot=1-Math.pow(1-z,Math.max(1,Ct)/16.67);ae[Z]+=(re[Z]-ae[Z])*Ot}return C(i,ae),r.duration===void 0||yt<r.duration}})},[C,U,j]),a=L((i,r,f)=>{let d=b.current.get(i);if(!d)return!1;let v=typeof performance>"u"?Date.now():performance.now();return d.override={level:r,until:v+Math.max(0,f)},I.current(),!0},[]),g=L(i=>b.current.delete(i),[]),S=L(()=>{b.current.clear(),c.current!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(c.current),c.current=null)},[]),B=L(()=>{for(let[i,r]of O.current)ft(i,r);O.current.clear();for(let[i,r]of w.current)i.position.set(...r.position),i.rotation.set(...r.rotation),i.scale.set(...r.scale),i.visible=r.visible,i.updateMatrix(),i.updateMatrixWorld(!0);w.current.clear();for(let i of l.current.values())i.light.removeFromParent(),i.light.dispose();l.current.clear(),m()},[m]),N=L(()=>{S(),B()},[B,S]),Y=L(i=>{s.current&&s.current!==i.raw.scene&&B(),n.current=i,s.current=i.raw.scene,t.current.onViewerReady?.(i)},[B]);return Xt(()=>()=>{N(),n.current=null,s.current=null},[N]),{handleViewerReady:Y,setMaterial:x,setTransform:T,getWorldPosition:_,addPointLight:y,updatePointLight:R,removePointLight:u,transition:h,timeline:V,pulse:F,flicker:o,overrideEffect:a,stopEffect:g,stopAllEffects:S,resetRuntime:N}}import{useCallback as rn,useState as on}from"react";function ke(){let[e,t]=on(null),n=rn(s=>{t(s)},[t]);return{hoveredObjectBinding:e,handleHoveredObject:n}}import{useCallback as gt,useState as sn}from"react";function De(e=null){let[t,n]=sn(e),s=gt((b,l)=>n({...l,target:b}),[]),c=gt(()=>n(null),[]);return{isolation:t,isolate:s,clearIsolation:c,handleIsolationChange:n}}import{useCallback as he,useState as ie}from"react";function Ue(){let[e,t]=ie(!0),[n,s]=ie(!1),[c,b]=ie(null),[l,O]=ie(null),[w,p]=ie(0),[j,m]=ie([]),[A,x]=ie([]),[M,T]=ie([]),_=he(C=>{O(C.bounds),p(C.objectCount),m(C.materialVariants),x(C.materialVariantGroups),b(null),t(!1),s(!0)},[]),u=he(C=>T(C),[]),y=he(C=>{b(C),O(null),p(0),m([]),x([]),T([]),t(!1),s(!1)},[]),R=he(()=>{t(!0),s(!1),b(null),O(null),p(0),m([]),x([]),T([])},[]);return{isLoading:e,isReady:n,error:c,bounds:l,objectCount:w,materialVariants:j,materialVariantGroups:A,objects:M,handleModelLoaded:_,handleObjectCatalog:u,handleLoadError:y,resetModelState:R}}import{useCallback as pt,useState as an}from"react";function He(e=null){let[t,n]=an(e),s=pt(b=>{n(b)},[n]),c=pt(()=>{n(null)},[]);return{selectedObjectBinding:t,setSelectedObjectBinding:n,handleObjectSelect:s,clearSelection:c}}var cn={};function ln(e={}){let t=mt(e);t.current=e;let n=mt(e.bindings===void 0||e.bindings==="auto"),s=Me(()=>{let h=t.current.bindings;return h===void 0||h==="auto"?cn:typeof h=="function"?h():h}),c=Re(()=>{let h=t.current.sceneConfig;return h===void 0?pe:typeof h=="function"?h():h}),b=He(),l=ke(),O=ye(e.camera),w=Ue(),p=ve(),j=De(),m=Ie(),A=Ae(O,m),x=Pe({bindings:s,scene:c,camera:O,animations:p,isolation:j,onAction:e.onAction}),{setObjectBindings:M}=s,{handleObjectCatalog:T}=w,_=Ve(h=>{T(h),n.current&&M(F=>{let V=Je(h.map(o=>o.name));for(let o of Object.keys(V))F[o]&&(V[o]=F[o]);return V})},[T,M]),{handleObjectSelect:u}=b,y=Ve(h=>{u(h),t.current.onObjectSelect?.(h)},[u]),{handleHoveredObject:R}=l,C=Ve(h=>{R(h),t.current.onObjectHover?.(h)},[R]),{handleLoadError:I}=w,E=Ve(h=>{I(h),t.current.onLoadError?.(h)},[I]),U=e.sceneConfig!==void 0||c.sceneConfig!==pe;return{props:{objectBindings:s.objectBindings,onObjectBindingsChange:M,selectedObject:b.selectedObjectBinding,onObjectSelect:y,onObjectHover:C,onCameraChange:O.handleCameraChange,onViewerReady:A.handleViewerReady,onModelLoaded:w.handleModelLoaded,onLoadError:E,onObjectCatalog:_,onAnimationsReady:p.handleAnimationsReady,onAction:x.handleAction,onSceneConfigChange:c.setSceneConfig,isolation:j.isolation,onIsolationChange:j.handleIsolationChange,...U?{sceneConfig:c.sceneConfig}:{}},bindings:s,selection:b,hover:l,camera:O,model:w,animations:p,actions:x,scene:c,isolation:j,effects:m,connection:A}}import{useMemo as dn}from"react";function un(e,t){return dn(()=>{if(!t)return null;let n=e[t];return n||(Object.values(e).find(s=>s.id===t||s.modelObjectId===t)??null)},[e,t])}import{useMemo as fn}from"react";function gn(e){return fn(()=>Object.values(e).map(t=>t.modelObjectId),[e])}import{useCallback as de,useEffect as _e,useRef as ee,useState as pn}from"react";function ht(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fe(e){return typeof e=="number"&&Number.isFinite(e)}function bt(e){return Array.isArray(e)&&e.length===3&&e.every(fe)}function mn(e){return!ht(e)||!bt(e.position)||!bt(e.target)||e.fov!==null&&!fe(e.fov)||!fe(e.zoom)||e.zoom<=0||e.azimuthAngle!==void 0&&!fe(e.azimuthAngle)||e.polarAngle!==void 0&&!fe(e.polarAngle)?null:{position:e.position,target:e.target,fov:e.fov,zoom:e.zoom,azimuthAngle:e.azimuthAngle,polarAngle:e.polarAngle}}function bn(e){if(!ht(e))return null;let t;if(e.camera!==void 0){let c=mn(e.camera);if(!c)return null;t=c}let n;if(e.hidden!==void 0){if(!Array.isArray(e.hidden)||!e.hidden.every(c=>typeof c=="string"))return null;n=e.hidden}let s;if(e.selected===null||typeof e.selected=="string")s=e.selected;else if(e.selected!==void 0)return null;return{camera:t,hidden:n,selected:s}}function wt(e,t,n){let s=Object.values(t).filter(c=>c.visible===!1).map(c=>c.id);return{camera:e??void 0,hidden:s,selected:n?.id??null}}function wn(e,t){if((!!e.hidden?.length||!!e.selected)&&Object.keys(t).length===0)return null;let s={};if(e.hidden){let c=new Set(e.hidden);s.bindings=Object.fromEntries(Object.entries(t).map(([b,l])=>[b,{...l,visible:!c.has(l.id)}]))}if(e.selected!==void 0){let c=e.selected?W(t,e.selected):null;s.selected=c?t[c]:null}return s}function hn({cameraState:e,setCameraState:t,objectBindings:n,onObjectBindingsChange:s,selectedObjectBinding:c,setSelectedObjectBinding:b,paramKey:l="view",debounceMs:O=400,autoSync:w=!0}){let p=ee(null),j=ee(null),m=ee(null),A=ee(null),x=ee(null),M=de(()=>{x.current!==null&&(window.clearTimeout(x.current),x.current=null),m.current=null,A.current=null},[]),T=de(()=>{let V=wt(e,n,c);return`${l}=${encodeURIComponent(JSON.stringify(V))}`},[e,n,c,l]),_=de(()=>{let V=new URL(window.location.href);return V.hash=T(),V.toString()},[T]),u=de(V=>{let o=new URL(window.location.href);o.hash=V,window.history.replaceState(null,"",o.toString()),j.current=V,p.current=new URLSearchParams(o.hash.slice(1)).get(l)},[l]),y=de(()=>{M(),u(T())},[T,M,u]),R=ee({cameraState:e,objectBindings:n,selectedObjectBinding:c});R.current={cameraState:e,objectBindings:n,selectedObjectBinding:c};let[C,I]=pn(!1);_e(()=>{if(!w||!C){M();return}let V=R.current,o=wt(V.cameraState,V.objectBindings,V.selectedObjectBinding),a=`${l}=${encodeURIComponent(JSON.stringify(o))}`;if(a===j.current){M();return}a===m.current&&O===A.current||(M(),m.current=a,A.current=O,x.current=window.setTimeout(()=>{x.current=null,m.current=null,A.current=null,u(a)},Math.max(0,O)))},[w,e,M,O,n,l,C,c,u]),_e(()=>M,[M]);let E=ee(null),U=ee(null),h=ee(null),F=de(async()=>{let V=B=>(I(!0),B),o=window.location.hash.startsWith("#")?window.location.hash.slice(1):window.location.hash,a=new URLSearchParams(o).get(l);if(!a)return E.current=null,V(!1);if(a===U.current)return!1;if(a===p.current||a===E.current)return V(!1);let g;try{g=JSON.parse(a)}catch{return V(!1)}let S=bn(g);if(!S)return V(!1);U.current=a;try{S.camera&&h.current!==a&&(await t(S.camera,!1),h.current=a);let B=wn(S,n);return B?(B.bindings&&s(B.bindings),B.selected!==void 0&&b(B.selected),E.current=a,V(!0)):!1}finally{U.current===a&&(U.current=null)}},[n,s,l,t,b]);return _e(()=>{let V=()=>{F().catch(()=>{})};return window.addEventListener("hashchange",V),()=>{window.removeEventListener("hashchange",V)}},[F]),{getShareUrl:_,syncUrl:y,restoreFromUrl:F}}import{useCallback as Vn,useState as Vt}from"react";var yn={};function Cn(e){let[t,n]=Vt(e),[s,c]=Vt(e[0]?.url??""),b=Vn(l=>{n(O=>O.map(w=>w.url===s?{...w,objectBindings:l}:w))},[s]);return{modelUrl:s,models:t,onModelChange:c,objectBindings:yn,onObjectBindingsChange:b}}export{Bt as ACTION_CATALOG,ot as CompareViewer,jt as DEFAULT_MODEL_VIEWER_LABELS,pe as DEFAULT_SCENE_CONFIG,Mt as DEFAULT_SECTION_CONFIG,Ut as MATERIAL_BLENDING_MODES,Dt as MATERIAL_SIDES,St as MODEL_VIEWER_PRESETS,le as ModelViewer,Et as applyIsolation,Pt as applyStyleRules,It as buildBindingsFromNodes,Rt as chooseMaterialVariant,xt as colorScaleValue,Lt as createDefaultBinding,kt as defineObjectBindings,vt as findCatalogAction,Tt as inferType,At as isolatedBindingKeys,je as material,ce as patchBindings,Se as patchSceneConfig,Be as sceneLight,ne as selectBindingKeys,Ce as selectBindings,un as useObjectBinding,gn as useObjectBindingIds,Me as useObjectBindings,Re as useSceneConfig,hn as useShareableViewerState,ln as useViewer,Pe as useViewerActions,ve as useViewerAnimations,ye as useViewerCamera,Ae as useViewerConnection,Ie as useViewerEffects,ke as useViewerHover,De as useViewerIsolation,Ue as useViewerModel,Cn as useViewerModels,He as useViewerSelection};
1
+ "use client";import{c as he}from"./chunk-2JFUMJUP.mjs";import"./chunk-MMO7KCYU.mjs";import{a as pe,b as He,c as _e,d as Ne,e as gn}from"./chunk-P2JZ5Z7I.mjs";import{I as ut,J as gt,K as De,L as ft,M as qe,N as yn,c as Ee,g as lt,i as en}from"./chunk-UGPR4EPP.mjs";import{a as st,b as at,y as ct}from"./chunk-OTSCPJWF.mjs";import{Aa as Qt,Ba as tn,Da as nn,Ha as le,Ia as Le,K as Se,Ka as on,L as Oe,La as sn,M as kt,Ma as an,N as Ut,Na as cn,Oa as ln,Pa as dn,Qa as un,R as re,Ra as dt,S as Te,U as Dt,Ua as ke,V as Ht,Va as Ue,Wa as fn,Xa as pn,Ya as mn,Za as bn,_a as wn,da as _t,e as ot,f as At,fa as Nt,g as Pt,ha as qt,ia as Ft,j as Et,ja as Kt,k as Tt,ka as Gt,l as It,la as $t,m as ee,ma as zt,na as Wt,oa as Yt,pa as fe,qa as ye,ra as Ie,wa as Xt,xa as Jt}from"./chunk-4JMJALRO.mjs";import{L as rn,j as Lt,q as Zt}from"./chunk-V7WZUWJ5.mjs";import"./chunk-JR557W27.mjs";import{useCallback as hn,useEffect as je,useMemo as Be,useRef as Fe,useState as me}from"react";import{jsx as ie,jsxs as Ke}from"react/jsx-runtime";var Vn=Object.freeze({});function pt(e){return ie(st,{labels:e.labels,children:ie(Cn,{...e})})}function Cn({before:e,after:t,layout:i="slider",split:s,onSplitChange:g,reveal:y="auto",semanticComparison:l=!1,showComparisonOutlines:A,onComparisonOutlinesChange:B,onComparisonChange:O,linkSections:v,...m}){let k=at(),[E,C]=me(y==="auto");je(()=>{y==="auto"&&C(!0)},[y]);let[h,b]=me(.5),[f,S]=me(!0),x=A??f,j=R=>{A===void 0&&S(R),B?.(R)},q=De(s??h),X=hn(R=>{let P=De(R);s===void 0&&b(P),g?.(P)},[s,g]),_=Fe([null,null]),[V,J]=me([null,null]),[N,a]=me(null),[r,c]=me(null),u=[{...m,...e},{...m,...t}];je(()=>a(null),[u[0].sceneConfig?.section,u[1].sceneConfig?.section]);let w=R=>{let P=u[R].objectBindings;return P&&typeof P=="object"?P:V[R]?.url===u[R].modelUrl?V[R].bindings:Vn},L=w(0),$=w(1),n=Be(()=>l?ke({objectBindings:L,sceneConfig:u[0].sceneConfig},{objectBindings:$,sceneConfig:u[1].sceneConfig},typeof l=="object"?l:{}):null,[l,L,$,u[0].sceneConfig,u[1].sceneConfig]),o=n?JSON.stringify(n):"",p=Fe(null);je(()=>{n&&p.current!==o&&(p.current=o,O?.(n))},[n,o,O]);let d=n?.objects.find(R=>R.id===r),M=Be(()=>n?[Ue(n,"before",r),Ue(n,"after",r)]:null,[n,r]),I=Be(()=>gt(),[]);je(()=>()=>I.detach(),[I]);let T=[e,t],D=Be(()=>[0,1].map(R=>(P,W)=>{_.current[R]=P,J(K=>K[R]?.bindings===P.objectBindings&&K[R]?.url===W?K:K.map((G,we)=>we===R?{url:W,bindings:P.objectBindings}:G)),I.attach(R,P.raw.controls,P.invalidate)}),[I]),z=T.map((R,P)=>{let{label:W,...K}=R,G={preset:"minimal",...m,...K},we=K.onViewerReady??m.onViewerReady;return{...G,...v??!!l?{sceneConfig:{...G.sceneConfig,section:N??u[1].sceneConfig?.section??Se},onSceneConfigChange:oe=>{a(oe.section??Se),(K.onSceneConfigChange??m.onSceneConfigChange)?.(oe)}}:{},...M?{comparisonHighlights:x?M[P]:void 0,selectedObject:P===0?d?.beforeKey?L[d.beforeKey]:null:d?.afterKey?$[d.afterKey]:null}:{},onObjectSelect:oe=>{if((K.onObjectSelect??m.onObjectSelect)?.(oe),n){let Ce=n.objects.find(Z=>(P===0?Z.beforeObjectId:Z.afterObjectId)===oe?.modelObjectId);c(Ce?.id??null)}},onViewerReady:oe=>{D[P](oe,G.modelUrl),we?.(oe)}}}),F=[e.label??k("compareBefore"),t.label??k("compareAfter")];(!z[0].modelUrl||!z[1].modelUrl)&&console.error("[react-immersive] CompareViewer needs a modelUrl, shared or on each side.");let ce=Fe(null),Q=n?ie(ut,{showOutlines:x,onShowOutlinesChange:j,report:n,selected:r,onSelect:R=>{c(R.id);let P=R.afterObjectId?1:0,W=_.current[P],K=P===1?R.afterObjectId:R.beforeObjectId,G=K?W?.raw.nodes[K]:null;W&&G&&(I.setLeader(P),W.raw.controls.fitToBox(G,!0),W.invalidate())},onClear:()=>c(null)}):null;if(!E)return ie(ct,{className:"ri-compare",background:lt(m.backgroundColor,m.sceneConfig),poster:m.poster??t.poster??e.poster,onReveal:()=>C(!0)});if(i==="side-by-side")return Ke("div",{className:"ri-compare ri-compare--sideBySide",children:[z.map((R,P)=>Ke("div",{className:"ri-compare__pane",children:[ie(he,{...R}),ie("span",{className:"ri-compare__label",children:F[P]})]},P)),Q]});let Y=`${q*100}%`;return Ke("div",{ref:ce,className:"ri-compare ri-compare--slider",style:{"--ri-compare-split":Y},children:[ie("div",{className:"ri-compare__layer",children:ie(he,{...z[0]})}),ie("div",{className:"ri-compare__layer ri-compare__layer--after",children:ie(he,{...z[1]})}),Q,ie(ft,{split:q,onSplitChange:X,labels:[F[0],F[1]],containerRef:ce})]})}import{useCallback as Ae,useRef as jt}from"react";import{useCallback as H,useMemo as mt,useState as Sn}from"react";var bt={baseColor:"texture",metalness:"metalnessMap",roughness:"roughnessMap",emissive:"emissiveMap",alpha:"alphaMap",normal:"normalMap",bump:"bumpMap",ao:"aoMap",displacement:"displacementMap",clearcoat:"clearcoatMap",clearcoatRoughness:"clearcoatRoughnessMap",clearcoatNormal:"clearcoatNormalMap",anisotropy:"anisotropyMap",transmission:"transmissionMap",thickness:"thicknessMap",sheenColor:"sheenColorMap",sheenRoughness:"sheenRoughnessMap",specularIntensity:"specularIntensityMap",specularColor:"specularColorMap"};function wt(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,i])=>[t,i&&typeof i=="object"?{...i}:i]))}function On(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t.visible===!1).map(([t])=>[t,!0]))}function Ge(e){let[t,i]=Sn(e),s=H((a,r)=>{i(c=>r===void 0?pe(c,a):pe(c,a,r))},[]),g=H((a,r)=>s(a,He(r)),[s]),y=H((a,r)=>g(a,{baseColor:r}),[g]),l=H((a,r,c="baseColor")=>{let u=bt[c],w=typeof r=="string"?{path:r}:r;s(a,{style:{material:{[u]:w}}})},[s]),A=H((a,r="baseColor")=>{let c=bt[r];s(a,{style:{material:{[c]:void 0}}})},[s]),B=H((a,r)=>{i(c=>{let u=ee(c,a);if(!u)return c;let w=wt(c[u]?.style?.material),L=le(c,r);if(L.length===0)return c;let $=c;for(let n of L){let o=c[n];o&&($===c&&($={...c}),$[n]={...o,style:{...o.style,material:wt(w)}})}return $})},[]),O=H(a=>s(a,{style:{material:void 0}}),[s]),v=H((a,r)=>s(a,{transform:r}),[s]),m=H(a=>s(a,{transform:void 0}),[s]),k=H((a,r)=>s(a,{metadata:r}),[s]),E=H((a,r)=>{i(c=>{let u=c;for(let w of le(c,a)){let L=c[w],$=r(L.decals??[]);u===c&&(u={...c}),u[w]={...L,decals:$.length>0?$:void 0}}return u})},[]),C=H((a,r)=>{let c=r.id??`decal-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;return E(a,u=>[...u.filter(w=>w.id!==c),{...r,id:c}]),c},[E]),h=H((a,r,c)=>E(a,u=>u.map(w=>w.id===r?{...w,...c}:w)),[E]),b=H((a,r)=>E(a,c=>c.filter(u=>u.id!==r)),[E]),f=H(a=>Le(t,a),[t]),S=H(a=>le(t,a).map(r=>t[r]?.id??r),[t]),x=H(a=>{let r=ee(t,a);return r?t[r]?.style?.material??null:null},[t]),j=H(a=>s(a,{visible:!1}),[s]),q=H(a=>s(a,{visible:!0}),[s]),X=H(a=>{i(r=>{let c=le(r,a).reduce((u,w)=>{let L=r[w];return L&&u.push({ids:w,patch:{visible:L.visible===!1}}),u},[]);return pe(r,c)})},[i]),_=H(()=>{i(a=>pe(a,Object.keys(a),{visible:!0}))},[i]),V=mt(()=>On(t),[t]),J=mt(()=>Object.keys(V).map(a=>t[a]?.id??a),[V,t]),N=H(a=>{let r=ee(t,a);return r?t[r]?.visible===!1:!1},[t]);return{objectBindings:t,setObjectBindings:i,updateObjectBindings:s,setMaterial:g,setBaseColor:y,setTexture:l,clearTexture:A,copyMaterial:B,resetMaterial:O,getMaterial:x,setTransform:v,resetTransform:m,updateMetadata:k,addDecal:C,updateDecal:h,removeDecal:b,selectObjectBindings:f,selectObjectBindingIds:S,hiddenObjects:V,hiddenObjectIds:J,hideObject:j,showObject:q,toggleObjectVisibility:X,isObjectHidden:N,clearHiddenObjects:_}}import{useCallback as te,useMemo as jn,useRef as Bn,useState as vn}from"react";function $e(e){let t=Bn(null),[i,s]=vn(()=>{let f=typeof e=="function"?e():e;return t.current=f,f}),g=te(f=>{s(S=>{let x=typeof f=="function"?f(S):f;return _e(S,x)})},[]),y=te(()=>{let f=t.current;f&&s(f)},[]),l=te((f,S)=>{g(x=>({lighting:{lights:x.lighting.lights.map(j=>j.id===f?{...j,...S}:j)}}))},[g]),A=te(f=>{g(S=>S.lighting.lights.some(x=>x.id===f.id)?{}:{lighting:{lights:[...S.lighting.lights,Ne(f)]}})},[g]),B=te(f=>{g(S=>({lighting:{lights:S.lighting.lights.filter(x=>x.id!==f)}}))},[g]),O=te((f,S)=>l(f,{intensity:S}),[l]),v=te((f,S)=>l(f,{color:S}),[l]),m=te(f=>l(f,{visible:!0}),[l]),k=te(f=>l(f,{visible:!1}),[l]),E=te(f=>{g(S=>({lighting:{lights:S.lighting.lights.map(x=>x.id===f?{...x,visible:!x.visible}:x)}}))},[g]),C=te((f,S)=>l(f,{attachment:S,attachedToCamera:!1}),[l]),h=te(f=>l(f,{attachment:void 0}),[l]),b=jn(()=>({items:i.lighting.lights,get:f=>i.lighting.lights.find(S=>S.id===f),add:A,update:l,remove:B,setIntensity:O,setColor:v,show:m,hide:k,toggle:E,attach:C,detach:h}),[i.lighting.lights,A,l,B,O,v,m,k,E,C,h]);return{sceneConfig:i,setSceneConfig:s,updateSceneConfig:g,resetSceneConfig:y,lights:b}}import{useCallback as ze}from"react";function We({bindings:e,scene:t,camera:i,animations:s,isolation:g,onAction:y}){let{objectBindings:l,updateObjectBindings:A,showObject:B,hideObject:O,toggleObjectVisibility:v}=e,m=t?.updateSceneConfig,k=i?.focusObject,E=i?.fitScene,C=i?.resetView,h=i?.setCameraTarget,b=i?.setCameraState,f=s?.play,S=s?.pause,x=s?.stop,j=s?.setSpeed,q=s?.seek,X=g?.handleIsolationChange,_=ze(N=>{let a=ee(l,N);return a?l[a]?.actions??[]:[]},[l]),V=ze(async N=>{for(let a of N.action.effects??[]){if("objectBindings"in a){A(a.target,a.objectBindings);continue}if("sceneConfig"in a){m?.(a.sceneConfig);continue}if("isolation"in a){X?.(a.isolation);continue}if("visibility"in a){a.visibility==="show"?B(a.target):a.visibility==="hide"?O(a.target):v(a.target);continue}if("camera"in a){let c=a.camera;c.type==="focus-object"?await k?.(c.objectId??N.objectId):c.type==="fit-scene"?await E?.():c.type==="reset"?await C?.():c.type==="set-target"?await h?.(c.target,c.transition??!0):await b?.(c.state,c.transition??!0);continue}let r=a.animation;if(r.type==="play"){let{type:c,clip:u,...w}=r;f?.(u,w)}else r.type==="pause"?S?.(r.clip):r.type==="stop"?x?.(r.clip):r.type==="set-speed"?j?.(r.speed,r.clip):q?.(r.time,r.clip)}await y?.(N)},[E,k,O,y,S,f,C,q,j,b,h,X,B,x,v,A,m]),J=ze(async(N,a)=>{let r=ee(l,N);if(!r)return null;let c=l[r],u=c?.actions?.find(L=>L.id===a);if(!c||!u)return null;let w={objectId:r,action:u,binding:c};return await V(w),w},[V,l]);return{getActionsForObject:_,handleAction:V,runAction:J}}import{useCallback as Ve,useRef as yt}from"react";function Mn(e){return typeof e=="function"?e:e?.handleViewerReady??null}function Ye(...e){let t=yt(null),i=yt(e);i.current=e;let s=Ve(B=>{t.current=B;let O=new Set;for(let v of i.current){let m=Mn(v);m&&!O.has(m)&&(O.add(m),m(B))}},[]),g=Ve(()=>t.current,[]),y=Ve(B=>{let O=t.current;return O?O.captureImage(B):Promise.reject(new Error("ModelViewer is not ready yet."))},[]),l=Ve(()=>{let B=t.current;return B?(B.invalidate(),!0):!1},[]),A=Ve(B=>{let O=t.current;return O?O.captureVideo(B):Promise.reject(new Error("ModelViewer is not ready yet."))},[]);return{handleViewerReady:s,getViewer:g,captureImage:y,captureVideo:A,invalidate:l}}import{useCallback as U,useEffect as Rn,useRef as se}from"react";import{Material as xn,PointLight as An,Vector3 as Pn}from"three";var Qe=["emissiveIntensity","opacity","metalness","roughness","transmission","clearcoat","clearcoatRoughness","ior","thickness"],ve=1;function Me(e){return typeof e=="string"?[e]:e}function Re(e,t=0,i=1){return Math.min(i,Math.max(t,e))}function Xe(e,t){return e+Math.random()*(t-e)}function ht([e,t],i){return e+(t-e)*i}function Je([e,t],i){return[e[0]+(t[0]-e[0])*i,e[1]+(t[1]-e[1])*i,e[2]+(t[2]-e[2])*i]}function Vt(e,t){let i=Re(e);switch(t){case"ease-in":return i*i;case"ease-out":return 1-(1-i)*(1-i);case"ease-in-out":return i<.5?2*i*i:1-Math.pow(-2*i+2,2)/2;default:return i}}function En(e){let t=e.material;return t?(Array.isArray(t)?t:[t]).filter(i=>i instanceof xn):[]}function Tn(e){let t={opacity:e.opacity,transparent:e.transparent};e.color&&(t.baseColor=`#${e.color.getHexString()}`),e.emissive&&(t.emissive=`#${e.emissive.getHexString()}`);for(let i of Qe){let s=e[i];typeof s=="number"&&(t[i]=s)}return t}function Ct(e,t){t.baseColor!==void 0&&e.color&&e.color.set(t.baseColor),t.emissive!==void 0&&e.emissive&&e.emissive.set(t.emissive);for(let i of Qe){let s=t[i];s!==void 0&&typeof e[i]=="number"&&(e[i]=s)}t.transparent!==void 0&&(e.transparent=t.transparent),e.needsUpdate=!0}function In(e){return{position:[e.position.x,e.position.y,e.position.z],rotation:[e.rotation.x,e.rotation.y,e.rotation.z],scale:[e.scale.x,e.scale.y,e.scale.z],visible:e.visible}}function Ln(e,t){if(t.position&&e.position.set(...t.position),t.rotation&&e.rotation.set(...t.rotation),t.scale!==void 0){let i=typeof t.scale=="number"?[t.scale,t.scale,t.scale]:t.scale;e.scale.set(...i)}t.visible!==void 0&&(e.visible=t.visible),e.updateMatrix(),e.updateMatrixWorld(!0)}function Ze(e={}){let t=se(e);t.current=e;let i=se(null),s=se(null),g=se(null),y=se(new Map),l=se(new Map),A=se(new Map),B=se(new Map),O=U(n=>{let o=i.current;if(!o)return null;let p=ee(o.objectBindings,n);return o.raw.nodes[n]??(p?o.raw.nodes[p]:null)??(o.raw.scene?ot(o.raw.scene,n):null)??null},[]),v=U(n=>{let o=i.current;return o?typeof n=="object"&&!Array.isArray(n)?le(o.objectBindings,n):Me(n).map(p=>ee(o.objectBindings,p)??p):typeof n=="string"?[n]:Array.isArray(n)?n:[]},[]),m=U(()=>{i.current?.invalidate()},[]),k=U((n,o)=>{let p=!1;for(let d of v(n)){let M=O(d);if(M)for(let I of En(M))A.current.has(I)||A.current.set(I,Tn(I)),Ct(I,o),p=!0}return p},[O,v]),E=U((n,o)=>{let p=k(n,o);return p&&m(),p},[m,k]),C=U((n,o)=>{let p=!1;for(let d of v(n)){let M=O(d);M&&(B.current.has(M)||B.current.set(M,In(M)),Ln(M,o),p=!0)}return p},[O,v]),h=U((n,o)=>{let p=C(n,o);return p&&m(),p},[m,C]),b=U(n=>{let o=O(n);if(!o)return null;o.updateWorldMatrix(!0,!1);let p=o.getWorldPosition(new Pn);return[p.x,p.y,p.z]},[O]),f=U(n=>{let o=l.current.get(n);return o?(o.light.removeFromParent(),o.light.dispose(),l.current.delete(n),m(),!0):!1},[m]),S=U(n=>{let o=O(n.target);if(!o)return!1;let p=l.current.get(n.id),d=p?.light??new An;return p&&p.target!==n.target&&d.removeFromParent(),d.name=`react-immersive-runtime-light:${n.id}`,d.color.set(n.color??"#ffffff"),d.intensity=n.intensity??1,d.distance=n.distance??0,d.decay=n.decay??2,d.castShadow=n.castShadow??!1,d.position.set(...n.offset??[0,0,0]),d.parent!==o&&o.add(d),l.current.set(n.id,{light:d,target:n.target}),m(),!0},[m,O]),x=U((n,o)=>{let p=l.current.get(n);if(!p)return!1;if(o.target&&o.target!==p.target){let d=O(o.target);if(!d)return!1;p.light.removeFromParent(),d.add(p.light),p.target=o.target}return o.color!==void 0&&p.light.color.set(o.color),o.intensity!==void 0&&(p.light.intensity=o.intensity),o.distance!==void 0&&(p.light.distance=o.distance),o.decay!==void 0&&(p.light.decay=o.decay),o.offset!==void 0&&p.light.position.set(...o.offset),o.castShadow!==void 0&&(p.light.castShadow=o.castShadow),m(),!0},[m,O]),j=U((n,o)=>{let p=d=>o[d%o.length]??0;for(let d of n.materials??[])v(d.targets).forEach((M,I)=>{let T=p(I),D={};for(let z of Qe){let F=d.values[z];F&&(D[z]=ht(F,T))}k(M,D)});for(let d of n.transforms??[])v(d.targets).forEach((M,I)=>{let T=p(I),D={};d.values.position&&(D.position=Je(d.values.position,T)),d.values.rotation&&(D.rotation=Je(d.values.rotation,T)),d.values.scale&&(D.scale=Je(d.values.scale,T)),C(M,D)});for(let d of n.lights??[])Me(d.lights).forEach((M,I)=>{let T=l.current.get(M);T&&(T.light.intensity=ht(d.intensity,p(I)))})},[v,k,C]),q=se(()=>{}),X=se(()=>{});X.current=n=>{g.current=null;let o=!1;for(let[p,d]of y.current){d.startedAt===null&&(d.startedAt=n);let M=d.lastFrameAt??n;d.lastFrameAt=n;let I=d.override&&d.override.until>n?d.override.level:null;d.override&&I===null&&(d.override=null);let T=d.update(n,n-d.startedAt,Math.min(100,n-M),I);o=!0,T||(y.current.delete(p),d.onComplete?.())}o&&m(),y.current.size>0&&q.current()},q.current=()=>{g.current!==null||typeof requestAnimationFrame>"u"||(g.current=requestAnimationFrame(n=>X.current(n)))};let _=U(n=>(y.current.set(n.id,n),q.current(),n.id),[]),V=U((n,o={})=>{let p=o.id??`transition-${ve++}`,d=Math.max(1,o.duration??400),M=o.easing??"ease-in-out";return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(I,T,D,z)=>{let F=z??Vt(T/d,M);return j(n,[F]),T<d}})},[j,_]),J=U((n,o={})=>{let p=o.id??`pulse-${ve++}`,d=Math.max(1,o.duration??1e3),M=o.minLevel??0,I=o.maxLevel??1,T=o.repeat??1/0,D=o.synchronized??!0,z=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(F=>v(F.targets).length),...(n.lights??[]).map(F=>Me(F.lights).length));return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(F,ce,ue,Q)=>{let Y=ce/d,R=Array.from({length:D?1:z},(P,W)=>{if(Q!==null)return Q;let K=Y+(D?0:W/z),G=.5-Math.cos(K%1*Math.PI*2)/2;return M+(I-M)*G});return j(n,R),T===1/0||Y<T}})},[j,_,v]),N=U((n,o={})=>{let p=o.id??`timeline-${ve++}`,d=o.repeat??1,M=n.map(T=>({...T,duration:Math.max(1,T.duration),hold:Math.max(0,T.hold??0)})),I=Math.max(1,M.reduce((T,D)=>T+D.duration+D.hold,0));return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(T,D,z,F)=>{if(M.length===0||d<=0)return!1;let ce=D/I;if(d!==1/0&&ce>=d){for(let Y of M)j(Y.channels,[1]);return!1}let ue=D%I,Q=0;for(let Y of M){let R=Q+Y.duration,P=R+Y.hold;if(ue>=R){j(Y.channels,[F??1]),Q=P;continue}if(ue>=Q){let W=F??Vt((ue-Q)/Y.duration,Y.easing??"ease-in-out");j(Y.channels,[W]);break}}return!0}})},[j,_]),a=U((n,o={})=>{let p=o.id??`flicker-${ve++}`,d=o.synchronized??!0,M=o.minLevel??.15,I=o.maxLevel??1,T=o.interval??[45,160],D=typeof T=="number"?[T,T]:T,z=[Math.max(1,Math.min(...D)),Math.max(1,Math.max(...D))],F=Re(o.response??.7,.01,1),ce=Re(o.blackoutChance??.08),ue=Re(o.flashChance??.12),Q=o.flashLevel??1.15,Y=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(G=>v(G.targets).length),...(n.lights??[]).map(G=>Me(G.lights).length)),R=d?1:Y,P=Array.from({length:R},()=>M),W=Array.from({length:R},()=>M),K=Array.from({length:R},()=>0);return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(G,we,oe,Ce)=>{for(let Z=0;Z<R;Z+=1){if(Ce!==null)W[Z]=Ce;else if(G>=K[Z]){let it=Math.random();W[Z]=it<ce?Xe(0,Math.min(.04,M)):it<ce+ue?Q:Xe(M,I),K[Z]=G+Xe(...z)}let xt=1-Math.pow(1-F,Math.max(1,oe)/16.67);P[Z]+=(W[Z]-P[Z])*xt}return j(n,P),o.duration===void 0||we<o.duration}})},[j,_,v]),r=U((n,o,p)=>{let d=y.current.get(n);if(!d)return!1;let M=typeof performance>"u"?Date.now():performance.now();return d.override={level:o,until:M+Math.max(0,p)},q.current(),!0},[]),c=U(n=>y.current.delete(n),[]),u=U(()=>{y.current.clear(),g.current!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(g.current),g.current=null)},[]),w=U(()=>{for(let[n,o]of A.current)Ct(n,o);A.current.clear();for(let[n,o]of B.current)n.position.set(...o.position),n.rotation.set(...o.rotation),n.scale.set(...o.scale),n.visible=o.visible,n.updateMatrix(),n.updateMatrixWorld(!0);B.current.clear();for(let n of l.current.values())n.light.removeFromParent(),n.light.dispose();l.current.clear(),m()},[m]),L=U(()=>{u(),w()},[w,u]),$=U(n=>{s.current&&s.current!==n.raw.scene&&w(),i.current=n,s.current=n.raw.scene,t.current.onViewerReady?.(n)},[w]);return Rn(()=>()=>{L(),i.current=null,s.current=null},[L]),{handleViewerReady:$,setMaterial:E,setTransform:h,getWorldPosition:b,addPointLight:S,updatePointLight:x,removePointLight:f,transition:V,timeline:N,pulse:J,flicker:a,overrideEffect:r,stopEffect:c,stopAllEffects:u,resetRuntime:L}}import{useCallback as kn,useState as Un}from"react";function et(){let[e,t]=Un(null),i=kn(s=>{t(s)},[t]);return{hoveredObjectBinding:e,handleHoveredObject:i}}import{useCallback as St,useState as Dn}from"react";function tt(e=null){let[t,i]=Dn(e),s=St((y,l)=>i({...l,target:y}),[]),g=St(()=>i(null),[]);return{isolation:t,isolate:s,clearIsolation:g,handleIsolationChange:i}}import{useCallback as xe,useState as de}from"react";function nt(){let[e,t]=de(!0),[i,s]=de(!1),[g,y]=de(null),[l,A]=de(null),[B,O]=de(0),[v,m]=de([]),[k,E]=de([]),[C,h]=de([]),b=xe(j=>{A(j.bounds),O(j.objectCount),m(j.materialVariants),E(j.materialVariantGroups),y(null),t(!1),s(!0)},[]),f=xe(j=>h(j),[]),S=xe(j=>{y(j),A(null),O(0),m([]),E([]),h([]),t(!1),s(!1)},[]),x=xe(()=>{t(!0),s(!1),y(null),A(null),O(0),m([]),E([]),h([])},[]);return{isLoading:e,isReady:i,error:g,bounds:l,objectCount:B,materialVariants:v,materialVariantGroups:k,objects:C,handleModelLoaded:b,handleObjectCatalog:f,handleLoadError:S,resetModelState:x}}import{useCallback as Ot,useState as Hn}from"react";function rt(e=null){let[t,i]=Hn(e),s=Ot(y=>{i(y)},[i]),g=Ot(()=>{i(null)},[]);return{selectedObjectBinding:t,setSelectedObjectBinding:i,handleObjectSelect:s,clearSelection:g}}var _n={};function Nn(e={}){let t=jt(e);t.current=e;let i=jt(e.bindings===void 0||e.bindings==="auto"),s=Ge(()=>{let V=t.current.bindings;return V===void 0||V==="auto"?_n:typeof V=="function"?V():V}),g=$e(()=>{let V=t.current.sceneConfig;return V===void 0?Oe:typeof V=="function"?V():V}),y=rt(),l=et(),A=Ee(e.camera),B=nt(),O=qe(),v=tt(),m=Ze(),k=Ye(A,m),E=We({bindings:s,scene:g,camera:A,animations:O,isolation:v,onAction:e.onAction}),{setObjectBindings:C}=s,{handleObjectCatalog:h}=B,b=Ae(V=>{h(V),i.current&&C(J=>{let N=dt(V.map(a=>a.name));for(let a of Object.keys(N))J[a]&&(N[a]=J[a]);return N})},[h,C]),{handleObjectSelect:f}=y,S=Ae(V=>{f(V),t.current.onObjectSelect?.(V)},[f]),{handleHoveredObject:x}=l,j=Ae(V=>{x(V),t.current.onObjectHover?.(V)},[x]),{handleLoadError:q}=B,X=Ae(V=>{q(V),t.current.onLoadError?.(V)},[q]),_=e.sceneConfig!==void 0||g.sceneConfig!==Oe;return{props:{objectBindings:s.objectBindings,onObjectBindingsChange:C,selectedObject:y.selectedObjectBinding,onObjectSelect:S,onObjectHover:j,onCameraChange:A.handleCameraChange,onViewerReady:k.handleViewerReady,onModelLoaded:B.handleModelLoaded,onLoadError:X,onObjectCatalog:b,onAnimationsReady:O.handleAnimationsReady,onAction:E.handleAction,onSceneConfigChange:g.setSceneConfig,isolation:v.isolation,onIsolationChange:v.handleIsolationChange,..._?{sceneConfig:g.sceneConfig}:{}},bindings:s,selection:y,hover:l,camera:A,model:B,animations:O,actions:E,scene:g,isolation:v,effects:m,connection:k}}import{useMemo as qn}from"react";function Fn(e,t){return qn(()=>{if(!t)return null;let i=e[t];return i||(Object.values(e).find(s=>s.id===t||s.modelObjectId===t)??null)},[e,t])}import{useMemo as Kn}from"react";function Gn(e){return Kn(()=>Object.values(e).map(t=>t.modelObjectId),[e])}import{useCallback as ne,useEffect as Pe,useRef as ae,useState as $n}from"react";function zn(e,t){if(!e.objectBindings&&(!!e.hidden?.length||!!e.selected)&&Object.keys(t).length===0)return null;let s={};if(e.objectBindings)s.bindings=e.objectBindings;else if(e.hidden){let g=new Set(e.hidden);s.bindings=Object.fromEntries(Object.entries(t).map(([y,l])=>[y,{...l,visible:!g.has(l.id)}]))}if(e.selected!==void 0){let g=e.objectBindings??t,y=e.selected?ee(g,e.selected):null;s.selected=y?g[y]:null}return s}function Bt(e){return JSON.stringify(e&&{modelUrl:e.modelUrl,activeModelId:e.activeModelId,tilesetUrl:e.tilesetUrl,mergeModels:e.mergeModels,models:e.models?.map(({id:t,url:i,mergeModels:s})=>({id:t,url:i,mergeModels:s}))})}function Wn(e){let t=ae(e);t.current=e;let i=e.paramKey??"view",s=`${i}Id`,[g,y]=$n(!1),l=ae(null),A=ae(null),B=ae(null),O=ae(null),v=ae(null),m=ae(null),k=ae(null),E=ae(null),C=ae(!0),h=ne(r=>{let c=r instanceof Error?r:new Error(String(r));t.current.onError?t.current.onError(c):k.current!==c.message&&console.warn("[react-immersive]",c.message),k.current=c.message},[]),b=ne(()=>{v.current!==null&&clearTimeout(v.current),v.current=null},[]);Pe(()=>(C.current=!0,()=>{C.current=!1,b()}),[b]);let f=ne(()=>{let r=t.current,c=(r.mode??(r.configuration?"configuration":"view"))==="configuration";return{version:1,camera:r.cameraState??void 0,hidden:Object.values(r.objectBindings).filter(u=>u.visible===!1).map(u=>u.id),selected:r.selectedObjectBinding?.id??null,...c?{objectBindings:r.objectBindings,configuration:r.configuration}:{}}},[]),S=ne(()=>ye(f(),typeof window>"u"?void 0:window.location.href),[f]),x=ne(()=>Ie(f(),typeof window>"u"?void 0:window.location.href),[f]),j=ne((r,c,u=window.location.href)=>{let w=new URL(u),L=new URLSearchParams(w.hash.slice(1));if(L.delete(i),L.delete(s),L.set(c?s:i,r),w.hash=L.toString(),!c&&w.href.length>(t.current.maxUrlLength??65536))throw new Error("Viewer configuration is too large for an inline link. Save JSON instead, or configure storage for createShareUrl(). Uploaded images can make links large.");return w.href},[i,s]),q=ne(()=>j(fe(S()),!1),[S,j]),X=ne(async()=>{let r=window.location.href,c=t.current.storage,u=await x();if(!c)return j(fe(u),!1,r);let w=await c.save(u);if(typeof w!="string"||!w.trim()||w.length>2048)throw new Error("Viewer state storage returned an invalid id.");return j(w,!0,r)},[x,j]),_=ne(()=>{if(b(),l.current||m.current)return;let r=q();window.history.replaceState(null,"",r),O.current=`inline:${new URL(r).hash}`},[b,q]),V=ne(async()=>{let r=l.current;if(!r||A.current||!C.current)return!1;A.current=r,b();try{let c=t.current,u=r.state;if(u.configuration&&!r.configurationApplied){if(!c.onConfigurationChange)throw new Error("Restoring a full viewer configuration requires onConfigurationChange.");return r.configurationApplied=!0,c.onConfigurationChange(u.configuration),!1}if(u.configuration&&Bt(c.configuration)!==Bt(u.configuration)||c.isReady===!1)return!1;if(u.camera&&!r.cameraApplied){if(!await c.setCameraState(u.camera,!1)||l.current!==r||!C.current)return!1;r.cameraApplied=!0}c=t.current;let w=zn(u,c.objectBindings);return!w||l.current!==r?!1:(w.bindings&&c.onObjectBindingsChange(w.bindings),w.selected!==void 0&&c.setSelectedObjectBinding(w.selected),l.current=null,B.current=r.key,y(!0),!0)}catch(c){throw l.current===r&&(l.current=null),y(!1),c}finally{A.current=null,l.current&&l.current!==r&&C.current&&V().catch(h)}},[b,h]),J=ne(async r=>{let c=ye(r,window.location.href);b(),E.current=null,m.current=null;let u=new URLSearchParams(window.location.hash.slice(1));return O.current=u.has(i)?`inline:${window.location.hash}`:u.has(s)?`stored:${s}:${u.get(s)}`:null,B.current=null,l.current={key:`manual:${fe(c)}`,origin:"manual",state:c,configurationApplied:!1,cameraApplied:!1},y(!1),V()},[V,b,i,s]),N=ne(async()=>{let r=new URLSearchParams(window.location.hash.slice(1)),c=r.get(i),u=r.get(s),w=c!==null?`inline:${window.location.hash}`:u!==null?`stored:${s}:${u}`:null;if(!w)return E.current=null,m.current=null,l.current?.origin==="manual"?V():(l.current=null,B.current=null,y(!0),!1);if(w===O.current||w===B.current)return l.current?.origin==="manual"?V():!1;if(l.current?.key===w)return V();b(),y(!1),E.current=w,l.current=null;let L=c;if(c===null){let n=t.current.storage;if(!n)throw new Error("This shared link requires a viewer state storage adapter.");(!m.current||m.current.key!==w)&&(m.current={key:w,promise:n.load(u)});let o=m.current;try{L=await o.promise}finally{m.current===o&&(m.current=null)}if(E.current!==w||!C.current)return!1;let p=l.current;if(p?.key===w||B.current===w)return p?V():!1}let $;try{$=ye(L,window.location.href)}catch(n){throw n}return l.current={key:w,origin:"url",state:$,configurationApplied:!1,cameraApplied:!1},V()},[V,b,s,i]);Pe(()=>{l.current&&V().catch(h)}),Pe(()=>{let r=()=>{N().catch(h)};return window.addEventListener("hashchange",r),()=>window.removeEventListener("hashchange",r)},[N,h]);let a=null;if(e.autoSync!==!1&&g&&!l.current&&!m.current)try{a=fe(S())}catch{}return Pe(()=>{if(e.autoSync===!1||!g||l.current||m.current){b();return}if(a===null){try{S()}catch(r){h(r)}return}return v.current=setTimeout(()=>{v.current=null;try{_()}catch(r){h(r)}},Math.max(0,e.debounceMs??400)),b},[a,e.autoSync,e.debounceMs,g,b,S,_,h]),{getState:S,getStateAsync:x,restoreState:J,getShareUrl:q,createShareUrl:X,syncUrl:_,restoreFromUrl:N}}import{useCallback as ge,useState as vt}from"react";var Yn={};function Mt(){return`asset-${globalThis.crypto.randomUUID()}`}function Xn(e){let[t,i]=vt(e),[s,g]=vt(()=>e[0]?re(e[0]):""),y=t.find(C=>re(C)===s)??t[0],l=y?re(y):"",A=ge(C=>{i(h=>h.map(b=>re(b)===l?{...b,objectBindings:C}:b))},[l]),B=ge(C=>{i(h=>h.map(b=>re(b)===l?{...b,sceneConfig:C}:b))},[l]),O=ge(C=>g(h=>{let b=t.find(f=>f.url===C);return b?re(b):h}),[t]),v=ge(C=>{let h={...C,id:C.id??Mt()};return i(b=>{if(b.some(f=>re(f)===h.id))throw new Error("Asset instance ID already exists.");return[...b,h]}),h.id},[]),m=ge(C=>{let h=t.find(j=>re(j)===C);if(!h)return null;let b=structuredClone(h);b.id=Mt(),b.sceneConfig?.measurements&&(b.sceneConfig.measurements.items=b.sceneConfig.measurements.items.map(j=>({...j,modelId:b.id}))),b.label=`${h.label??"Asset"} copy`;let[f,S,x]=h.transform?.position??[0,0,0];return b.transform={...b.transform,position:[f+1,S,x]},i(j=>[...j,b]),b.id},[t]),k=ge(C=>{i(h=>h.filter(b=>re(b)!==C))},[]),E=ge((C,h)=>{let b=Te(h);i(f=>f.map(S=>re(S)===C?{...S,transform:b}:S))},[]);return{modelUrl:y?.url??"",models:t,activeModelId:l,onModelChange:O,onActiveModelChange:g,objectBindings:Yn,onObjectBindingsChange:A,sceneConfig:y?.sceneConfig,onSceneConfigChange:B,addModel:v,duplicateModel:m,removeModel:k,updateModelTransform:E}}import{useCallback as be,useEffect as Jn,useState as Qn,useSyncExternalStore as Zn}from"react";var er={sequenceId:null,time:0,duration:0,status:"stopped",previewing:!1,ready:!1,issues:[]},tr=()=>()=>{},Rt=()=>er;function nr(){let[e,t]=Qn(null),i=Zn(e?.subscribe??tr,e?.getState??Rt,Rt);Jn(()=>()=>e?.stop(),[e]);let s=be(g=>t(g),[]);return{controls:e,playback:i,handleSequencesReady:s,play:be(g=>e?.play(g)??!1,[e]),pause:be(()=>e?.pause(),[e]),stop:be(()=>e?.stop(),[e]),seek:be(g=>e?.seek(g)??!1,[e]),select:be(g=>e?.select(g)??!1,[e])}}export{tn as ACTION_CATALOG,yn as AssetDiagnosticsPanel,pt as CompareViewer,Lt as DEFAULT_MODEL_VIEWER_LABELS,Oe as DEFAULT_SCENE_CONFIG,Se as DEFAULT_SECTION_CONFIG,pn as MATERIAL_BLENDING_MODES,fn as MATERIAL_SIDES,Yt as MAX_VIEWER_STATE_BYTES,_t as MEASUREMENT_UNITS,en as MODEL_VIEWER_PRESETS,he as ModelViewer,Pt as SEQUENCE_EASINGS,At as SEQUENCE_OBJECT_PROPERTIES,cn as applyIsolation,sn as applyStyleRules,un as buildBindingsFromNodes,qt as calibrateMeasurements,rn as chooseMaterialVariant,mn as collectObjectHierarchy,on as colorScaleValue,ke as compareViewerConfigurations,bn as copyBindingStyle,Xt as createARHandoffUrl,dn as createDefaultBinding,gn as defineObjectBindings,Qt as exportConfiguredUSDZ,nn as findCatalogAction,Ht as groundAsset,ln as inferType,Zt as inspectAsset,an as isolatedBindingKeys,He as material,Kt as measurementResult,Nt as measurementScale,Ft as measurementValue,zt as measurementsToCsv,Te as parseAssetTransform,Gt as parseMeasurements,kt as parseSectionConfig,Wt as parseSelectionSets,Et as parseSequences,ye as parseViewerState,wn as pasteBindingStyle,pe as patchBindings,_e as patchSceneConfig,Ie as prepareViewerState,Jt as readARHandoffUrl,Tt as sampleSequenceTrack,Ne as sceneLight,Ut as sectionSnapshot,le as selectBindingKeys,Le as selectBindings,$t as serializeMeasurements,fe as serializeViewerState,Dt as snapAssetToGrid,It as upsertSequenceKeyframe,Fn as useObjectBinding,Gn as useObjectBindingIds,Ge as useObjectBindings,$e as useSceneConfig,Wn as useShareableViewerState,Nn as useViewer,We as useViewerActions,qe as useViewerAnimations,Ee as useViewerCamera,Ye as useViewerConnection,Ze as useViewerEffects,et as useViewerHover,tt as useViewerIsolation,nt as useViewerModel,Xn as useViewerModels,rt as useViewerSelection,nr as useViewerSequences};
@@ -1,3 +1,55 @@
1
+ /** One choice in a row of material variants. */
2
+ type MaterialVariantOption = {
3
+ /** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
4
+ name: string;
5
+ /** The name without its group, for display: "Red" for "Paint: Red". */
6
+ label: string;
7
+ /**
8
+ * The colour of the variant's main material, as a CSS colour, when that
9
+ * material is a plain colour rather than a texture.
10
+ */
11
+ swatch?: string;
12
+ };
13
+ /**
14
+ * Variants that take turns: choosing one replaces the group's other choice.
15
+ * Variants in different groups combine, like a paint colour and a wheel style.
16
+ */
17
+ type MaterialVariantGroup = {
18
+ /** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
19
+ name: string | null;
20
+ variants: MaterialVariantOption[];
21
+ };
22
+ /**
23
+ * The active variants after choosing `name`: it replaces any other variant of
24
+ * its group, so a paint colour swaps for another while the wheels stay.
25
+ */
26
+ declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
27
+
28
+ type ViewerModelBounds = {
29
+ min: [number, number, number];
30
+ max: [number, number, number];
31
+ center: [number, number, number];
32
+ size: [number, number, number];
33
+ };
34
+ /** What `onModelLoaded` reports about a model that finished loading. */
35
+ type ViewerModelInfo = {
36
+ /** Bounds in world space, where the viewer placed the model. */
37
+ bounds: ViewerModelBounds;
38
+ /** Number of meshes in the loaded scene. */
39
+ objectCount: number;
40
+ /**
41
+ * Names of the glTF material variants (KHR_materials_variants) the model
42
+ * offers, in file order; empty when it has none. Show them by setting
43
+ * `sceneConfig.model.activeVariants`.
44
+ */
45
+ materialVariants: string[];
46
+ /**
47
+ * The same variants as option groups, with their display labels and
48
+ * swatches. One variant from each group can show at once.
49
+ */
50
+ materialVariantGroups: MaterialVariantGroup[];
51
+ };
52
+
1
53
  /** Built-in viewer text. Override only the keys your application needs. */
2
54
  declare const DEFAULT_MODEL_VIEWER_LABELS: {
3
55
  readonly verifyingLicense: "Verifying License";
@@ -15,6 +67,27 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
15
67
  readonly dismiss: "Dismiss";
16
68
  readonly missingUVsAreShownInMagenta: "Missing UVs are shown in magenta.";
17
69
  readonly viewThisModelInARWithAppleQuickLook: "View this model in AR with Apple Quick Look";
70
+ readonly sequencePlayer: "Sequence player";
71
+ readonly sequenceSelect: "Sequence";
72
+ readonly sequencePlay: "Play sequence";
73
+ readonly sequencePause: "Pause sequence";
74
+ readonly sequenceStop: "Stop and restore scene";
75
+ readonly sequencePlayhead: "Sequence playhead";
76
+ readonly sequenceTime: "Sequence time";
77
+ readonly sequenceIssues: "Unavailable sequence targets";
78
+ readonly arConfiguredButton: "AR handoff";
79
+ readonly arConfiguredTitle: "Take this configuration to AR";
80
+ readonly arConfiguredDescription: "Your current materials, visible models and placements are included.";
81
+ readonly arSnapshotStale: "Updating AR to include your latest changes…";
82
+ readonly arPreparing: "Preparing your scene…";
83
+ readonly arRefresh: "Refresh AR";
84
+ readonly arRetry: "Try again";
85
+ readonly arExportDetails: "Export details";
86
+ readonly arPrepare: "Prepare AR";
87
+ readonly arPrepareAgain: "Prepare again";
88
+ readonly arDownloadUSDZ: "Download USDZ for iPhone/iPad";
89
+ readonly arScanConfigured: "Scan to open this configuration on your phone.";
90
+ readonly arOpenConfiguredLink: "Open configuration link";
18
91
  readonly viewInAR: "View in AR";
19
92
  readonly openThisExperienceOnAPhoneForAR: "Open this experience on a phone for AR";
20
93
  readonly openOnPhone: "Open on phone";
@@ -57,8 +130,11 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
57
130
  readonly pointLock: "Point Lock";
58
131
  readonly cameraController: "Camera controller";
59
132
  readonly cameraControllerSettings: "Camera controller settings";
60
- readonly downloadGLB: "Download static GLB";
61
- readonly downloadGLBDescription: "All visible models and material edits in one static file. No animations, annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
133
+ readonly downloadGLB: "Download GLB";
134
+ readonly downloadGLBDescription: "All visible models, material edits and animations in one file. No annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
135
+ readonly downloadCombinedGLB: "Download as one GLB";
136
+ readonly downloadSeparateGLBs: "Download separate GLBs";
137
+ readonly downloadSeparateGLBsDescription: "One GLB file per model";
62
138
  readonly downloadPNG: "Download PNG";
63
139
  readonly downloadUVLayout: "Download UV Layout";
64
140
  readonly videoFormat: "Video format";
@@ -94,6 +170,35 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
94
170
  readonly undoMeasurementPoint: "Undo measurement point";
95
171
  readonly clearMeasurements: "Clear measurements";
96
172
  readonly finishArea: "Finish area";
173
+ readonly savedMeasurements: "Saved measurements ({count})";
174
+ readonly noSavedMeasurements: "No saved measurements yet. Pick points in the preview, then save a measurement here.";
175
+ readonly measurementFiles: "Import / export";
176
+ readonly measurementSourceUnit: "Model units";
177
+ readonly measurementDisplayUnit: "Display units";
178
+ readonly measurementName: "Measurement name";
179
+ readonly measurementNamePlaceholder: "e.g. Door width";
180
+ readonly saveMeasurement: "Save measurement";
181
+ readonly knownMeasurementDistance: "Known distance";
182
+ readonly calibrationUnit: "Calibration unit";
183
+ readonly calibrateMeasurement: "Calibrate";
184
+ readonly measurementCalibrationHint: "Pick two distance points, enter their known length, then calibrate.";
185
+ readonly measurementCalibratedScale: "Calibrated: 1 model unit = {scale} m";
186
+ readonly resetMeasurementCalibration: "Reset calibration";
187
+ readonly showSavedMeasurement: "Show {name}";
188
+ readonly renameSavedMeasurement: "Rename {name}";
189
+ readonly deleteSavedMeasurement: "Delete {name}";
190
+ readonly exportMeasurementJson: "Export JSON";
191
+ readonly exportMeasurementCsv: "Export CSV";
192
+ readonly importMeasurementJson: "Import JSON";
193
+ readonly measurementReady: "Ready";
194
+ readonly measurementApproximate: "Approximate LOD";
195
+ readonly measurementModelChanged: "Different model";
196
+ readonly measurementObjectMissing: "Object unavailable";
197
+ readonly measurementGeometryChanged: "Geometry changed — measure again";
198
+ readonly measurementPoseChanged: "Pose changed — measure again";
199
+ readonly measurementObjectHidden: "Object hidden";
200
+ readonly measurementInvalid: "Invalid measurement";
201
+ readonly measurementWaiting: "Waiting for model";
97
202
  readonly openSceneObjectsPanel: "Open scene objects panel";
98
203
  readonly sceneObjects: "SCENE OBJECTS";
99
204
  readonly searchNodesLabels: "Search nodes, labels";
@@ -277,6 +382,19 @@ type ModelViewerLabelKey = keyof typeof DEFAULT_MODEL_VIEWER_LABELS;
277
382
  /** Plain-text overrides; dynamic labels use named {placeholders}. */
278
383
  type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
279
384
 
385
+ /**
386
+ * When a viewer starts its 3D view on its own. `"lazy"` waits until it's on
387
+ * or near the screen and shares the page's live 3D views with the other lazy
388
+ * viewers, so a page of viewers stays within the browser's limit. `"eager"`
389
+ * starts at once and keeps its view.
390
+ */
391
+ type ViewerLoading = "lazy" | "eager";
392
+ /**
393
+ * Whether the 3D view starts on its own (`"auto"`) or waits on the poster
394
+ * until the visitor asks for it with a "View in 3D" button (`"interaction"`).
395
+ */
396
+ type ViewerReveal = "auto" | "interaction";
397
+
280
398
  /**
281
399
  * Whether the viewer cuts motion that starts on its own: `"user"` follows the
282
400
  * visitor's `prefers-reduced-motion` setting, `"always"` and `"never"` override
@@ -284,31 +402,6 @@ type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
284
402
  */
285
403
  type ReducedMotionSetting = "user" | "always" | "never";
286
404
 
287
- /** One choice in a row of material variants. */
288
- type MaterialVariantOption = {
289
- /** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
290
- name: string;
291
- /** The name without its group, for display: "Red" for "Paint: Red". */
292
- label: string;
293
- /**
294
- * The colour of the variant's main material, as a CSS colour, when that
295
- * material is a plain colour rather than a texture.
296
- */
297
- swatch?: string;
298
- };
299
- /**
300
- * Variants that take turns: choosing one replaces the group's other choice.
301
- * Variants in different groups combine, like a paint colour and a wheel style.
302
- */
303
- type MaterialVariantGroup = {
304
- /** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
305
- name: string | null;
306
- variants: MaterialVariantOption[];
307
- };
308
- /**
309
- * The active variants after choosing `name`: it replaces any other variant of
310
- * its group, so a paint colour swaps for another while the wheels stay.
311
- */
312
- declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
405
+ type ModelFormat = "glb" | "gltf" | "obj" | "fbx" | "usdz" | "stl" | "ply";
313
406
 
314
- export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type MaterialVariantOption as a, type ModelViewerLabelKey as b, type ModelViewerLabels as c, chooseMaterialVariant as d };
407
+ export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type ViewerLoading as V, type MaterialVariantOption as a, type ModelFormat as b, type ModelViewerLabelKey as c, type ModelViewerLabels as d, type ViewerModelBounds as e, type ViewerModelInfo as f, type ViewerReveal as g, chooseMaterialVariant as h };
@@ -1,3 +1,55 @@
1
+ /** One choice in a row of material variants. */
2
+ type MaterialVariantOption = {
3
+ /** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
4
+ name: string;
5
+ /** The name without its group, for display: "Red" for "Paint: Red". */
6
+ label: string;
7
+ /**
8
+ * The colour of the variant's main material, as a CSS colour, when that
9
+ * material is a plain colour rather than a texture.
10
+ */
11
+ swatch?: string;
12
+ };
13
+ /**
14
+ * Variants that take turns: choosing one replaces the group's other choice.
15
+ * Variants in different groups combine, like a paint colour and a wheel style.
16
+ */
17
+ type MaterialVariantGroup = {
18
+ /** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
19
+ name: string | null;
20
+ variants: MaterialVariantOption[];
21
+ };
22
+ /**
23
+ * The active variants after choosing `name`: it replaces any other variant of
24
+ * its group, so a paint colour swaps for another while the wheels stay.
25
+ */
26
+ declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
27
+
28
+ type ViewerModelBounds = {
29
+ min: [number, number, number];
30
+ max: [number, number, number];
31
+ center: [number, number, number];
32
+ size: [number, number, number];
33
+ };
34
+ /** What `onModelLoaded` reports about a model that finished loading. */
35
+ type ViewerModelInfo = {
36
+ /** Bounds in world space, where the viewer placed the model. */
37
+ bounds: ViewerModelBounds;
38
+ /** Number of meshes in the loaded scene. */
39
+ objectCount: number;
40
+ /**
41
+ * Names of the glTF material variants (KHR_materials_variants) the model
42
+ * offers, in file order; empty when it has none. Show them by setting
43
+ * `sceneConfig.model.activeVariants`.
44
+ */
45
+ materialVariants: string[];
46
+ /**
47
+ * The same variants as option groups, with their display labels and
48
+ * swatches. One variant from each group can show at once.
49
+ */
50
+ materialVariantGroups: MaterialVariantGroup[];
51
+ };
52
+
1
53
  /** Built-in viewer text. Override only the keys your application needs. */
2
54
  declare const DEFAULT_MODEL_VIEWER_LABELS: {
3
55
  readonly verifyingLicense: "Verifying License";
@@ -15,6 +67,27 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
15
67
  readonly dismiss: "Dismiss";
16
68
  readonly missingUVsAreShownInMagenta: "Missing UVs are shown in magenta.";
17
69
  readonly viewThisModelInARWithAppleQuickLook: "View this model in AR with Apple Quick Look";
70
+ readonly sequencePlayer: "Sequence player";
71
+ readonly sequenceSelect: "Sequence";
72
+ readonly sequencePlay: "Play sequence";
73
+ readonly sequencePause: "Pause sequence";
74
+ readonly sequenceStop: "Stop and restore scene";
75
+ readonly sequencePlayhead: "Sequence playhead";
76
+ readonly sequenceTime: "Sequence time";
77
+ readonly sequenceIssues: "Unavailable sequence targets";
78
+ readonly arConfiguredButton: "AR handoff";
79
+ readonly arConfiguredTitle: "Take this configuration to AR";
80
+ readonly arConfiguredDescription: "Your current materials, visible models and placements are included.";
81
+ readonly arSnapshotStale: "Updating AR to include your latest changes…";
82
+ readonly arPreparing: "Preparing your scene…";
83
+ readonly arRefresh: "Refresh AR";
84
+ readonly arRetry: "Try again";
85
+ readonly arExportDetails: "Export details";
86
+ readonly arPrepare: "Prepare AR";
87
+ readonly arPrepareAgain: "Prepare again";
88
+ readonly arDownloadUSDZ: "Download USDZ for iPhone/iPad";
89
+ readonly arScanConfigured: "Scan to open this configuration on your phone.";
90
+ readonly arOpenConfiguredLink: "Open configuration link";
18
91
  readonly viewInAR: "View in AR";
19
92
  readonly openThisExperienceOnAPhoneForAR: "Open this experience on a phone for AR";
20
93
  readonly openOnPhone: "Open on phone";
@@ -57,8 +130,11 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
57
130
  readonly pointLock: "Point Lock";
58
131
  readonly cameraController: "Camera controller";
59
132
  readonly cameraControllerSettings: "Camera controller settings";
60
- readonly downloadGLB: "Download static GLB";
61
- readonly downloadGLBDescription: "All visible models and material edits in one static file. No animations, annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
133
+ readonly downloadGLB: "Download GLB";
134
+ readonly downloadGLBDescription: "All visible models, material edits and animations in one file. No annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
135
+ readonly downloadCombinedGLB: "Download as one GLB";
136
+ readonly downloadSeparateGLBs: "Download separate GLBs";
137
+ readonly downloadSeparateGLBsDescription: "One GLB file per model";
62
138
  readonly downloadPNG: "Download PNG";
63
139
  readonly downloadUVLayout: "Download UV Layout";
64
140
  readonly videoFormat: "Video format";
@@ -94,6 +170,35 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
94
170
  readonly undoMeasurementPoint: "Undo measurement point";
95
171
  readonly clearMeasurements: "Clear measurements";
96
172
  readonly finishArea: "Finish area";
173
+ readonly savedMeasurements: "Saved measurements ({count})";
174
+ readonly noSavedMeasurements: "No saved measurements yet. Pick points in the preview, then save a measurement here.";
175
+ readonly measurementFiles: "Import / export";
176
+ readonly measurementSourceUnit: "Model units";
177
+ readonly measurementDisplayUnit: "Display units";
178
+ readonly measurementName: "Measurement name";
179
+ readonly measurementNamePlaceholder: "e.g. Door width";
180
+ readonly saveMeasurement: "Save measurement";
181
+ readonly knownMeasurementDistance: "Known distance";
182
+ readonly calibrationUnit: "Calibration unit";
183
+ readonly calibrateMeasurement: "Calibrate";
184
+ readonly measurementCalibrationHint: "Pick two distance points, enter their known length, then calibrate.";
185
+ readonly measurementCalibratedScale: "Calibrated: 1 model unit = {scale} m";
186
+ readonly resetMeasurementCalibration: "Reset calibration";
187
+ readonly showSavedMeasurement: "Show {name}";
188
+ readonly renameSavedMeasurement: "Rename {name}";
189
+ readonly deleteSavedMeasurement: "Delete {name}";
190
+ readonly exportMeasurementJson: "Export JSON";
191
+ readonly exportMeasurementCsv: "Export CSV";
192
+ readonly importMeasurementJson: "Import JSON";
193
+ readonly measurementReady: "Ready";
194
+ readonly measurementApproximate: "Approximate LOD";
195
+ readonly measurementModelChanged: "Different model";
196
+ readonly measurementObjectMissing: "Object unavailable";
197
+ readonly measurementGeometryChanged: "Geometry changed — measure again";
198
+ readonly measurementPoseChanged: "Pose changed — measure again";
199
+ readonly measurementObjectHidden: "Object hidden";
200
+ readonly measurementInvalid: "Invalid measurement";
201
+ readonly measurementWaiting: "Waiting for model";
97
202
  readonly openSceneObjectsPanel: "Open scene objects panel";
98
203
  readonly sceneObjects: "SCENE OBJECTS";
99
204
  readonly searchNodesLabels: "Search nodes, labels";
@@ -277,6 +382,19 @@ type ModelViewerLabelKey = keyof typeof DEFAULT_MODEL_VIEWER_LABELS;
277
382
  /** Plain-text overrides; dynamic labels use named {placeholders}. */
278
383
  type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
279
384
 
385
+ /**
386
+ * When a viewer starts its 3D view on its own. `"lazy"` waits until it's on
387
+ * or near the screen and shares the page's live 3D views with the other lazy
388
+ * viewers, so a page of viewers stays within the browser's limit. `"eager"`
389
+ * starts at once and keeps its view.
390
+ */
391
+ type ViewerLoading = "lazy" | "eager";
392
+ /**
393
+ * Whether the 3D view starts on its own (`"auto"`) or waits on the poster
394
+ * until the visitor asks for it with a "View in 3D" button (`"interaction"`).
395
+ */
396
+ type ViewerReveal = "auto" | "interaction";
397
+
280
398
  /**
281
399
  * Whether the viewer cuts motion that starts on its own: `"user"` follows the
282
400
  * visitor's `prefers-reduced-motion` setting, `"always"` and `"never"` override
@@ -284,31 +402,6 @@ type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
284
402
  */
285
403
  type ReducedMotionSetting = "user" | "always" | "never";
286
404
 
287
- /** One choice in a row of material variants. */
288
- type MaterialVariantOption = {
289
- /** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
290
- name: string;
291
- /** The name without its group, for display: "Red" for "Paint: Red". */
292
- label: string;
293
- /**
294
- * The colour of the variant's main material, as a CSS colour, when that
295
- * material is a plain colour rather than a texture.
296
- */
297
- swatch?: string;
298
- };
299
- /**
300
- * Variants that take turns: choosing one replaces the group's other choice.
301
- * Variants in different groups combine, like a paint colour and a wheel style.
302
- */
303
- type MaterialVariantGroup = {
304
- /** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
305
- name: string | null;
306
- variants: MaterialVariantOption[];
307
- };
308
- /**
309
- * The active variants after choosing `name`: it replaces any other variant of
310
- * its group, so a paint colour swaps for another while the wheels stay.
311
- */
312
- declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
405
+ type ModelFormat = "glb" | "gltf" | "obj" | "fbx" | "usdz" | "stl" | "ply";
313
406
 
314
- export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type MaterialVariantOption as a, type ModelViewerLabelKey as b, type ModelViewerLabels as c, chooseMaterialVariant as d };
407
+ export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type ViewerLoading as V, type MaterialVariantOption as a, type ModelFormat as b, type ModelViewerLabelKey as c, type ModelViewerLabels as d, type ViewerModelBounds as e, type ViewerModelInfo as f, type ViewerReveal as g, chooseMaterialVariant as h };