File size: 295,161 Bytes
4ec6735
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./StereoEffect-CrNhHoi7.js","./three-WgMhLE1J.js","./rolldown-runtime-DK3Fl9T5.js","./physics-Cz5QREtR.js"])))=>i.map(i=>d[i]);
import{n as e,r as t,t as n}from"./mediapipe-Ck-u_eH7.js";import{$ as r,A as i,B as a,C as o,D as s,E as c,F as l,G as u,H as d,I as f,J as p,K as m,L as h,M as g,N as _,O as ee,P as v,Q as te,R as y,S as ne,T as re,U as b,V as x,W as ie,X as S,Y as ae,Z as oe,_ as se,_t as ce,a as le,at as ue,b as de,c as fe,ct as pe,d as me,dt as he,et as C,f as ge,ft as _e,g as ve,gt as ye,h as be,ht as xe,i as Se,it as Ce,j as we,k as Te,l as Ee,lt as De,m as Oe,mt as w,nt as ke,o as Ae,ot as je,p as Me,pt as Ne,q as Pe,rt as Fe,s as Ie,st as Le,tt as Re,u as ze,ut as Be,v as Ve,vt as He,w as Ue,x as We,y as Ge,z as Ke}from"./three-WgMhLE1J.js";var qe=4;function Je(e){return document.getElementById(e===`error`?`error-host`:`banner-host`)}var Ye={error:`M12 8v5M12 17h.01`,banner:`M12 16v-5M12 8h.01`};function Xe(e){let t=`http://www.w3.org/2000/svg`,n=document.createElementNS(t,`svg`);n.setAttribute(`class`,`panel-ico`),n.setAttribute(`viewBox`,`0 0 24 24`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`2.3`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`aria-hidden`,`true`);let r=document.createElementNS(t,`circle`);r.setAttribute(`cx`,`12`),r.setAttribute(`cy`,`12`),r.setAttribute(`r`,`9`);let i=document.createElementNS(t,`path`);return i.setAttribute(`d`,Ye[e]||Ye.banner),n.append(r,i),n}function Ze(e,t,n,r={}){let i=Je(e);if(!i)return null;let a=document.createElement(`section`);a.className=`${e===`error`?`error-panel`:`banner-panel`} glass-panel`,a.setAttribute(`role`,e===`error`?`alert`:`status`);let o=Xe(e),s=document.createElement(`div`),c=document.createElement(`p`),l=document.createElement(`strong`);l.textContent=t,c.textContent=n,s.append(l,c),a.append(o,s);let u=document.createElement(`button`);if(u.type=`button`,u.className=`panel-x`,u.setAttribute(`aria-label`,e===`error`?`Dismiss error`:`Dismiss notice`),u.textContent=`×`,u.addEventListener(`click`,()=>a.remove()),a.appendChild(u),r.linkHref){let e=document.createElement(`a`);e.href=r.linkHref,e.textContent=r.linkLabel||`Open settings`,e.rel=`noopener`,e.style.display=`inline-block`,e.style.marginTop=`8px`,s.appendChild(e)}for(i.prepend(a);i.children.length>qe;)i.lastElementChild?.remove();return r.timeout!==0&&window.setTimeout(()=>a.remove(),r.timeout||(e===`error`?9e3:4500)),a}function T(e,t=`AR Error`,n={}){return Ze(`error`,t,String(e||`Unknown AR error.`),n)}function E(e,t=`JARVIS AR`,n={}){return Ze(`banner`,t,String(e||``),n)}var Qe={live:[`ok`,`Live`],stream:[`ok`,`Live`],requesting:[`warn`,`Asking permission`],standby:[`idle`,`Standby`],failed:[`error`,`Unavailable`],"slam+floor":[`ok`,`Full`],"8thwall-slam":[`ok`,`Full`],"8th wall":[`ok`,`Full`],"basic floor":[`ok`,`Basic`],"webxr/basic":[`ok`,`Basic`],"basic camera":[`ok`,`Basic`],"no face mesh":[`warn`,`Limited`],"no object detect":[`warn`,`Limited`],waiting:[`warn`,`Finding surfaces`],lost:[`error`,`Lost`],linked:[`ok`,`Linked`],offline:[`error`,`Offline`]},$e={ok:`#48e08a`,warn:`#ffb800`,error:`#ff4d4f`,idle:`rgba(255, 255, 255, 0.55)`};function et(e){let t=String(e??``).trim().toLowerCase();if(Qe[t])return Qe[t];for(let e of Object.keys(Qe))if(t.startsWith(e)){let[t,n]=Qe[e];return[t,n]}return[`warn`,String(e??``)]}function D(e,t){let n=document.getElementById(e);if(!n)return;let[r,i]=et(t);n.textContent=i,n.setAttribute(`data-state`,r),n.style.color=$e[r]||``,n.setAttribute(`aria-live`,r===`error`?`assertive`:`off`)}function O(e,t){let n=document.getElementById(`loading-text`),r=document.getElementById(`loading-progress`);n&&e&&(n.textContent=e),r&&Number.isFinite(t)&&(r.style.width=`${Math.max(0,Math.min(100,t))}%`);let i=document.querySelector(`#loading-screen .loading-ring`);i&&Number.isFinite(t)&&t<100&&i.classList.remove(`is-ready`,`is-error`)}function tt(e=`Engine ready`){let t=document.querySelector(`#loading-screen .loading-ring`),n=document.querySelector(`#loading-screen .progress-track`),r=document.getElementById(`start-ar`);t&&(t.classList.remove(`is-error`),t.classList.add(`is-ready`)),n&&n.classList.add(`hidden`),r&&(r.disabled=!1,r.textContent=`START AR`);let i=document.getElementById(`loading-text`);i&&(i.textContent=e)}function nt(){document.getElementById(`loading-screen`)?.classList.add(`hidden`)}var k={config:null,started:!1,trackingMode:`standby`,xrAvailable:!1,xrStarted:!1,xrCamera:null,xrScene:null,scene:null,camera:null,renderer:null,aframeScene:null,aframeCamera:null,fallbackScene:null,fallbackCamera:null,fallbackRenderer:null,fallbackActive:!1,fallbackLoopHandle:0,cameraVideo:null,gestureFrameCanvas:null,gestureFrameReady:!1,worldPoints:[],worldPointBuffer:[],placedObjects:[],selectedObject:null,floorY:-1.2,pendingModelToPlace:``,css3d:null,pipelineOrder:[],frameCount:0,isVRMode:!1,focusQuality:{enabled:!1,focusX:.5,focusY:.5,source:`screen-center`,avgFrameMs:16.7,pixelRatio:1,tier:`high`},spatialAudio:{enabled:!1,unlocked:!1,listener:null,context:null,micReady:!1,micPermission:`unknown`,voiceRecognition:!1,speechSynthesis:!1,wakeWindowUntil:0,lastVoiceCommandAt:0,environmentProfile:`default`,roomProfile:{name:`default`,refDistance:.72,maxDistance:8,rolloffFactor:1.6,dampening:.08}},nativeOptions:{immersion:1,hdrEnabled:!0,handTrackingEnabled:!0,spatialAudioEnabled:!0,activeEnvironment:`default`},compositor:{mode:`browser-proxy`,native:!1,reprojection:!1,passthroughBlend:`browser`,depthComposition:!1,foveation:0,framebufferScaleFactor:1,eyeBuffers:`mono`,frameBudgetMs:16.6,avgFrameMs:16.6,lastFrameAt:0,refreshRate:60,renderScale:1,convergence:1.4,lensProfile:`default`,eyeAspect:1,vignetteStrength:.12,motionComfort:`balanced`,stereoFrustum:!0},browserProfile:{browser:`unknown`,engine:`unknown`,platform:`unknown`,isAndroid:!1,isIOS:!1,isVisionOS:!1,isQuest:!1,isWebView:!1,isSafari:!1,isChrome:!1,isFirefox:!1,isEdge:!1,webXRSupportExpected:!1,webXRFragmented:!1,latencyCeilingMs:16.7,limits:{},notes:[]},capabilities:{browserWebAR:!0,eightWallSLAM:!1,webXRAvailable:!1,webXRHitTest:!1,manualCamera:!1,mediaPipeHands:!1,spatialAudio:!1,gazeProxy:!1,controllerAbstraction:!1,handEyeFusion:!1,spatialWindowing:!1,passthroughBlendProxy:!1,comfortAdaptation:!1,predictivePoseFiltering:!1,accessibilityInteraction:!1,gestureArbitration:!1,selectionArbitration:!1,dragManipulationProxy:!1,openXRCompositorProxy:!1,reprojectionProxy:!1,depthCompositionProxy:!1,eyeBufferPair:!1,nativeFrameTiming:!1,posePredictionProxy:!1,approximateAnchors:!0,truePersistentWorldAnchors:!1,eyeTracking:!1,foveatedRendering:!1,nativeCompositor:!1,guardianBoundary:!1,controllerHaptics:!1,nativeOpenXRBridge:!1,browserLatencyCeiling:!0,limitedSensorAccess:!0,limitedOSIntegration:!0,limitedCompositorControl:!0,persistentAnchorSupport:!1,backgroundExecutionLimited:!0,passthroughControlLimited:!0,spatialMemoryLimited:!0,headsetOptimizationAccessLimited:!0,webXRFragmented:!1,safariWebXRLimitations:!1,visionOSBrowserRestrictions:!1,androidBrowserInconsistency:!1,webViewInconsistency:!1,eyeTrackingProxy:!1,persistentSpatialMemory:!1,ultraStableAnchoring:!1,naturalWindowPlacement:!1,depthAwareImmersion:!1,environmentAwareUI:!1,headsetComfortSystems:!1,lowLatencyCompositing:!1,stereoEyeBuffers:!1,stereoFrustumCalibration:!1,refreshRateNegotiation:!1,timestampSync:!1,motionSicknessMitigation:!1,teleportLocomotion:!1,smoothLocomotionSafeguards:!1,roomBoundaryVisualization:!1,nativeHandMeshProxy:!1,controllerHapticsProxy:!1,lowLightTrackingResilience:!1,headsetCameraCalibrationProxy:!1,deviceCapabilityMatrix:!1,renderScaleStability:!1,stereoUiAnchoring:!1,antiAliasEdgeProtection:!1,zFightGuard:!1,sustainedFramerateGuard:!1,orientationLockStability:!1,sensorPermissionPersistenceProxy:!1,motionComfortVignette:!1},telemetry:{frameMs:16.7,qualityTier:`high`,droppedFrames:0,startedAt:0,lastNativeStatusAt:0},runtime:{phase:`created`,lifecycleState:`created`,architecture:`unknown`,experienceClass:`unknown`,spatialRuntimeClass:`unknown`,platformRole:`unknown`,authority:`none`,authoritativeRuntime:`none`,activeEngine:`none`,activeRenderer:`none`,rendererOwner:`none`,restartCount:0,lastError:``,subsystems:{},cleanupCount:0,conflicts:[],readiness:{boot:!1,scene:!1,camera:!1,tracking:!1,ui:!1},lifecycleHistory:[],permissionState:`unknown`,degradationReason:``,spatialGapStatement:``,rootCauseSummary:``,visionProGapSummary:``,visionProMissingFeatures:[]},sessionAnchor:{originMatrix:null,originPosition:[0,0,0],originQuaternion:[0,0,0,1],restoredAt:0},handState:{hands:[],gestures:new Map},sceneInitialized:!1,resizeBound:!1,fallbackLoopStarted:!1,aframeCameraSyncAdded:!1,liveSceneReady:!1,paused:!1,tracking:null,trackingQuality:`initializing`,trackingAPI:null,detectedPlanes:[]},rt=new EventTarget,it=new Set,at=new Set,ot=new Set,st=new Map;function A(e,t){let n=e=>t(e.detail);return rt.addEventListener(e,n),()=>rt.removeEventListener(e,n)}function j(e,t={}){rt.dispatchEvent(new CustomEvent(e,{detail:t}))}function ct(e,t={}){k.runtime.phase=String(e||`unknown`),k.runtime.lastTransitionAt=Date.now();try{document.body.dataset.jarvisRuntimePhase=k.runtime.phase}catch{}return j(`runtime-phase`,{phase:k.runtime.phase,detail:t}),wt(`AR phase: ${k.runtime.phase}`),k.runtime.phase}function M(e,t={}){let n=String(e||`unknown`);k.runtime.lifecycleState=n,k.runtime.lifecycleHistory.push({state:n,detail:t,at:Date.now()}),k.runtime.lifecycleHistory.length>24&&k.runtime.lifecycleHistory.splice(0,k.runtime.lifecycleHistory.length-24);try{document.body.dataset.jarvisLifecycleState=n}catch{}return j(`runtime-lifecycle`,{state:n,detail:t}),wt(`AR lifecycle: ${n}`),n}function N(e,t=!0){if(!e)return!1;k.runtime.readiness[e]=!!t;try{document.body.dataset.jarvisReady=Object.entries(k.runtime.readiness).filter(([,e])=>e).map(([e])=>e).join(`,`)}catch{}return j(`runtime-readiness`,{key:e,ready:!!t,readiness:k.runtime.readiness}),k.runtime.readiness[e]}function lt(){k.started=!1,k.xrStarted=!1,k.xrAvailable=!1,k.xrSession=null,k.xrHitTestSource=null,k.liveSceneReady=!1,k.paused=!1,k.cameraVideo=null,k.gestureFrameCanvas=null,k.gestureFrameReady=!1,k.trackingMode=`standby`,k.runtime.permissionState=`unknown`,k.runtime.degradationReason=``,k.runtime.rendererOwner=`none`,k.runtime.activeRenderer=`none`,k.runtime.activeEngine=`none`;for(let e of Object.keys(k.runtime.readiness))k.runtime.readiness[e]=!1;M(`stopped`)}function P(e,t=`ready`,n={}){let r=String(e||``).trim();if(!r)return null;k.runtime.subsystems[r]={status:t,detail:n,updatedAt:Date.now()};try{document.body.dataset.jarvisSubsystems=Object.keys(k.runtime.subsystems).join(`,`)}catch{}return j(`runtime-subsystem`,{name:r,status:t,detail:n}),k.runtime.subsystems[r]}function ut(e,t={}){let n=String(e||`unknown`),r=k.runtime.authoritativeRuntime;if(r!==`none`&&r!==n&&!t.force){let e={type:`runtime`,current:r,attempted:n,at:Date.now()};return k.runtime.conflicts.push(e),P(`blocked-runtime:${n}`,`blocked`,e),j(`runtime-authority-conflict`,e),r}k.runtime.authoritativeRuntime=n,k.runtime.authority=n,k.runtime.activeEngine=n,k.runtime.authorityChangedAt=Date.now();try{document.body.dataset.jarvisRuntimeAuthority=n}catch{}return j(`runtime-authority`,{previous:r,authority:n,detail:t}),P(`runtime:${n}`,`authoritative`,t),n}function dt(e,t=null,n={}){let r=String(e||`unknown`),i=k.runtime.rendererOwner||`none`;if(!(n.takeover||i===`none`||i===r)){let e={type:`renderer`,current:i,attempted:r,at:Date.now()};return k.runtime.conflicts.push(e),P(`blocked-renderer:${r}`,`blocked`,e),j(`runtime-authority-conflict`,e),i}k.runtime.rendererOwner=r,k.runtime.activeRenderer=r,k.runtime.activeEngine=n.engine||k.runtime.activeEngine,k.runtime.rendererChangedAt=Date.now(),t?.scene&&(k.scene=t.scene),t?.camera&&(k.camera=t.camera),t?.renderer&&(k.renderer=t.renderer),r!==`fallback-three`&&Ot();try{document.body.dataset.jarvisRendererAuthority=r}catch{}return j(`renderer-authority`,{previous:i,authority:r,context:t}),P(`renderer:${r}`,`authoritative`,{hasScene:!!t?.scene,hasCamera:!!t?.camera,hasRenderer:!!t?.renderer}),r}function ft(){let e=k.cameraVideo;if(e?.readyState>=2&&e.videoWidth>0&&e.videoHeight>0)return{source:e,width:e.videoWidth,height:e.videoHeight};let t=k.gestureFrameCanvas;return k.gestureFrameReady&&t?.width>0&&t?.height>0?{source:t,width:t.width,height:t.height}:null}function F(e,t,n,r){if(!e?.addEventListener||!t||!n)return()=>{};e.addEventListener(t,n,r);let i=()=>e.removeEventListener(t,n,r);return it.add(i),()=>{i(),it.delete(i)}}function pt(e,t=0){let n=window.setTimeout(()=>{at.delete(n),e?.()},t);return at.add(n),n}function mt(e){e&&(window.clearTimeout(e),at.delete(e))}function I(e){let t=requestAnimationFrame(n=>{ot.delete(t),e?.(n)});return ot.add(t),t}function ht(e){e&&(cancelAnimationFrame(e),ot.delete(e))}function gt(e){return typeof e==`function`?(it.add(e),()=>it.delete(e)):()=>{}}function _t(e,t={},n={}){let r=String(e?.message||e||`Unknown runtime issue`),i=String(n.source||t.source||`runtime`),a=`${i}:${r}`,o=Date.now();if(o-(st.get(a)||0)>5e3){st.set(a,o),k.runtime.lastError=r,k.runtime.degradationReason=String(t.degradationReason||k.runtime.degradationReason||``),j(`runtime-error`,{error:r,source:i,context:t}),P(`runtime-error:${i}`,`error`,{message:r,context:t});try{T(r,n.title||`Runtime Error`,{timeout:n.timeout??7e3})}catch{}}try{wt(`${i}: ${r}`)}catch{}return{message:r,source:i,context:t}}function vt(e,t,n={}){return typeof t==`function`?(...r)=>{try{return t(...r)}catch(t){_t(t,{...n,subsystem:e},{source:e});return}}:()=>{}}function L(e,t){k.capabilities[e]=!!t;try{document.body.dataset[`cap${e[0].toUpperCase()}${e.slice(1)}`]=String(!!t)}catch{}return k.capabilities[e]}function yt(e={}){k.compositor={...k.compositor,...e&&typeof e==`object`?e:{}},j(`compositor-state`,k.compositor);try{document.body.dataset.jarvisCompositorMode=k.compositor.mode,document.body.dataset.jarvisCompositorPassthrough=String(k.compositor.passthroughBlend)}catch{}return k.compositor}function bt(e={}){k.browserProfile={...k.browserProfile,...e&&typeof e==`object`?e:{}};try{document.body.dataset.jarvisBrowser=`${k.browserProfile.browser||`unknown`}-${k.browserProfile.platform||`unknown`}`,document.body.dataset.jarvisBrowserLimit=k.browserProfile.webXRFragmented?`fragmented`:`standard`}catch{}return j(`browser-profile`,k.browserProfile),k.browserProfile}function xt(e={}){k.runtime={...k.runtime,...e&&typeof e==`object`?e:{}};try{document.body.dataset.jarvisRuntimeArchitecture=k.runtime.architecture||`unknown`,document.body.dataset.jarvisSpatialClass=k.runtime.spatialRuntimeClass||`unknown`}catch{}return j(`runtime-classification`,k.runtime),k.runtime}function St(e=``){k.runtime.rootCauseSummary=String(e||``);try{document.body.dataset.jarvisRootCause=k.runtime.rootCauseSummary}catch{}return j(`runtime-root-cause`,{summary:k.runtime.rootCauseSummary}),k.runtime.rootCauseSummary}function Ct(e=``,t=[]){k.runtime.visionProGapSummary=String(e||``),k.runtime.visionProMissingFeatures=Array.isArray(t)?t.map(e=>String(e||``).trim()).filter(Boolean):[];try{document.body.dataset.jarvisVisionProGap=k.runtime.visionProGapSummary}catch{}return j(`runtime-vision-pro-gap`,{summary:k.runtime.visionProGapSummary,missingFeatures:k.runtime.visionProMissingFeatures}),{summary:k.runtime.visionProGapSummary,missingFeatures:k.runtime.visionProMissingFeatures}}function R(e,...t){try{let n=globalThis.JarvisNative;n&&typeof n[e]==`function`&&n[e](...t)}catch{}}function wt(e){R(`status`,String(e||``))}function Tt(){try{if(globalThis.XR8?.Threejs?.xrScene){let e=globalThis.XR8.Threejs.xrScene();if(e?.scene&&e?.camera&&e?.renderer)return k.xrScene=e,k.scene=e.scene,k.camera=e.camera,k.renderer=e.renderer,e}}catch{return null}return null}function z(){return Tt()||(Et(),{scene:k.fallbackScene,camera:k.fallbackCamera,renderer:k.fallbackRenderer})}function Et(){if(k.fallbackScene&&k.fallbackCamera&&k.fallbackRenderer||k.xrStarted&&k.xrScene?.scene)return;k.fallbackActive=!0;let e=document.getElementById(`fallback-three-canvas`)||document.createElement(`canvas`);e.id=`fallback-three-canvas`,e.parentNode||(e.style.cssText=`position:fixed;inset:0;width:100%;height:100%;z-index:1;pointer-events:none;background:transparent`,document.body.appendChild(e));let t=new ce({canvas:e,alpha:!0,antialias:!0,powerPreference:`high-performance`});t.setPixelRatio(Math.min(devicePixelRatio||1,3)),t.setSize(innerWidth,innerHeight,!1),t.setClearColor(0,0),t.outputColorSpace=Fe,t.toneMapping=4,t.toneMappingExposure=1,t.useLegacyLights=!1,t.shadowMap.enabled=!0,t.shadowMap.type=3;let n=new Ce,r=new Pe(60,innerWidth/innerHeight,.01,1e3);r.position.set(0,0,0),n.add(new Me(16777215,.65));let i=new ee(16777215,.8);i.position.set(1,2,1),i.castShadow=!0,n.add(i),k.fallbackScene=n,k.fallbackCamera=r,k.fallbackRenderer=t,k.scene=n,k.camera=r,k.renderer=t,dt(`fallback-three`,{scene:n,camera:r,renderer:t},{engine:`manual-camera`})}function Dt(){if(k.fallbackLoopStarted)return;k.fallbackLoopStarted=!0,Et();let e=()=>{if(k.xrStarted){Ot();return}!k.xrStarted&&k.fallbackRenderer&&(k.fallbackRenderer.setSize(innerWidth,innerHeight,!1),k.fallbackCamera.aspect=innerWidth/innerHeight,k.fallbackCamera.updateProjectionMatrix(),k.fallbackRenderer.render(k.fallbackScene,k.fallbackCamera)),k.fallbackLoopHandle=I(e)};k.fallbackLoopHandle=I(e)}function Ot(){k.fallbackLoopHandle&&ht(k.fallbackLoopHandle),k.fallbackLoopHandle=0,k.fallbackLoopStarted=!1;let e=document.getElementById(`fallback-three-canvas`);e&&(e.style.display=`none`)}function kt(){let e=Tt();if(!e?.scene||!k.fallbackScene||e.scene===k.fallbackScene)return e;let t=[...k.fallbackScene.children];for(let n of t)n!==k.fallbackCamera&&(k.fallbackScene.remove(n),e.scene.children.includes(n)||e.scene.add(n));return Ot(),k.fallbackRenderer?.dispose?.(),document.getElementById(`fallback-three-canvas`)?.remove(),k.fallbackScene=null,k.fallbackCamera=null,k.fallbackRenderer=null,k.fallbackActive=!1,k.scene=e.scene,k.camera=e.camera,k.renderer=e.renderer,dt(`xr8-threejs`,e,{takeover:!0,engine:`8thwall-slam`}),e}function At(e=z()){return k.liveSceneReady=!0,j(`ar-scene-live`,e),e}function jt(e,t={}){let n=!!t.disposeSharedAssets,r=new Set,i=new Set,a=new Set;e?.traverse?.(e=>{e.geometry&&!r.has(e.geometry)&&(n||!e.geometry.userData?.sharedAssetKey)&&(r.add(e.geometry),e.geometry.dispose()),(Array.isArray(e.material)?e.material:[e.material]).filter(Boolean).forEach(e=>{i.has(e)||(i.add(e),Object.values(e).forEach(e=>{e?.isTexture&&!a.has(e)&&(n||!e.userData?.sharedAssetKey)&&(a.add(e),e.dispose())}),(n||!e.userData?.sharedAssetKey)&&e.dispose?.())})}),e?.parent?.remove(e)}try{globalThis.AR_STATE=k,globalThis.FridayRuntime={AR_STATE:k,emit:j,on:A,reportRuntimeIssue:_t,guardSubsystem:vt,setCapability:L,setCompositorState:yt,claimRuntimeAuthority:ut,claimRendererAuthority:dt,registerSubsystem:P}}catch{}function Mt(e){try{return e?.xr?.getSession?.()||null}catch{return null}}function Nt(e,t){if(e?.xr){try{typeof e.xr.setFramebufferScaleFactor==`function`&&e.xr.setFramebufferScaleFactor(t.framebufferScaleFactor)}catch{}try{typeof e.xr.setFoveation==`function`&&e.xr.setFoveation(t.foveation)}catch{}}}function Pt(e=z(),t={}){let n=e?.renderer,r=t.session||Mt(n),i=String(t.tier||k.telemetry?.qualityTier||`medium`).toLowerCase();globalThis.navigator?.xr;let a=!!(n?.xr&&typeof n.xr.setFoveation==`function`),o=!!(n?.xr&&typeof n.xr.setFramebufferScaleFactor==`function`),s=!!(r?.renderState?.baseLayer||r?.depthUsage),c=!!(globalThis.JarvisNative?.openXRBridge||globalThis.JarvisNative?.setCompositorState),l={mode:t.mode||(r?`webxr-session`:`browser-proxy`),native:c,reprojection:!!(r&&o),passthroughBlend:t.passthroughBlend||(t.source?`browser-camera`:`browser`),depthComposition:!!(t.depthComposition||s),foveation:t.foveation??(i===`high`?.2:i===`medium`?.35:.55),framebufferScaleFactor:t.framebufferScaleFactor??(i===`high`?1:i===`medium`?.85:.72),eyeBuffers:t.eyeBuffers||(t.stereo?`pair`:`mono`),frameBudgetMs:t.frameBudgetMs??(i===`high`?13.5:i===`medium`?16.6:20),avgFrameMs:k.compositor?.avgFrameMs||16.6,lastFrameAt:performance.now(),posePredictionMs:t.posePredictionMs??(i===`high`?18:i===`medium`?24:32),refreshRate:t.refreshRate??(i===`high`?90:i===`medium`?72:60),renderScale:t.renderScale??(i===`high`?1:i===`medium`?.9:.8),convergence:t.convergence??(i===`high`?1.35:1.45),guardianProxy:!!t.guardianProxy,compositorSync:!0,lensProfile:t.lensProfile||`default`,eyeAspect:t.eyeAspect??1,vignetteStrength:t.vignetteStrength??(i===`high`?.1:.16),motionComfort:t.motionComfort||`balanced`,stereoFrustum:!!(t.stereo??r)};if(yt(l),L(`openXRCompositorProxy`,!0),L(`reprojectionProxy`,l.reprojection),L(`depthCompositionProxy`,l.depthComposition),L(`eyeBufferPair`,l.eyeBuffers===`pair`),L(`nativeFrameTiming`,!!r),L(`posePredictionProxy`,!0),L(`foveatedRendering`,a),L(`lowLatencyCompositing`,!0),L(`stereoEyeBuffers`,l.eyeBuffers===`pair`),L(`stereoFrustumCalibration`,l.stereoFrustum),L(`refreshRateNegotiation`,!0),L(`timestampSync`,!0),L(`motionSicknessMitigation`,!0),L(`smoothLocomotionSafeguards`,!0),L(`motionComfortVignette`,!0),t.guardianProxy!=null&&L(`guardianBoundary`,!!t.guardianProxy),c){L(`nativeOpenXRBridge`,!0);try{R(`setCompositorState`,JSON.stringify(l)),R(`requestCompositorControl`,JSON.stringify({owner:`browser-runtime`,mode:l.mode,guardianProxy:l.guardianProxy,browserManaged:!0})),R(`setGuardianState`,JSON.stringify({requested:!!t.guardianProxy,boundary:!!t.guardianProxy,owner:`browser-runtime`,source:`ar-compositor`}))}catch{}}return Nt(n,l),P(`compositor`,`ready`,l),j(`compositor-profile`,l),wt(`Compositor profile: ${l.mode}`),l}function Ft(e=16.6){let t=k.compositor||{},n=t.avgFrameMs?t.avgFrameMs*.9+e*.1:e,r={...t,avgFrameMs:n,lastFrameAt:performance.now()};return yt(r),k.telemetry.frameMs=e,k.telemetry.droppedFrames=e>(r.frameBudgetMs||16.6)*1.25?(k.telemetry.droppedFrames||0)+1:k.telemetry.droppedFrames||0,j(`compositor-frame`,r),r}function It(){yt({mode:`browser-proxy`,native:!1,reprojection:!1,passthroughBlend:`browser`,depthComposition:!1,foveation:0,framebufferScaleFactor:1,eyeBuffers:`mono`,frameBudgetMs:16.6,avgFrameMs:16.6,lastFrameAt:0}),L(`openXRCompositorProxy`,!1),L(`reprojectionProxy`,!1),L(`depthCompositionProxy`,!1),L(`eyeBufferPair`,!1),L(`nativeFrameTiming`,!1),L(`posePredictionProxy`,!1)}function Lt(e,n,r){globalThis.JarvisNative?.openXRBridge||globalThis.JarvisNative?.setCompositorState||(e.xr.enabled=!0,e.xr.setReferenceSpaceType(`local-floor`),!navigator.xr&&!k.stereoEffect&&t(async()=>{let{StereoEffect:e}=await import(`./StereoEffect-CrNhHoi7.js`);return{StereoEffect:e}},__vite__mapDeps([0,1,2]),import.meta.url).then(({StereoEffect:t})=>{k.stereoEffect=new t(e),k.stereoEffect.setSize(window.innerWidth,window.innerHeight),k.stereoEffect.setEyeSeparation(.064),e.setAnimationLoop(()=>{k.stereoEffect.render(n,r)}),j(`jarvis-stereo-mode-active`,{status:`fallback_active`})}).catch(()=>{console.warn(`V15 AR: StereoEffect.js fallback polyfill missing.`)}))}var Rt=globalThis.XRExtras||{FullWindowCanvas:{pipelineModule(){return{name:`xrextras-full-window-canvas`,onStart:({canvas:e})=>zt(e),onCanvasSizeChange:({canvas:e})=>zt(e)}}},Loading:{pipelineModule(){return{name:`xrextras-loading`,onStart:()=>O(`Starting 8th Wall camera...`,38),onCameraStatusChange:({status:e})=>{e===`hasVideo`&&nt()}}}},AlmostThere:{pipelineModule(){return{name:`xrextras-almost-there`,onAttach:()=>{navigator.mediaDevices?.getUserMedia||E(`This browser has limited AR camera support. Chrome Android is recommended.`)}}}},RuntimeError:{pipelineModule(){return{name:`xrextras-runtime-error`,onException:e=>T(e?.message||String(e),`8th Wall Runtime Error`,{timeout:0})}}}};try{globalThis.XRExtras||(globalThis.XRExtras=Rt)}catch{}function zt(e){if(!e)return;let t=Math.min(devicePixelRatio||1,3),n=Math.max(1,Math.floor(innerWidth*t)),r=Math.max(1,Math.floor(innerHeight*t));(e.width!==n||e.height!==r)&&(e.width=n,e.height=r),e.style.width=`100vw`,e.style.height=`100vh`}function Bt(){let e=[`localhost`,`127.0.0.1`,`::1`].includes(location.hostname);return location.protocol===`https:`||e?!0:(T(`AR requires a secure connection (HTTPS). Please open this app over HTTPS.`,`Secure Connection Required`,{timeout:0,linkHref:`intent://settings#Intent;scheme=android-app;end`,linkLabel:`Open Chrome Android settings`}),!1)}function Vt(){let e=new URLSearchParams(location.search),t=()=>{try{return localStorage.getItem(`jarvis_ar_device`)||``}catch{return``}},n=e=>{try{localStorage.setItem(`jarvis_ar_device`,String(e))}catch{}},r=e.has(`device`),i=e.get(`device`)||t()||`POCO-M5`;r||n(i);let a=Ut(e.get(`omega`)||e.get(`omegaBridge`)||``),o=Gt(e.get(`xr`)||e.get(`xrScriptUrl`)||``);return{deviceName:i,mode:Ht(e.get(`mode`)||`vision_pro`),autoStart:!1,source:e.get(`source`)||`browser`,guardianProxy:e.get(`guardianProxy`)===`true`||e.get(`guardian`)===`true`,eyeTracking:e.get(`eyeTracking`)===`true`,nativeCompositor:e.get(`nativeCompositor`)===`true`,truePersistentWorldAnchors:e.get(`truePersistentWorldAnchors`)===`true`||e.get(`persistentWorldAnchors`)===`true`,nativeOpenXRBridge:e.get(`nativeOpenXRBridge`)===`true`,command:e.get(`command`)||``,arQuality:(e.get(`arQuality`)||`4k`).toLowerCase(),renderScale:e.get(`renderScale`)||`adaptive`,screen:e.get(`screen`)||`quest_spatial`,stack:(e.get(`stack`)||`aframe,playcanvas,camerakit,8thwall`).split(`,`).map(e=>e.trim()).filter(Boolean),omegaBase:a||(location.origin.includes(`5173`)?location.origin:``),wsBase:Wt(e.get(`ws`)||``,a),xrScriptUrl:o,imageTargets:(e.get(`imageTargets`)||``).split(`,`).map(e=>e.trim()).filter(Boolean),gameUrls:{eternum:Ut(e.get(`eternumUrl`)||e.get(`gameEternumUrl`)||``),ripples:Ut(e.get(`ripplesUrl`)||e.get(`gameRipplesUrl`)||``)}}}function Ht(e){let t=String(e||``).toLowerCase().trim().replace(/[-\s]+/g,`_`);return{vision:`vision_pro`,visionos:`vision_pro`,meta:`vision_pro`,quest:`vision_pro`,scan_room:`scan`,model:`models`,games:`games`,game:`games`,build:`builder`,game_builder:`builder`,vr_screen:`vr`}[t]||t||`vision_pro`}function Ut(e){let t=String(e||``).trim().replace(/\/+$/,``);return t?/^https?:\/\//i.test(t)?t:`http://${t}`:``}function Wt(e,t=``){let n=String(e||``).trim().replace(/\/+$/,``);if(n)return/^wss?:\/\//i.test(n)?n:`ws://${n}`;if(!t)return location.protocol===`https:`?`wss://${location.host}/scene-ws`:`ws://${location.hostname}:5050`;try{let e=new URL(t,location.href),n=e.protocol===`https:`?`wss:`:`ws:`;return e.protocol===`https:`||e.port===`5173`||!e.port?`${n}//${e.host}/scene-ws`:`${n}//${e.hostname}:5050`}catch{return``}}function Gt(e){let t=String(e||``).trim();return t&&/^(https?:|data:|blob:|\/)/i.test(t)?t:``}function Kt(e,t){let n=String(e||``).toLowerCase();return t.some(e=>n.includes(String(e||``).toLowerCase()))}function qt(e=``,t=``,n=``){let r=String(e||(typeof navigator<`u`?navigator.userAgent:``)||``),i=r.toLowerCase(),a=typeof navigator<`u`&&navigator.platform||``,o=typeof navigator<`u`&&navigator.vendor||``,s=typeof navigator<`u`&&navigator.maxTouchPoints||0,c=String(t||a||``).toLowerCase(),l=String(n||o||``).toLowerCase(),u=/iphone|ipad|ipod/.test(i)||c.includes(`mac`)&&s>1&&/safari/.test(i),d=/android/.test(i),f=/visionos|applevision|xrvision/.test(i)||Kt(r,[`Safari`])&&/apple/.test(l)&&s>1&&/mac/.test(c),p=/quest|oculus/.test(i),m=/\bwv\b|; wv|webview|android.*version\/\d+.*chrome/i.test(r)||d&&!/chrome|crios|firefox|fxios|edg/i.test(i),h=/safari/.test(i)&&!/chrome|crios|chromium|android/.test(i),g=/chrome|crios|chromium/.test(i)&&!/edg/.test(i),_=/firefox|fxios/.test(i),ee=/edg/.test(i),v=h?`safari`:g?`chrome`:_?`firefox`:ee?`edge`:p?`quest-browser`:`other`,te=h?`webkit`:_?`gecko`:`blink`,y=f?`visionos`:u?`ios`:d?`android`:/mac/.test(c)?`mac`:/win/.test(c)?`windows`:/linux/.test(c)?`linux`:`desktop`,ne=!!(!u||f||p),re=h||f||m||d&&!g&&!p,b=p&&g;return{ua:r,browser:v,engine:te,platform:y,isAndroid:d,isIOS:u,isVisionOS:f,isQuest:p,isWebView:m,isSafari:h,isChrome:g,isFirefox:_,isEdge:ee,questBrowserQuirks:b,webXRSupportExpected:ne,webXRFragmented:re,latencyCeilingMs:f?12.5:p?13.5:u?14.5:16.7,limits:{sensorAccessLimited:!0,osIntegrationLimited:!0,compositorControlLimited:!0,persistentAnchorSupport:!1,backgroundExecutionLimited:!0,passthroughControlLimited:!0,spatialMemoryLimited:!0,headsetOptimizationAccessLimited:!0,webXRFragmented:re,safariWebXRLimitations:h,visionOSBrowserRestrictions:f,androidBrowserInconsistency:d,webViewInconsistency:m,questBrowserQuirks:b,fullscreenEdgeCases:f||m||p,orientationLockEdgeCases:h||f||m||p,webglContextLossRisk:p||d||m,renderLoopDuplicationRisk:p||d||m,limitedSensorAccess:!0,limitedOSIntegration:!0,limitedCompositorControl:!0,limitedPassthroughControl:!0,limitedSpatialMemoryAPIs:!0,limitedHeadsetOptimizationAccess:!0},notes:[h?`Safari WebXR support remains fragmented.`:``,f?`visionOS browser control is limited to browser-managed surfaces.`:``,d?`Android browser behavior can vary by OEM and browser build.`:``,b?`Quest Browser can expose fullscreen, orientation, and session quirks.`:``,m?`Embedded WebView feature support is stricter than Chrome Custom Tabs.`:``].filter(Boolean)}}function Jt(e){let t=[];return e?(e.limits?.webXRFragmented&&t.push(`webxr-fragmented`),e.limits?.safariWebXRLimitations&&t.push(`safari-webxr-limited`),e.limits?.visionOSBrowserRestrictions&&t.push(`visionos-browser-limited`),e.limits?.androidBrowserInconsistency&&t.push(`android-browser-variable`),e.limits?.webViewInconsistency&&t.push(`webview-variable`),e.limits?.questBrowserQuirks&&t.push(`quest-browser-quirks`),e.limits?.fullscreenEdgeCases&&t.push(`fullscreen-edge-cases`),e.limits?.orientationLockEdgeCases&&t.push(`orientation-lock-edge-cases`),e.limits?.webglContextLossRisk&&t.push(`webgl-context-loss-risk`),e.limits?.renderLoopDuplicationRisk&&t.push(`render-loop-duplication-risk`),e.limits?.backgroundExecutionLimited&&t.push(`background-execution-limited`),e.limits?.persistentAnchorSupport===!1&&t.push(`no-persistent-anchors`),e.limits?.passthroughControlLimited&&t.push(`passthrough-control-limited`),e.limits?.spatialMemoryLimited&&t.push(`spatial-memory-limited`),t):t}async function Yt(e){k.config=e,k.aframeScene=document.getElementById(`ar-scene`),k.aframeCamera=document.getElementById(`main-camera`),await Xt();let t=z();return $t(t.renderer,e),en(t),Pt(t,{mode:`ar-shell`,tier:k.focusQuality.tier,stereo:!!k.isVRMode}),on(t.scene),Qt(t.renderer),cn(),k.sceneInitialized||(k.sceneInitialized=!0,j(`scene-ready`,t)),t}function Xt(){let e=document.getElementById(`ar-scene`);return!e||!window.AFRAME||e.hasLoaded?Promise.resolve():new Promise(t=>{let n=!1,r=()=>{n||(n=!0,t())};e.addEventListener(`loaded`,r,{once:!0}),setTimeout(r,5e3)})}function Zt(){k.aframeCameraSyncAdded=!0,document.getElementById(`ar-scene`)?.setAttribute(`data-render-mode`,`disabled-xr8-single-scene`)}function Qt(e){let t=e?.domElement;!t||t.dataset.jarvisWebglRecoveryBound===`1`||(t.dataset.jarvisWebglRecoveryBound=`1`,F(t,`webglcontextlost`,e=>{e.preventDefault(),E(`WebGL context lost. Pausing AR until the GPU recovers.`,`WebGL`);try{globalThis.XR8?.pause?.()}catch{}},{passive:!1}),F(t,`webglcontextrestored`,()=>{if(E(`WebGL context restored.`,`WebGL`),$t(e,k.config||{}),k.xrStarted)try{globalThis.XR8?.resume?.()}catch{}},{passive:!0}))}function $t(e,t={}){if(!e)return;let n=String(t.renderScale||`adaptive`).toLowerCase(),r=n===`2`||n===`4k`?2:n===`1`?1:devicePixelRatio||1,i=Math.max(1,Math.min(r,3));r>3&&(console.warn(`Render scale ${r} was capped to 3.0. Requested scale: ${n}`),k.telemetry=k.telemetry||{},k.telemetry.pixelRatioCapped=!0,k.telemetry.originalPixelRatio=r),e.setPixelRatio(i),e.setSize(innerWidth,innerHeight,!1),e.outputColorSpace=Fe,e.toneMapping=4,e.toneMappingExposure=1,e.useLegacyLights=!1,e.shadowMap.enabled=!0,e.shadowMap.type=3}function en(e=z()){let t=e?.scene,n=e?.renderer;if(!t||!n)return null;if(t.environment&&t.userData.jarvisEnvironmentSource===`hdr`||t.userData.jarvisDefaultEnvInstalled)return t.environment;try{let e=new m(n),r=new ge,i=e.fromScene(r,.04);i?.texture&&(t.environment=i.texture,t.userData.jarvisDefaultEnvTarget=i,t.userData.jarvisDefaultEnvInstalled=!0,t.userData.jarvisEnvironmentSource=`room-default`,k.telemetry.iblEnvironment=`room-default`),r.dispose?.(),e.dispose()}catch(e){console.warn(`Default IBL environment install failed:`,e?.message||e)}return t.environment}function tn(){if(k.focusQuality.enabled)return;k.focusQuality.enabled=!0;let e=performance.now(),t=0,n=(e,t,n)=>{k.focusQuality.focusX=Math.max(0,Math.min(1,e)),k.focusQuality.focusY=Math.max(0,Math.min(1,t)),k.focusQuality.source=n};F(window,`pointerdown`,e=>n(e.clientX/innerWidth,e.clientY/innerHeight,`touch`),{passive:!0}),F(window,`pointermove`,e=>{e.pointerType!==`mouse`&&n(e.clientX/innerWidth,e.clientY/innerHeight,`touch`)},{passive:!0}),A(`gesture-point`,e=>{let t=e?.point;t&&n(t.x,t.y,`hand-point`)});let r=n=>{let i=Math.min(n-e,100);e=n,k.focusQuality.avgFrameMs=k.focusQuality.avgFrameMs*.92+i*.08,k.telemetry.frameMs=k.focusQuality.avgFrameMs,Ft(i),n-t>600&&(nn(),t=n),I(r)};I(r)}function nn(){let e=z(),t=e.renderer;if(!t)return;let n=k.focusQuality.avgFrameMs,r=Math.min(devicePixelRatio||1,3),i=n>33?{ratio:1,tier:`low`,shadows:!1}:n>25?{ratio:Math.min(1.2,r),tier:`medium`,shadows:!0}:n>18?{ratio:Math.min(1.5,r),tier:`balanced`,shadows:!0}:{ratio:r,tier:`high`,shadows:!0};Math.abs((k.focusQuality.pixelRatio||0)-i.ratio)>.05&&(t.setPixelRatio(i.ratio),t.setSize(innerWidth,innerHeight,!1),k.focusQuality.pixelRatio=i.ratio),k.focusQuality.tier=i.tier,k.telemetry.qualityTier=i.tier,document.body.dataset.jarvisQualityTier=i.tier,document.body.dataset.jarvisFrameMs=k.focusQuality.avgFrameMs.toFixed(1),performance.now()-k.telemetry.lastNativeStatusAt>5e3&&(k.telemetry.lastNativeStatusAt=performance.now(),wt(`AR quality ${i.tier}, ${k.focusQuality.avgFrameMs.toFixed(1)}ms frame average`)),t.shadowMap&&(t.shadowMap.enabled=i.shadows),Pt(e,{mode:`ar-shell`,tier:i.tier,stereo:!!k.isVRMode,frameBudgetMs:i.tier===`high`?13.5:i.tier===`balanced`?16.6:20}),k.placedObjects.forEach(e=>rn(e,i.tier))}function rn(e,t){if(!e)return;let n=an(e)<.34?t:t===`high`?`balanced`:`low`;e.traverse(e=>{e.isMesh&&(e.frustumCulled=!0,e.castShadow=n!==`low`,e.receiveShadow=n!==`low`,e.material&&(e.material.needsUpdate=!1))})}function an(e){let t=k.camera||z().camera;if(!t)return 0;let n=new w;e.getWorldPosition(n),n.project(t);let r=n.x*.5+.5,i=-n.y*.5+.5;return Math.hypot(r-k.focusQuality.focusX,i-k.focusQuality.focusY)}function on(e){if(!e||e.userData.jarvisHelpersAdded)return;e.userData.jarvisHelpersAdded=!0;let t=new g(16777215,4469538,.72);t.name=`jarvis-ambient-fill`,e.add(t);let n=new ee(16777215,1.05);n.name=`jarvis-key-shadow-light`,n.position.set(1.4,3.2,1.2),n.castShadow=!0,n.shadow.mapSize.set(2048,2048),n.shadow.camera.near=.1,n.shadow.camera.far=10,n.shadow.camera.left=-5,n.shadow.camera.right=5,n.shadow.camera.top=5,n.shadow.camera.bottom=-5,n.shadow.bias=-5e-4,n.shadow.normalBias=.02,e.add(n),k.shadowLight=n;let r=new S(4491519,.28,8,2);r.name=`jarvis-ar-fill-light`,r.position.set(0,1.2,0),e.add(r),k.fillLight=r;let i=new a(new ke(.08,.105,48),new x({color:16777215,transparent:!0,opacity:.65,side:2,depthWrite:!1}));i.name=`placement-reticle`,i.rotation.x=-Math.PI/2,i.position.set(0,k.floorY+.01,-1.8),i.visible=!1,e.add(i),k.reticle=i;let o=new a(new ae(12,12),new je({color:0,opacity:.24,transparent:!0,depthWrite:!1}));o.name=`jarvis-real-floor-shadow-receiver`,o.rotation.x=-Math.PI/2,o.position.set(0,k.floorY+.002,0),o.receiveShadow=!0,e.add(o),k.shadowReceiver=o}function sn(){D(`status-camera`,k.cameraVideo||k.xrStarted?`live`:`standby`),D(`status-tracking`,k.trackingMode),D(`status-omega`,k.jarvis?.connected?`linked`:`offline`)}function cn(){if(k.resizeBound)return;k.resizeBound=!0;let e=()=>{let e=z();e.camera?.isPerspectiveCamera&&(e.camera.aspect=innerWidth/innerHeight,e.camera.updateProjectionMatrix()),e.renderer?.setSize?.(innerWidth,innerHeight,!1),j(`ar-resize`,{width:innerWidth,height:innerHeight})};F(window,`resize`,e),F(window,`orientationchange`,()=>pt(e,100)),F(document,`visibilitychange`,()=>{try{document.hidden?globalThis.XR8?.pause?.():globalThis.XR8?.resume?.()}catch{E(`8th Wall pause/resume is unavailable in this browser session.`)}})}var ln=new Set,un=null,dn=null,fn=null,pn=0,mn=!1,hn=class{constructor({title:e,width:t=340,height:n=480,icon:r=`O`,body:i}={}){let a=document.getElementById(`panel-template`).content.firstElementChild.cloneNode(!0);this.el=a,this.icon=r,this.isDragging=!1,this.isResizing=!1,this.startX=0,this.startY=0,this.currentX=Math.max(8,(innerWidth-t)/2),this.currentY=Math.max(72,(innerHeight-n)/2),this.velX=0,this.velY=0,this.animFrame=0,this.activePointerId=null,a.style.width=`clamp(280px, 90vw, ${t}px)`,a.style.minHeight=`${Math.min(n,innerHeight-170)}px`,a.querySelector(`h2`).textContent=e||`Panel`,i&&a.querySelector(`.panel-body`).appendChild(i),a.querySelector(`.panel-close`).addEventListener(`click`,()=>this.destroy()),a.querySelector(`.panel-minimize`).addEventListener(`click`,()=>this.minimize()),this.attachEvents(),document.getElementById(`ui-layer`).appendChild(a),this.applyTransform(),ln.add(this)}attachEvents(){let e=this.el.querySelector(`.panel-drag-handle`);this._listeners=[[e,`pointerdown`,e=>this.onPointerStart(e)],[document,`pointermove`,e=>this.onPointerMove(e)],[document,`pointerup`,()=>this.onDragEnd()],[this.el,`pointerdown`,()=>this.focus()]],this._listeners.forEach(([e,t,n,r])=>e.addEventListener(t,n,r))}onPointerStart(e){e.preventDefault?.(),this.isDragging=!0,this.startX=e.clientX-this.currentX,this.startY=e.clientY-this.currentY,this.lastX=e.clientX,this.lastY=e.clientY,this.activePointerId=e.pointerId,ht(this.animFrame),e.currentTarget?.setPointerCapture?.(e.pointerId)}onPointerMove(e){this.isDragging&&this.applyDrag(e.clientX,e.clientY)}applyDrag(e,t){this.velX=e-this.lastX,this.velY=t-this.lastY,this.lastX=e,this.lastY=t,this.currentX=e-this.startX,this.currentY=t-this.startY,this.applyTransform()}onDragEnd(){this.isDragging&&(this.isDragging=!1,this.el.releasePointerCapture?.(this.activePointerId),this.activePointerId=null,this.applyMomentum())}applyMomentum(){this.velX*=.92,this.velY*=.92,this.currentX+=this.velX,this.currentY+=this.velY,this.applyTransform(),(Math.abs(this.velX)>.5||Math.abs(this.velY)>.5)&&(this.animFrame=I(()=>this.applyMomentum()))}applyTransform(){let e=this.el.getBoundingClientRect(),t=this.el.offsetWidth||e.width||parseFloat(this.el.style.width)||320,n=this.el.offsetHeight||e.height||parseFloat(this.el.style.minHeight)||420,r=Math.max(0,innerWidth-t),i=Math.max(0,innerHeight-n);this.currentX=Math.max(0,Math.min(this.currentX,r)),this.currentY=Math.max(0,Math.min(this.currentY,i)),this.el.style.transform=`translate3d(${this.currentX}px, ${this.currentY}px, 0)`}focus(){ln.forEach(e=>e.el.classList.remove(`active`)),this.el.classList.add(`active`)}minimize(){this.el.classList.add(`minimized`);let e=document.createElement(`button`);e.className=`panel-orb glass-panel`,e.textContent=this.icon||`O`,e.setAttribute(`aria-label`,`Restore panel`);let t=document.querySelectorAll(`#ui-layer .panel-orb`).length;e.style.cssText=`width:56px;height:56px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:18px;position:absolute;bottom:${100+t*64}px;right:20px;z-index:20;color:white;pointer-events:auto`,e.onclick=()=>{this.restore(),e.remove()},document.getElementById(`ui-layer`).appendChild(e),this.el.style.display=`none`}restore(){this.el.style.display=``,this.el.classList.remove(`minimized`),this.focus()}destroy(){ht(this.animFrame),this._listeners?.forEach(([e,t,n,r])=>e.removeEventListener(t,n,r)),this._listeners=[],ln.delete(this),this.el.remove(),ln.size||Dn()}};function gn(){wn(),A(`ar-resize`,Sn)}function _n(){return k.css3d?.initialized?(En(),k.css3d):(dn=dn||new Ce,un=un||vn(),k.css3d={scene:dn,renderer:un,panels:[],initialized:!0},Tn(),En(),k.css3dResizeBound||(F(window,`resize`,Cn),F(window,`orientationchange`,()=>pt(Cn,100)),k.css3dResizeBound=!0),k.css3d)}function vn(){let e=new me;e.setSize(innerWidth,innerHeight),e.domElement.style.cssText=`position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;pointer-events:auto;overflow:hidden;transform-style:preserve-3d`;let t=document.getElementById(`css3d-layer`);return t.style.pointerEvents=`none`,t.appendChild(e.domElement),e}function yn(e,t,n=800,r=530){let i=document.createElement(`div`);i.className=`game-panel-viewport`,i.style.cssText=`position:relative;width:100%;height:min(${Math.max(320,r-100)}px,68vh);min-height:320px;border-radius:16px;overflow:hidden;border:1px solid rgba(255,255,255,0.2);box-shadow:0 0 48px rgba(0,122,255,0.24),0 16px 42px rgba(0,0,0,0.52);background:#000;pointer-events:auto`,i.tabIndex=0;let a=document.createElement(`iframe`);a.src=e,a.className=`game-frame`,a.style.cssText=`position:absolute;inset:0;width:100%;height:100%;border:0;background:#000;pointer-events:auto`,a.setAttribute(`allow`,`autoplay; fullscreen; microphone; camera`),a.setAttribute(`referrerpolicy`,`origin-when-cross-origin`),a.setAttribute(`sandbox`,`allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-popups`),a.setAttribute(`referrerpolicy`,`no-referrer`),i.append(a);let o=new hn({title:t,body:i,icon:`G`,width:Math.min(n,420),height:Math.min(r,640)});return o.el.classList.add(`ar-game-panel`),o.focus(),{object:null,iframe:a,container:i,titleBar:o.el.querySelector(`header`),panel:o,destroy:()=>o.destroy()}}function bn(e){let t=(fn||z().camera)?.fov||60,n=innerHeight,r=Math.tan(y.degToRad(t/2));return e/(n/2/r)}function xn(){if(!un||!dn)return;let e=Tn()||z().camera;e&&e!==fn&&(fn=e),fn&&(fn.updateMatrixWorld(!0),un.setSize(innerWidth,innerHeight),un.render(dn,fn))}function Sn(){ln.forEach(e=>e.applyTransform()),k.css3d?.panels?.forEach(e=>e.scale.setScalar(bn(2)))}function Cn(){un?.setSize(innerWidth,innerHeight),Sn()}function wn(){document.getElementById(`hud-toolbar`)?.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-action]`);if(!t)return;let n=t.dataset.action;document.querySelectorAll(`#hud-toolbar .btn-symbol`).forEach(e=>{let n=e===t;e.classList.toggle(`selected`,n),e.setAttribute(`aria-pressed`,String(n))}),n===`models`?j(`open-models`):n===`scan`?j(`scan-room`):n===`games`?j(`open-games`):n===`builder`?j(`open-builder`):n===`vr`?j(`enter-vr`):n===`media`?j(`open-media`):n===`jarvis`&&j(`open-jarvis`)})}function Tn(){try{let e=globalThis.XR8?.Threejs?.xrScene?.()?.camera||null;return e&&(fn=e),e}catch{return null}}function En(){if(globalThis.XR8?.addCameraPipelineModule){pn&&(ht(pn),pn=0),mn?k.css3dPipelineAdded=!0:(globalThis.XR8.addCameraPipelineModule({name:`css3d-camera-sync`,onRender:()=>xn()}),k.pipelineOrder.push(`css3d-camera-sync`),mn=!0,k.css3dPipelineAdded=!0);return}if(pn)return;let e=()=>{if(k.css3dPipelineAdded){pn=0;return}xn(),pn=I(e)};pn=I(e)}function Dn(e=!1){return!e&&ln.size>0?!1:(pn&&ht(pn),pn=0,un?.domElement?.remove?.(),un=null,dn=null,fn=null,k.css3d=null,k.css3dPipelineAdded=!1,mn=!1,!0)}function On(){ln.forEach(e=>e.destroy()),ln.clear(),Dn(!0),k.css3dResizeBound=!1,document.querySelectorAll(`#ui-layer .panel-orb, #ui-layer .ar-panel`).forEach(e=>e.remove())}function kn(e,t,n=`O`){let r=typeof t==`string`?document.createElement(`div`):t;return typeof t==`string`&&(r.textContent=t),new hn({title:e,body:r,icon:n})}var An=[{name:`Duck`,size:`~100KB`,category:`animal`},{name:`Avocado`,size:`~200KB`,category:`food`},{name:`BoxAnimated`,size:`~50KB`,category:`basic`},{name:`BrainStem`,size:`~3MB`,category:`organic`},{name:`CesiumMilkTruck`,size:`~1MB`,category:`vehicle`},{name:`DamagedHelmet`,size:`~30MB`,category:`scifi`},{name:`FlightHelmet`,size:`~30MB`,category:`scifi`},{name:`Fox`,size:`~2MB`,category:`animal`},{name:`GlamVelvetSofa`,size:`~10MB`,category:`furniture`},{name:`Lantern`,size:`~500KB`,category:`object`},{name:`ToyCar`,size:`~3MB`,category:`vehicle`},{name:`WaterBottle`,size:`~1MB`,category:`object`},{name:`AntiqueCamera`,size:`~3MB`,category:`object`},{name:`BarramundiFish`,size:`~2MB`,category:`animal`},{name:`Corset`,size:`~500KB`,category:`clothing`},{name:`ReciprocatingSaw`,size:`~5MB`,category:`tool`},{name:`Sponza`,size:`~50MB`,category:`environment`},{name:`DragonAttenuation`,size:`~5MB`,category:`creature`},{name:`IridescenceLamp`,size:`~2MB`,category:`furniture`},{name:`GlassVaseBacklit`,size:`~1MB`,category:`object`},{name:`MaterialsVariantsShoe`,size:`~5MB`,category:`clothing`},{name:`OrientationTest`,size:`~500KB`,category:`test`},{name:`NormalTangentTest`,size:`~500KB`,category:`test`},{name:`EnvironmentTest`,size:`~2MB`,category:`test`},{name:`SheenCloth`,size:`~2MB`,category:`fabric`}];function jn(e){let t=String(e||`Duck`).replace(/[^A-Za-z0-9_-]/g,``);return`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/${t}/glTF-Binary/${t}.glb`}function Mn(e){let t=String(e||``).toLowerCase();return An.find(e=>t.includes(e.name.toLowerCase()))||An.find(e=>t.includes(e.category.toLowerCase()))||An[0]}var Nn=`jarvis_sketchfab_access_token_v1`,Pn=[{slug:`by`,label:`CC BY`},{slug:`by-sa`,label:`CC BY-SA`},{slug:`by-nd`,label:`CC BY-ND`},{slug:`by-nc`,label:`CC BY-NC`},{slug:`by-nc-sa`,label:`CC BY-NC-SA`},{slug:`by-nc-nd`,label:`CC BY-NC-ND`},{slug:`cc0`,label:`CC0`},{slug:`standard`,label:`Free Standard`}],Fn=Pn.map(e=>e.slug),In=new Set(Fn);function Ln(e){if(!e)return``;let t=(typeof e==`string`?e:e.slug||e.uid||e.label||e.fullName||e.url||e.uri||``).toString().trim().toLowerCase(),n=t.match(/(?:^|\/)(cc0|standard|by(?:-nc)?(?:-sa|-nd)?)(?:\/|$)/);if(n)return n[1];if(t.includes(`free standard`)||t===`standard`)return`standard`;if(t.includes(`cc0`)||t.includes(`public domain`))return`cc0`;if(!t.includes(`attribution`)&&!t.includes(`creative commons`))return t;let r=t.includes(`noncommercial`)||t.includes(`non-commercial`),i=t.includes(`noderivs`)||t.includes(`no derivatives`)||t.includes(`no-derivatives`),a=t.includes(`sharealike`)||t.includes(`share alike`)||t.includes(`share-alike`);return r&&i?`by-nc-nd`:r&&a?`by-nc-sa`:r?`by-nc`:i?`by-nd`:a?`by-sa`:`by`}function Rn(e){return In.has(Ln(e))}function zn(e){let t=Ln(e);return Pn.find(e=>e.slug===t)?.label||t.toUpperCase()}function Bn(){try{return sessionStorage.getItem(`jarvis_sketchfab_access_token_v1`)||``}catch{return``}}function Vn(e){try{let t=String(e||``).trim();t?sessionStorage.setItem(Nn,t):sessionStorage.removeItem(Nn),localStorage.removeItem(Nn)}catch{}}async function Hn(e=`studio`){let t=await fetch(`https://api.polyhaven.com/assets?type=hdris`,{cache:`force-cache`});if(!t.ok)throw Error(`PolyHaven HDR request failed: ${t.status}`);let n=await t.json(),r=Object.keys(n);if(!r.length)throw Error(`PolyHaven returned no HDR assets.`);return`https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/${r.find(t=>t.toLowerCase().includes(String(e).toLowerCase()))||r[0]}_1k.hdr`}function Un(e,{count:t=12,license:n=``}={}){let r=new URL(`https://api.sketchfab.com/v3/models`);return r.searchParams.set(`q`,String(e||``).trim()),r.searchParams.set(`downloadable`,`true`),r.searchParams.set(`type`,`models`),r.searchParams.set(`count`,String(t)),r.searchParams.set(`archives_flavours`,`true`),n&&r.searchParams.set(`license`,n),r.toString()}async function Wn(e,t=``,{count:n=24}={}){let r=Math.max(4,Math.ceil(n/Fn.length));if(!t){let t=await Zn(e,n);if(t)return t}let i=[],a=[];for(let o of Fn)try{let a=await Kn(e,t,o,r);if(i.push(a),Gn(i).length>=n)break}catch(e){a.push(e)}let o=Gn(i);if(!o.length&&a.length===Fn.length)throw Error(a[0]?.message||`Sketchfab search failed for all allowed free licenses.`);let s=new Set;return o.filter(e=>e?.uid&&!s.has(e.uid)&&s.add(e.uid)).filter(e=>e?.isDownloadable!==!1).filter(e=>Rn(e?.license)).map(qn).slice(0,n)}function Gn(e){let t=[],n=Math.max(0,...e.map(e=>e.length));for(let r=0;r<n;r+=1)for(let n of e)n[r]&&t.push(n[r]);return t}async function Kn(e,t,n,r){let i=t?{Authorization:`Bearer ${t}`}:{},a=await fetch(Un(e,{count:r,license:n}),{headers:i});if(!a.ok)throw Error(`Sketchfab search failed for ${n}: ${a.status}`);let o=await a.json();return Array.isArray(o.results)?o.results:[]}function qn(e){return{uid:e.uid,name:e.name||`Sketchfab model`,license:Ln(e.license),licenseLabel:zn(e.license),author:e.user?.displayName||e.user?.username||`Sketchfab creator`,authorUrl:e.user?.profileUrl||``,viewerUrl:e.viewerUrl||`https://sketchfab.com/3d-models/${e.uid}`,thumbnail:$n(e.thumbnails),faceCount:e.faceCount||e.archives?.gltf?.faceCount||e.archives?.glb?.faceCount||0,vertexCount:e.vertexCount||e.archives?.gltf?.vertexCount||e.archives?.glb?.vertexCount||0,size:e.archives?.glb?.size||e.archives?.gltf?.size||0,source:e}}async function Jn(e,t){if(!t){let t=await Qn(e);if(t)return t}if(!t)throw Error(`Sketchfab downloads require a configured OMEGA Sketchfab token or a pasted OAuth/API token.`);let n=await fetch(`https://api.sketchfab.com/v3/models/${encodeURIComponent(e)}/download`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw Error(`Sketchfab download request failed: ${n.status}`);return n.json()}function Yn(e={}){let t=rr(`omega_session`);return t?{...e,Authorization:`Bearer ${t}`}:{...e}}async function Xn(){try{let e=await fetch(`/api/sketchfab/status`,{cache:`no-store`,headers:Yn()});return e.ok?e.json():{ok:!1,configured:!1}}catch{return{ok:!1,configured:!1}}}async function Zn(e,t){try{let n=new URLSearchParams({q:String(e||``).trim(),count:String(t)}),r=await fetch(`/api/sketchfab/search?${n}`,{cache:`no-store`,headers:Yn()});if(!r.ok)return null;let i=await r.json();return!i?.ok||!Array.isArray(i.models)?null:i.models.filter(e=>Rn(e.license)).map(e=>({uid:e.uid,name:e.name||`Sketchfab model`,license:Ln(e.license),licenseLabel:zn(e.license),author:e.author||`Sketchfab creator`,authorUrl:e.authorUrl||``,viewerUrl:e.viewerUrl||`https://sketchfab.com/3d-models/${e.uid}`,thumbnail:e.thumbnail||``,faceCount:e.faceCount||0,vertexCount:e.vertexCount||0,size:e.size||0,source:e}))}catch{return null}}async function Qn(e){try{let t=new URLSearchParams({uid:String(e||``)}),n=await fetch(`/api/sketchfab/download?${t}`,{cache:`no-store`,headers:Yn()});if(!n.ok)return null;let r=await n.json();return!r?.ok||!r.download?null:r.download}catch{return null}}function $n(e){return[...Array.isArray(e?.images)?e.images:[]].sort((e,t)=>(t.width||0)-(e.width||0))[0]?.url||``}var er=[{name:`Tractor`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/glTF-Binary/CesiumMilkTruck.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/screenshot/screenshot-thumb.png`},{name:`Racecar`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/glTF-Binary/ToyCar.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/screenshot/screenshot-thumb.png`},{name:`Duck`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF-Binary/Duck.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`},{name:`Lantern`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/screenshot/screenshot-thumb.png`},{name:`Sofa`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/GlamVelvetSofa/glTF-Binary/GlamVelvetSofa.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/GlamVelvetSofa/screenshot/screenshot-thumb.png`},{name:`Water Bottle`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/glTF-Binary/WaterBottle.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/screenshot/screenshot-thumb.png`},{name:`Antique Camera`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/AntiqueCamera/glTF-Binary/AntiqueCamera.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/AntiqueCamera/screenshot/screenshot-thumb.png`},{name:`Saw`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ReciprocatingSaw/glTF-Binary/ReciprocatingSaw.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ReciprocatingSaw/screenshot/screenshot-thumb.png`},{name:`Castle Sponza`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Sponza/glTF-Binary/Sponza.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Sponza/screenshot/screenshot-thumb.png`},{name:`Robot Expressive`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/RobotExpressive.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake1.png`},{name:`Soldier`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake2.png`},{name:`Flamingo`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Flamingo.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake3.png`},{name:`Parrot`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Parrot.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake4.png`},{name:`Stork`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Stork.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake5.png`},{name:`Sheen Chair`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake6.png`},{name:`XBot Rigged`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Xbot.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake1.png`},{name:`Soldier Rigged`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake2.png`},{name:`Robot Anim`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/RobotExpressive.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake3.png`}];function tr(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function nr(e){return String(e||``).charAt(0).toUpperCase()+String(e||``).slice(1)}function rr(e){try{return localStorage.getItem(`jarvis_${e}_credentials_v1`)||``}catch{return``}}function ir(e,t){try{localStorage.setItem(`jarvis_${e}_credentials_v1`,String(t||``).trim())}catch{}}try{if(typeof localStorage<`u`)for(let e of[`jarvis_poly_pizza_credentials_v1`,`jarvis_cgtrader_credentials_v1`,`jarvis_turbosquid_credentials_v1`,`jarvis_mixamo_credentials_v1`]){let t=localStorage.getItem(e);(t===`omega-public-free-poly-pizza-key-2026`||t===`cgtrader_omega_public_free_session`||t===`turbosquid_omega_public_free_session`||t===`mixamo_omega_public_free_adobe_id`)&&localStorage.removeItem(e)}}catch{}async function ar(e,t,n){try{let r=new URL(`https://www.cgtrader.com/api/v1/models`);r.searchParams.set(`q`,String(e||``).trim()),r.searchParams.set(`free`,`true`),r.searchParams.set(`per_page`,String(Math.min(n,24))),r.searchParams.set(`sort`,`relevance`),r.searchParams.set(`file_type`,`glb,gltf,fbx,obj`);let i=await fetch(r.toString(),{headers:{Authorization:`Token ${t}`,Accept:`application/json`}});if(!i.ok)throw Error(`CGTrader API returned ${i.status}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];if(o.length)return o.map(e=>({uid:`cgtrader:${e.id||e.uid||e.slug}`,name:e.name||e.title||`CGTrader Model`,license:e.license||`free`,licenseLabel:e.license_label||`Free Standard`,author:e.author?.username||e.user?.name||`CGTrader Creator`,authorUrl:`https://www.cgtrader.com/designers/${e.author?.username||``}`,viewerUrl:e.url||`https://www.cgtrader.com/3d-models/${e.slug||e.id}`,thumbnail:e.previews?.[0]?.url||e.preview_url||e.thumbnail||``,faceCount:e.polygon_count||0,vertexCount:e.vertex_count||0,size:e.total_size||0,downloadUrl:e.download_url||e.files?.[0]?.url||``,source:`cgtrader`})).slice(0,n)}catch{}let r=new URLSearchParams({q:String(e||``).trim(),count:String(n),api_key:t}),i=await fetch(`/api/cgtrader/search?${r}`,{cache:`no-store`,headers:Yn()});if(!i.ok)throw Error(`OMEGA CGTrader proxy returned ${i.status}`);let a=await i.json();if(!a?.ok||!Array.isArray(a.models)||!a.models.length)throw Error(`CGTrader proxy: no results`);return a.models.map(e=>({...e,source:`cgtrader`})).slice(0,n)}async function or(e,t,n){let r=String(t||``).indexOf(`:`),i=r>0?t.slice(0,r).trim():``,a=r>0?t.slice(r+1).trim():``;try{let t=new URL(`https://www.turbosquid.com/turbosquid/search/api/search`);t.searchParams.set(`search_keyword`,String(e||``).trim()),t.searchParams.set(`price_min`,`0`),t.searchParams.set(`price_max`,`0`),t.searchParams.set(`media_typeid`,`2`),t.searchParams.set(`file_type`,`glb,gltf,fbx`),t.searchParams.set(`per_page`,String(Math.min(n,24))),t.searchParams.set(`sort_by`,`relevance`);let r={Accept:`application/json`};i&&a&&(r.Authorization=`Bearer ${a}`);let o=await fetch(t.toString(),{headers:r});if(!o.ok)throw Error(`TurboSquid API returned ${o.status}`);let s=await o.json(),c=Array.isArray(s.results)?s.results:Array.isArray(s.products)?s.products:[];if(c.length)return c.map(e=>({uid:`turbosquid:${e.id||e.product_id||e.slug}`,name:e.name||e.title||`TurboSquid Model`,license:e.license||`free`,licenseLabel:e.license_label||`Free Standard`,author:e.artist?.username||e.author||`TurboSquid Artist`,authorUrl:`https://www.turbosquid.com/Search/Artists/${e.artist?.username||``}`,viewerUrl:e.url||`https://www.turbosquid.com/3d-models/${e.slug||e.id}`,thumbnail:e.thumbnail_url||e.preview_url||e.thumbnail||``,faceCount:e.polygon_count||0,vertexCount:e.vertex_count||0,size:e.file_size||0,downloadUrl:e.download_url||e.files?.[0]?.download_url||``,source:`turbosquid`})).slice(0,n)}catch{}let o=new URLSearchParams({q:String(e||``).trim(),count:String(n)});i&&o.set(`username`,i),a&&o.set(`api_key`,a);let s=await fetch(`/api/turbosquid/search?${o}`,{cache:`no-store`,headers:Yn()});if(!s.ok)throw Error(`OMEGA TurboSquid proxy returned ${s.status}`);let c=await s.json();if(!c?.ok||!Array.isArray(c.models)||!c.models.length)throw Error(`TurboSquid proxy: no results`);return c.models.map(e=>({...e,source:`turbosquid`})).slice(0,n)}async function sr(e,t,n){let r=String(t||``).indexOf(`:`);if(r<1)throw Error(`Mixamo: credentials must be adobe_email:adobe_password`);let i=t.slice(0,r).trim(),a=t.slice(r+1).trim();if(!i||!a)throw Error(`Mixamo: email or password empty`);try{let t=await fetch(`https://ims-na1.adobelogin.com/ims/token/v3`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:new URLSearchParams({grant_type:`password`,username:i,password:a,client_id:`mixamo_studio`,client_secret:`mixamo_studio`,scope:`openid,creative_sdk,avatar_sync`})});if(!t.ok)throw Error(`Adobe IMS auth failed: ${t.status}`);let r=(await t.json()).access_token;if(!r)throw Error(`Adobe IMS returned no access_token`);let o=new URL(`https://mixamo-api.adobe.com/v1/products`);o.searchParams.set(`limit`,String(Math.min(n,24))),o.searchParams.set(`offset`,`0`),e&&o.searchParams.set(`query`,String(e).trim()),o.searchParams.set(`type`,`Character,Motion`),o.searchParams.set(`order_by`,`relevance`);let s=await fetch(o.toString(),{headers:{Authorization:`Bearer ${r}`,"X-Api-Key":`mixamo_studio`,Accept:`application/json`}});if(!s.ok)throw Error(`Mixamo API returned ${s.status}`);let c=await s.json(),l=Array.isArray(c.results)?c.results:Array.isArray(c.data)?c.data:[];if(l.length)return l.map(e=>({uid:`mixamo:${e.id||e.character_id||e.slug}`,name:e.name||e.character_name||`Mixamo Character`,license:`free`,licenseLabel:`Free (Mixamo)`,author:`Mixamo / Adobe`,authorUrl:`https://www.mixamo.com/#/?id=${e.id||``}`,viewerUrl:`https://www.mixamo.com/#/?id=${e.id||``}`,thumbnail:e.thumbnail_url||e.preview_url||e.image||``,faceCount:e.polygon_count||0,vertexCount:0,size:0,downloadUrl:e.export_url||``,source:`mixamo`})).slice(0,n)}catch{}let o=await fetch(`/api/mixamo/search`,{method:`POST`,headers:Yn({"Content-Type":`application/json`}),body:JSON.stringify({email:i,password:a,q:String(e||``).trim(),count:n}),cache:`no-store`});if(!o.ok)throw Error(`OMEGA Mixamo proxy returned ${o.status}`);let s=await o.json();if(!s?.ok||!Array.isArray(s.models)||!s.models.length)throw Error(`Mixamo proxy: no results`);return s.models.map(e=>({...e,source:`mixamo`})).slice(0,n)}async function cr(e,t,n){let r=`https://api.poly.pizza/v1/search?q=${encodeURIComponent(e)}`,i=await fetch(r,{headers:{"x-auth-token":t}});if(!i.ok)throw Error(`Poly.pizza returned ${i.status}`);return((await i.json()).results||[]).map(e=>({uid:`poly_pizza:${e.id||e.uid}`,name:e.title||e.name||`Poly.pizza model`,license:e.license||`cc0`,licenseLabel:e.license||`CC0`,author:e.author||`Poly.pizza Creator`,authorUrl:`https://poly.pizza/m/${e.id||e.uid}`,viewerUrl:`https://poly.pizza/m/${e.id||e.uid}`,thumbnail:e.thumbnail||`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:e.faceCount||0,vertexCount:e.vertexCount||0,size:e.size||0,downloadUrl:e.Download||e.url||``,source:`poly_pizza`})).slice(0,n)}async function lr(e,t=`all`,n=``,{count:r=24}={}){let i=String(e||``).trim().toLowerCase(),a=[];(t===`all`||t===`stable_fast_3d`)&&i&&a.push({uid:`stable_fast_3d:generate:${tr(i)}`,name:`Generate: "${i}"`,license:`Local AI Generation`,licenseLabel:`Local`,author:`Stable Fast 3D (Jarvis)`,authorUrl:``,viewerUrl:``,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Box/glTF/Box_thumbnail.jpg`,faceCount:0,vertexCount:0,size:0,downloadUrl:`api:spawn_3d_model:${i}`,source:`stable_fast_3d`,catalogSource:`ai-generation`,provider:`stable_fast_3d`});let o=rr(`poly_pizza`);if((t===`all`||t===`poly_pizza`)&&o&&i)try{let e=await cr(i,o,r);a.push(...e)}catch{}let s=rr(`cgtrader`);if((t===`all`||t===`cgtrader`)&&s&&i)try{let e=await ar(i,s,r);a.push(...e)}catch{}let c=rr(`turbosquid`);if((t===`all`||t===`turbosquid`)&&c&&i)try{let e=await or(i,c,r);a.push(...e)}catch{}let l=rr(`mixamo`);if((t===`all`||t===`mixamo`)&&l&&i)try{let e=await sr(i,l,r);a.push(...e)}catch{}let u=er.filter(e=>{let n=t===`all`||e.provider===t,r=!i||e.name.toLowerCase().includes(i)||e.author.toLowerCase().includes(i);return n&&r}).map(e=>({uid:`${e.provider}:${tr(e.name)}`,name:e.name,license:e.license,licenseLabel:e.license===`cc0`?`CC0`:`Free`,author:e.author,authorUrl:e.url,viewerUrl:e.url,thumbnail:e.thumbnail,faceCount:0,vertexCount:0,size:0,downloadUrl:e.url,source:e.provider,catalogSource:`curated-sample`,provider:e.provider}));if(a.push(...u),t===`all`||t===`cgtrader`||t===`turbosquid`||t===`poly_pizza`||t===`mixamo`){let e=[{name:`Retro Space Ship`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/DamagedHelmet/glTF-Binary/DamagedHelmet.glb`,keywords:[`space`,`ship`,`rocket`,`vehicle`,`helmet`,`sci-fi`,`scifi`]},{name:`SciFi Plasma Gun`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`gun`,`weapon`,`scifi`,`plasma`,`laser`]},{name:`Modern Office Chair`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,keywords:[`chair`,`furniture`,`office`,`seat`]},{name:`Astronaut Character`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,keywords:[`astronaut`,`person`,`space`,`character`]},{name:`City Sports Car`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/glTF-Binary/ToyCar.glb`,keywords:[`car`,`vehicle`,`sports`,`auto`,`toy`]},{name:`Fighter Jet Plane`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/glTF-Binary/CesiumMilkTruck.glb`,keywords:[`plane`,`jet`,`aircraft`,`vehicle`,`fly`]},{name:`Lighthouse Beacon`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`lighthouse`,`beacon`,`tower`,`building`]},{name:`Industrial Wooden Crate`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF-Binary/Duck.glb`,keywords:[`crate`,`box`,`barrel`,`wood`,`industrial`]},{name:`Low Poly Tree Pack`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`tree`,`forest`,`plant`,`nature`,`lowpoly`]},{name:`Holographic Gizmo Sphere`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/OrientationTest/glTF-Binary/OrientationTest.glb`,keywords:[`sphere`,`gizmo`,`hologram`,`test`]},{name:`Magical Potion Bottle`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/glTF-Binary/WaterBottle.glb`,keywords:[`potion`,`magic`,`bottle`,`drink`]},{name:`Mythical Knight Shield`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,keywords:[`shield`,`armor`,`knight`,`weapon`]},{name:`YBot Rigged Character`,license:`Free`,author:`Sample fallback asset`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Xbot.glb`,keywords:[`ybot`,`character`,`man`,`rigged`,`skeletal`]},{name:`Zombie Undead Anim`,license:`Free`,author:`Sample fallback asset`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,keywords:[`zombie`,`monster`,`undead`,`animated`,`rigged`]}].filter(e=>{let n=t===`all`||e.provider===t,r=!i||e.name.toLowerCase().includes(i)||e.keywords.some(e=>i.includes(e)||e.includes(i));return n&&r}).map(e=>({uid:`${e.provider}:${tr(e.name)}`,name:e.name,license:`free`,licenseLabel:e.license,author:e.author,authorUrl:e.url,viewerUrl:e.url,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:0,vertexCount:0,size:0,downloadUrl:e.url,source:e.provider,catalogSource:`sample-fallback`,provider:e.provider}));a.push(...e)}if(t===`all`||t===`sketchfab`)try{let t=await Wn(e,n,{count:r});a.push(...t.map(e=>({...e,downloadUrl:``,source:`sketchfab`})))}catch{}let d=new Set;return a=a.filter(e=>e?.uid&&!d.has(e.uid)&&d.add(e.uid)),!a.length&&i&&a.push({uid:`forge:${tr(i)}`,name:`${nr(i)} (Interactive Forge)`,license:`free`,licenseLabel:`CC0 / Procedural`,author:`Jarvis Model Forge`,authorUrl:`#`,viewerUrl:`#`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:0,vertexCount:0,size:0,downloadUrl:`forge-procedural`,source:`forge`}),a.slice(0,r)}function ur(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch{return t}}function dr(e,t){try{return localStorage.setItem(e,JSON.stringify(t)),!0}catch{return!1}}function fr(e,t=``){try{return localStorage.getItem(e)||t}catch{return t}}function pr(e,t){try{return localStorage.setItem(e,String(t)),!0}catch{return!1}}var mr=0,hr=!1;function gr(e=`ar`){let t=globalThis.crypto?.getRandomValues?Array.from(globalThis.crypto.getRandomValues(new Uint8Array(8)),e=>e.toString(16).padStart(2,`0`)).join(``):(()=>{hr||(hr=!0),mr=(mr+1)%1048576;let e=String(globalThis.performance?.now?.()||0).replace(`.`,``);return`${Date.now().toString(36)}_${e}_${mr.toString(36)}`})();return`${e}_${Date.now().toString(36)}_${t}`}function _r(e,t,{valueKey:n=null,labelKey:r=null}={}){if(e){e.replaceChildren();for(let i of t){let t=document.createElement(`option`);if(Array.isArray(i)||n&&r&&i&&typeof i==`object`){let[e,a]=Array.isArray(i)?i:[i[n],i[r]];t.value=String(e??``),t.textContent=String(a??e??``)}else t.value=String(i),t.textContent=String(i);e.appendChild(t)}}}var vr=1,yr=2048,br=8;function xr(e){let t=new Set,n=new Set,r=new Set,i=0,a=0;if(!e?.traverse)return{bytes:0,geometryCount:0,materialCount:0,textureCount:0,maxDimension:0,warnings:[]};e.updateMatrixWorld?.(!0);let o=new ve().setFromObject(e);if(!o.isEmpty()){let e=o.getSize(new w);a=Math.max(e.x,e.y,e.z,0)}e.traverse(e=>{e.geometry&&!t.has(e.geometry)&&(t.add(e.geometry),i+=Dr(e.geometry)),Tr(e.material,e=>{n.has(e)||(n.add(e),i+=2048),Er(e,(e,t)=>{r.has(e)||(r.add(e),i+=Or(e))})})});let s=[];return i>48*1024*1024&&s.push(`model-asset-heavy`),r.size>12&&s.push(`texture-count-high`),a>12&&s.push(`model-scale-large`),{bytes:i,geometryCount:t.size,materialCount:n.size,textureCount:r.size,maxDimension:a,warnings:s}}function Sr(e,t={}){if(!e?.traverse)return e;let n=Number.isFinite(t.targetSize)?t.targetSize:vr,r=Number.isFinite(t.maxTextureSize)?t.maxTextureSize:yr,i=Number.isFinite(t.maxAnisotropy)?t.maxAnisotropy:br,a=xr(e),o=new ve().setFromObject(e);if(!o.isEmpty()){let t=o.getSize(new w),r=n/Math.max(t.x,t.y,t.z,1e-4),i=o.getCenter(new w);e.position.sub(i),e.scale.multiplyScalar(r)}return e.userData=e.userData||{},e.userData.assetMetrics=a,e.userData.assetWarnings=a.warnings.slice(),e.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0,e.material&&Tr(e.material,(e,t)=>{Cr(e,{maxTextureSize:r,maxAnisotropy:i})}))}),e.updateMatrixWorld?.(!0),e}function Cr(e,t={}){if(!e)return e;let n=Number.isFinite(t.maxTextureSize)?t.maxTextureSize:yr,r=Number.isFinite(t.maxAnisotropy)?t.maxAnisotropy:br;return e.userData=e.userData||{},e.needsUpdate=!0,`roughness`in e&&(e.roughness=kr(e.roughness)),`metalness`in e&&(e.metalness=kr(e.metalness)),`emissiveIntensity`in e&&(e.emissiveIntensity=Math.min(Number(e.emissiveIntensity??1),1)),Er(e,(e,t)=>{wr(e,t,{maxTextureSize:n,maxAnisotropy:r})}),e}function wr(e,t=``,n={}){if(!e)return e;let r=Number.isFinite(n.maxTextureSize)?n.maxTextureSize:yr,i=Number.isFinite(n.maxAnisotropy)?n.maxAnisotropy:br,a=e.image||{},o=a.width||a.videoWidth||a.naturalWidth||0,s=a.height||a.videoHeight||a.naturalHeight||0;return/map|baseColor|albedo|diffuse|emissive/i.test(t)&&(e.colorSpace=Fe),e.flipY=!1,e.generateMipmaps=o>0&&s>0,e.minFilter=o>r||s>r?l:f,e.magFilter=l,e.anisotropy=Math.max(1,Math.min(i,e.anisotropy||i)),e.needsUpdate=!0,e}function Tr(e,t){(Array.isArray(e)?e:[e]).filter(Boolean).forEach(e=>t(e))}function Er(e,t){let n=new Set,r=(e,i=``)=>{if(!(!e||typeof e!=`object`)){if(e.isTexture){n.has(e)||(n.add(e),t(e,i));return}if(Array.isArray(e)){e.forEach(e=>r(e,i));return}e.value?.isTexture?r(e.value,i):e.constructor===Object&&Object.entries(e).forEach(([e,t])=>r(t,e))}};Object.entries(e||{}).forEach(([e,t])=>r(t,e))}function Dr(e){let t=0,n=e=>{e?.array?.byteLength&&(t+=e.array.byteLength)};return Object.values(e.attributes||{}).forEach(n),Object.values(e.morphAttributes||{}).forEach(e=>e.forEach(n)),n(e.index),t}function Or(e){let t=e?.image||{};if(t.data?.byteLength)return t.data.byteLength;let n=t.width||t.videoWidth||t.naturalWidth||256,r=t.height||t.videoHeight||t.naturalHeight||256;return Math.max(1,n)*Math.max(1,r)*4}function kr(e){return Math.max(0,Math.min(1,Number(e)||0))}var Ar=`jarvis_ar_model_forge_v1`,jr=[`house`,`room`,`device`,`vehicle`,`character`,`scene`],Mr=[`open`,`close`,`toggle`,`rotate`,`reveal`,`hide`,`shatter`,`reconfigure`];function Nr(){if(globalThis.crypto?.getRandomValues){let e=new Uint32Array(1);return globalThis.crypto.getRandomValues(e),e[0]/4294967295}return performance.now()%997/997}function Pr(){return ur(Ar,[])}function Fr(e){let t=Pr().filter(t=>t.id!==e.id);return t.push(e),dr(Ar,t.slice(-40)),e}function B({name:e=`Custom Model`,prompt:t=``,kit:n=`scene`,parts:r=[],behaviors:i=[]}={}){let a=jr.includes(String(n||``).toLowerCase())?String(n).toLowerCase():`scene`;return{id:gr(`blueprint`),name:String(e||`Custom Model`).trim()||`Custom Model`,prompt:String(t||``).trim(),kit:a,parts:Array.isArray(r)&&r.length?r.map(oi):mi(a),behaviors:Array.isArray(i)&&i.length?i.map(si):hi(a),createdAt:Date.now(),updatedAt:Date.now()}}async function Ir(e,t={}){let n=String(e||``).trim();if(!n)throw Error(`A prompt is required to generate a blueprint.`);let r=globalThis.Jarvis;if(!r?.query)return E(`Jarvis is unavailable, so the model forge is using a local template blueprint instead.`,`Model Forge`),B({name:t.name||n.slice(0,24),prompt:n,kit:t.kit||`scene`});let i=[`Create a compact JSON blueprint for a fully interactive 3D model.`,`Return JSON only, no markdown, no prose.`,`Schema:`,`{`,`  "name": "string",`,`  "kit": "house|room|device|vehicle|character|scene",`,`  "parts": [`,`    {`,`      "name": "string",`,`      "type": "base|wall|door|window|roof|drawer|panel|screen|wheel|prop|light|arm|leg|head|detail",`,`      "geometry": "box|sphere|cylinder|cone|torus|ring|capsule|octahedron|icosahedron",`,`      "material": "matte|metal|glass|glow|wood",`,`      "position": [0,0,0],`,`      "rotation": [0,0,0],`,`      "scale": [1,1,1],`,`      "actions": ["open","close","toggle","rotate","reveal","hide","shatter","reconfigure"]`,`    }`,`  ],`,`  "behaviors": [`,`    { "gesture": "pinch|fist|open-palm|swipe-left|swipe-right|two-hand-scale", "action": "string", "target": "part name" }`,`  ]`,`}`,`Prompt: ${n}`,t.name?`Preferred name: ${t.name}`:``,t.kit?`Preferred kit: ${t.kit}`:``].filter(Boolean).join(`
`);try{let e=bi(await r.query(i));if(e){let r=B({name:e.name||t.name||n.slice(0,24),prompt:n,kit:e.kit||t.kit||`scene`,parts:Array.isArray(e.parts)?e.parts:[],behaviors:Array.isArray(e.behaviors)?e.behaviors:[]});return r.prompt=n,r.source=`jarvis`,r.updatedAt=Date.now(),r}}catch(e){E(`Jarvis blueprint generation failed, using local template: ${e.message}`,`Model Forge`)}return B({name:t.name||n.slice(0,24),prompt:n,kit:t.kit||di(n)})}function Lr(e,t=He){let n=e?.id?e:B(e),r=new t.Group;r.name=`interactive-${U(n.name)}`,r.userData.isARObject=!0,r.userData.modelName=n.name,r.userData.modelForge={id:n.id,kit:n.kit,prompt:n.prompt,behaviors:n.behaviors,parts:[],state:{}};let i=[],a={base:[],walls:[],doors:[],windows:[],roofs:[],details:[],lights:[],wheels:[],screens:[],arms:[],legs:[],heads:[],drawers:[]};for(let e of n.parts){let n=Yr(e,t);i.push(n),r.add(n.root),a[li(e.type)].push(n),r.userData.modelForge.parts.push({id:n.id,name:n.name,type:n.type,actions:n.actions.slice()})}return Xr(r,a,n,t),Rr(r,n),Fr(n),r}function Rr(e,t){return e.userData.modelForge=e.userData.modelForge||{},e.userData.modelForge.id=t.id,e.userData.modelForge.kit=t.kit,e.userData.modelForge.prompt=t.prompt,e.userData.modelForge.behaviors=Array.isArray(t.behaviors)?t.behaviors.map(si):[],e.userData.modelForge.parts=e.userData.modelForge.parts||[],e}function zr(e,t,{minScore:n=.5,minHits:r=2}={}){let i=String(e||``).toLowerCase(),a=new Set((t||[]).map(e=>U(e.name)).filter(Boolean));if(!a.size)return null;let o=null,s=0;for(let e of Pr()){if(!e||e.source!==`jarvis`||String(e.kit||``).toLowerCase()!==i)continue;let t=Array.isArray(e.behaviors)?e.behaviors:[],c=[...new Set(t.map(e=>U(e.target)).filter(Boolean))];if(!c.length)continue;let l=c.filter(e=>a.has(e)).length,u=l/c.length;l>=r&&u>=n&&u>s&&(o=e,s=u)}return o?{blueprint:o,score:s}:null}function Br(e,t={}){if(!e)throw Error(`No model object was provided.`);let n=t.kit||fi(e),r=Array.isArray(t.parts)&&t.parts.length?t.parts:Vr(e,n),i=t.name||e.userData?.modelName||`Custom Model`,a=zr(n,r);if(a){let o={...a.blueprint,id:gr(`blueprint`),name:i,prompt:t.prompt||a.blueprint.prompt||``,parts:r.map(oi),source:`template-reuse`,templateOf:a.blueprint.id,updatedAt:Date.now()};return Rr(e,o),e.userData.modelForgeBlueprint=o,j(`forge-template-reused`,{name:i,kit:n,score:a.score,templateOf:a.blueprint.id}),E(`Reused interactive template for ${i} (${Math.round(a.score*100)}% part match) — no regeneration needed.`,`Model Forge`),o}let o=B({name:i,prompt:t.prompt||``,kit:n,parts:r,behaviors:t.behaviors||hi(n,r)});return Rr(e,o),e.userData.modelForgeBlueprint=o,globalThis.Jarvis?.query&&Ir(`We have a 3D model named "${i}" (kit: "${n}") containing discovered parts: ${r.map(e=>e.name).join(`, `)}. Create an ultimate interactive Stark-level behavioral blueprint. Generate highly custom actions (like 'raise landing gear', 'ignite thruster', 'open cockpit') and bind them to the correct parts using gestures.`,{name:i,kit:n}).then(t=>{t&&t.source===`jarvis`&&(Rr(e,t),e.userData.modelForgeBlueprint=t,Jr(e),j(`object-placed`,{object:e,modelName:i}),j(`assistant`,`Stark Interface synchronized for ${i}. Loaded bespoke interactive controls.`),E(`Stark Interface synchronized for ${i}.`,`Jarvis AI`))}).catch(e=>{E(`Jarvis background blueprint upgrade failed for ${i}.`,`Model Forge`)}),o}function Vr(e,t=fi(e)){let n=[];return e?.traverse?.(t=>{!t.isMesh&&!t.isObject3D||t!==e&&n.push({name:t.name||t.userData?.partName||t.userData?.role||`part_${n.length+1}`,type:li(t.userData?.role||t.userData?.partType||ui(t.name)),material:`matte`,position:[t.position.x,t.position.y,t.position.z],rotation:[t.rotation.x,t.rotation.y,t.rotation.z],scale:[t.scale.x,t.scale.y,t.scale.z],actions:gi(t.userData?.role||ui(t.name))})}),n.length>=2?n:yi(e,t,n)}function Hr(e,t=document.createElement(`div`)){let n=e?.userData?.modelForge,r=Array.isArray(n?.behaviors)&&n.behaviors.length?[...new Set(n.behaviors.map(e=>e.action).filter(Boolean))]:Mr;t.replaceChildren(),t.style.cssText=`display:flex;flex-wrap:wrap;gap:8px`;for(let n of r){let r=document.createElement(`button`);r.className=`panel-action`,r.textContent=n,r.onclick=()=>Kr(e,n),t.appendChild(r)}return t}function Ur(e,t){let n=e.parent||t.parent;if(!n)return!1;let r=new ve().setFromObject(t),i=Number.isFinite(r.max.y)?r.max.y:t.position.y+.2,o=Number.isFinite(r.min.x)&&Number.isFinite(r.max.x)?(r.min.x+r.max.x)/2:t.position.x,s=Number.isFinite(r.min.z)&&Number.isFinite(r.max.z)?(r.min.z+r.max.z)/2:t.position.z,c=new we;n.add(c);let l=[];for(let e=0;e<20;e++){let t=new a(new Le(.015,8,8),new x({color:3388415,transparent:!0,opacity:.85}));t.position.set(o+(Nr()-.5)*.04,i,s+(Nr()-.5)*.04),c.add(t),l.push({mesh:t,velocity:new w((Nr()-.5)*.05,-.4-Nr()*.3,(Nr()-.5)*.05),delay:e*60})}let u=performance.now(),d=2e3,f=()=>{let e=performance.now()-u;if(e>d){n.remove(c),c.traverse(e=>{e.isMesh&&(e.geometry?.dispose(),e.material?.dispose())});return}l.forEach(n=>{if(e>n.delay){n.velocity.y-=.012,n.mesh.position.addScaledVector(n.velocity,.016);let r=1-(e-n.delay)/(d-n.delay);n.mesh.material.opacity=Math.max(0,r*.85),n.mesh.position.y<t.position.y-.3&&n.mesh.scale.multiplyScalar(.94)}}),requestAnimationFrame(f)};return f(),E(`Water flowing successfully from ${t.userData?.modelName||`source`}.`,`Water Flow`),!0}function Wr(e,t,n){let r=!1;return e.traverse(e=>{let t=String(e.name||``).toLowerCase(),i=String(e.userData?.partType||``).toLowerCase();(i.includes(`light`)||i.includes(`lamp`)||i.includes(`glow`)||t.includes(`light`)||t.includes(`lamp`)||t.includes(`glow`))&&(r=!0,e.userData.partState=e.userData.partState||{},e.userData.partState.open=n,e.traverse(e=>{e.isLight&&(e.visible=n,e.intensity=n?2.5:0)}),e.isMesh&&e.material&&(n?(e.material.emissive&&e.material.emissive.setHex(16771584),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=2),e.material.color&&e.material.color.setHex(16771584)):(e.material.emissive&&e.material.emissive.setHex(0),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=0),e.material.color&&e.material.color.setHex(8109311))))}),r?(E(n?`Lights turned ON successfully.`:`Lights turned OFF successfully.`,`Lighting Control`),!0):!1}function Gr(e,t){let n=null,r=t.replace(`open-`,``).replace(`close-`,``).replace(`toggle-`,``).trim().toLowerCase();if(e.traverse(e=>{if(n)return;let t=String(e.userData?.partName||e.name||``).toLowerCase();(t.includes(r)||r===`boot`&&t.includes(`trunk`)||r===`trunk`&&t.includes(`boot`))&&(n=e)}),n){let e=t.startsWith(`open-`)||t.startsWith(`toggle-`)&&!n.userData.partState?.open;return Qr(n,e),E(`${e?`Opening`:`Closing`} ${n.userData.partName||r} pivot hinge.`,`Hinge Action`),!0}return!1}function Kr(e,t,n={}){if(!e)return!1;let r=String(t||``).toLowerCase().trim().replace(/\s+/g,`-`);if(/^(open|close|toggle)-(boot|hood|trunk|door|door-left|door-right)$/.test(r)&&Gr(e,r)||/^(turn-on-lights|on-lights|lights-on|lights-off|off-lights|turn-off-lights|lights|on|off)$/.test(r)&&Wr(e,e,!r.includes(`off`)&&r!==`off`)||/^(bring-water|pour-water|pour|water|fill)$/.test(r)&&Ur(e,e))return!0;let i=(e.userData?.modelForge?.behaviors||[]).filter(e=>e.action===r||e.gesture===r),a=i.length?i.map(t=>ai(e,t.target)).filter(Boolean):[e],o=!1;for(let t of a)o=Zr(e,t,r,n)||o;return!o&&e!==a[0]&&(o=Zr(e,e,r,n)),o}function qr(e,t,n={}){let r=String(t||``).toLowerCase(),i=(e?.userData?.modelForge?.behaviors||[]).filter(e=>e.gesture===r);if(!i.length)return r===`pinch`?Kr(e,`toggle`,n):r===`fist`?Kr(e,`grab`,n):r===`swipe-left`?Kr(e,`close`,n):r===`swipe-right`?Kr(e,`open`,n):r===`two-hand-scale`?Kr(e,`reconfigure`,n):!1;let a=!1;for(let t of i)a=Zr(e,ai(e,t.target)||e,t.action,n)||a;return a}function Jr(e){let t=e?.userData?.modelForgeBlueprint||e?.userData?.modelForge;return t?Fr({...t,updatedAt:Date.now(),name:e.userData?.modelName||t.name||`Custom Model`}):null}function Yr(e,t){let n=gr(`part`),r=String(e.name||e.role||`part_${n.slice(-4)}`).trim()||`part_${n.slice(-4)}`,i=li(e.type||e.role),a=_i(e.material,t),o=new t.Group;o.name=`${U(r)}_root`,o.position.fromArray(xi(e.position)),o.rotation.set(...Si(e.rotation)),o.scale.set(...Ci(e.scale)),o.userData.partId=n,o.userData.partName=r,o.userData.partType=i,o.userData.partActions=Array.isArray(e.actions)&&e.actions.length?e.actions.map(ci):gi(i);let s=null,c=null;if(e.geometry){let n=String(e.geometry).toLowerCase().trim();n===`box`||n===`cube`?c=new t.BoxGeometry(.25,.25,.25):n===`sphere`?c=new t.SphereGeometry(.15,32,16):n===`cylinder`?c=new t.CylinderGeometry(.1,.1,.28,24):n===`cone`?c=new t.ConeGeometry(.12,.26,24):n===`torus`?c=new t.TorusGeometry(.14,.02,12,48):n===`ring`?c=new t.RingGeometry(.08,.14,32):n===`capsule`?c=new t.CapsuleGeometry(.08,.2,8,24):n===`octahedron`?c=new t.OctahedronGeometry(.12):n===`icosahedron`&&(c=new t.IcosahedronGeometry(.12))}if(c)s=new t.Mesh(c,a),o.add(s);else if(i===`door`){let n=new t.Group;n.name=`${U(r)}_hinge`,n.userData.interactivePivot=!0,n.position.x=0;let i=new t.Mesh(new t.BoxGeometry(.22,.5,.04),a);i.position.x=.11,i.castShadow=!0,i.receiveShadow=!0,n.add(i),o.add(n),s=i,o.userData.interactivePivot=n,o.userData.closedRotation=0,o.userData.openRotation=Number.isFinite(e.openAngle)?e.openAngle:Math.PI/2}else if(i===`window`)s=new t.Mesh(new t.PlaneGeometry(.35,.3),a),s.position.z=.02,o.add(s);else if(i===`roof`)s=new t.Mesh(new t.ConeGeometry(.34,.28,4),a),s.rotation.y=Math.PI/4,o.add(s);else if(i===`light`){s=new t.Mesh(new t.SphereGeometry(.09,32,16),a);let e=new t.PointLight(16777215,1.2,2.6,2);e.position.set(0,0,0),o.add(s,e),o.userData.light=e}else i===`wheel`?(s=new t.Mesh(new t.CylinderGeometry(.11,.11,.05,20),a),s.rotation.z=Math.PI/2,o.add(s)):i===`screen`?(s=new t.Mesh(new t.BoxGeometry(.42,.25,.03),a),o.add(s)):(s=new t.Mesh(vi(i,t),a),o.add(s));return o.userData.partMesh=s,o.userData.partState={open:!1,visible:!0,rotated:!1,shatter:!1},{id:n,name:r,type:i,root:o,mesh:s,actions:o.userData.partActions}}function Xr(e,t,n,r){let i=String(n.kit||`scene`).toLowerCase(),a=t.base[0]?.root||t.walls[0]?.root||t.details[0]?.root||null;return a&&a.scale.multiplyScalar(1),i===`house`?(t.base[0]&&t.base[0].root.position.set(0,-.15,0),t.walls.forEach((e,t)=>{e.root.position.set(t%2==0?-.16:.16,.05,t<2?-.16:.16),e.root.scale.set(1,1,1)}),t.doors[0]&&t.doors[0].root.position.set(.18,-.12,.18),t.windows[0]&&t.windows[0].root.position.set(-.18,.06,.18),t.roofs[0]&&t.roofs[0].root.position.set(0,.28,0)):i===`room`?(t.base[0]&&t.base[0].root.position.set(0,-.18,0),t.walls.forEach((e,t)=>{e.root.position.set(t<2?-.22:.22,.05,t%2==0?-.22:.22)})):i===`vehicle`?(t.base[0]&&t.base[0].root.position.set(0,-.08,0),t.wheels.forEach((e,t)=>{let n=t<2?-.22:.22,r=t%2==0?-.16:.16;e.root.position.set(n,-.16,r)})):i===`device`&&(t.base[0]&&t.base[0].root.position.set(0,0,0),t.screens.forEach(e=>e.root.position.set(0,.01,.01))),e.userData.modelForge.layout=i,e}function Zr(e,t,n,r={}){if(!t)return!1;let i=String(n||``).toLowerCase();return i===`open`?Qr(t,!0):i===`close`?Qr(t,!1):i===`toggle`?Qr(t,!t.userData.partState?.open):i===`rotate`?$r(t,r?.delta||Math.PI/2):i===`reveal`?ei(t,!0):i===`hide`?ei(t,!1):i===`shatter`?ti(e,t):i===`reconfigure`?ni(e):i===`grab`?ri(t,r):ii(t,i,r)}function Qr(e,t){let n=e.userData.interactivePivot||e,r=n.rotation.y,i=t?e.userData.openRotation??Math.PI/2:e.userData.closedRotation??0;return e.userData.partState=e.userData.partState||{},e.userData.partState.open=t,wi(360,e=>{n.rotation.y=r+(i-r)*Ti(e)})}function $r(e,t){let n=e.userData.partMesh||e,r=e.userData.rotateAxis||`y`,i=n.rotation[r],a=i+t;return e.userData.partState=e.userData.partState||{},e.userData.partState.rotated=!0,wi(240,e=>{n.rotation[r]=i+(a-i)*Ei(e)})}function ei(e,t){return e.visible=t,e.traverse?.(e=>{e.visible=t}),e.userData.partState=e.userData.partState||{},e.userData.partState.visible=t,!0}function ti(e,t){let n=[];if(t.traverse?.(e=>{e.isMesh&&n.push(e)}),!n.length)return ni(e);let r=new w;return t.getWorldPosition(r),n.forEach((e,t)=>{let n=new w(Math.cos(t*2.399),.35+t%3*.12,Math.sin(t*1.917)).normalize();e.userData.shatterStart=performance.now(),e.userData.shatterFrom=r.clone(),e.userData.shatterDirection=n}),wi(680,e=>{let t=Ti(e);n.forEach(e=>{let n=e.userData.shatterDirection;n&&(e.position.copy(n).multiplyScalar(t*.65),e.rotation.x+=.05*t,e.rotation.y+=.06*t,e.rotation.z+=.04*t)})})}function ni(e){let t=e.children.filter(e=>e.isObject3D);return t.forEach((e,t)=>{let n=Math.floor(t/3),r=(t%3-1)*.18,i=.04*n,a=(n-.5)*.12;e.position.x+=r*.2,e.position.y+=i*.2,e.position.z+=a*.2}),wi(340,e=>{let n=Ti(e);t.forEach((e,t)=>{let r=Math.floor(t/3),i=(t%3-1)*.18,a=.04*r,o=(r-.5)*.12;e.position.x+=(i-e.position.x)*n*.12,e.position.y+=(a-e.position.y)*n*.12,e.position.z+=(o-e.position.z)*n*.12})})}function ri(e,t){return t?.position&&e.position?.copy?(e.position.copy(t.position),!0):(e.userData.partState=e.userData.partState||{},e.userData.partState.grabbed=!0,!0)}function ii(e,t,n){e.userData.partState=e.userData.partState||{},e.userData.partState.lastAction=t;let r=String(t||``).toLowerCase().trim();if(r.includes(`raise`)||r.includes(`lift`)||r===`up`||r.includes(`deploy-gear`)){let t=e.position.y;return wi(400,n=>{e.position.y=t+.12*Ti(n)})}if(r.includes(`lower`)||r===`down`||r.includes(`retract-gear`)){let t=e.position.y;return wi(400,n=>{e.position.y=t-.12*Ti(n)})}if(r.includes(`extend`)||r.includes(`deploy`)||r.includes(`unfold`)||r.includes(`expand`)){let t=e.scale.clone(),n=e.rotation.y;return wi(500,r=>{let i=Ti(r);e.scale.copy(t).multiplyScalar(1+.18*i),e.rotation.y=n+.35*i})}if(r.includes(`retract`)||r.includes(`fold`)||r.includes(`pull`)||r.includes(`collapse`)){let t=e.scale.clone(),n=e.rotation.y;return wi(500,r=>{let i=Ti(r);e.scale.copy(t).multiplyScalar(1-.18*i),e.rotation.y=n-.35*i})}if(r.includes(`ignite`)||r.includes(`fire`)||r.includes(`charge`)||r.includes(`thrust`)||r.includes(`launch`)){if(e.isMesh&&e.material){let t=e.material.emissive?e.material.emissive.getHex():0;e.material.emissive=new re(54015),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=4),window.setTimeout(()=>{e.material.emissive&&e.material.emissive.setHex(t),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=0)},1e3)}return!0}return e.userData.partState.lastContext=n||{},!0}function ai(e,t){let n=U(t);if(!n)return null;let r=null;return e.traverse?.(e=>{r||[e.name,e.userData?.partName,e.userData?.role,e.userData?.partType].filter(Boolean).map(U).includes(n)&&(r=e.userData?.interactivePivot||e)}),r}function oi(e={}){return{name:String(e.name||e.role||`part`).trim(),type:li(e.type||e.role),material:[`matte`,`metal`,`glass`,`glow`,`wood`].includes(String(e.material||``).toLowerCase())?String(e.material).toLowerCase():`matte`,geometry:e.geometry?String(e.geometry).toLowerCase().trim():void 0,position:xi(e.position),rotation:Si(e.rotation),scale:Ci(e.scale),actions:Array.isArray(e.actions)&&e.actions.length?e.actions.map(ci):gi(e.type||e.role),openAngle:Number.isFinite(e.openAngle)?e.openAngle:void 0}}function si(e={}){return{gesture:String(e.gesture||``).toLowerCase().trim(),action:ci(e.action||e.trigger||``),target:String(e.target||e.part||``).trim()}}function ci(e){return String(e||``).toLowerCase().trim().replace(/\s+/g,`-`)}function li(e){let t=String(e||``).toLowerCase().trim().replace(/\s+/g,`-`);return[`wall`,`door`,`window`,`roof`,`drawer`,`panel`,`screen`,`wheel`,`prop`,`light`,`arm`,`leg`,`head`,`detail`,`base`].includes(t)?t:ui(t)}function ui(e){let t=U(e);return t.includes(`door`)?`door`:t.includes(`window`)?`window`:t.includes(`roof`)?`roof`:t.includes(`wheel`)?`wheel`:t.includes(`screen`)||t.includes(`display`)?`screen`:t.includes(`light`)||t.includes(`lamp`)?`light`:t.includes(`drawer`)?`drawer`:t.includes(`wall`)?`wall`:t.includes(`base`)||t.includes(`floor`)?`base`:t.includes(`arm`)?`arm`:t.includes(`leg`)?`leg`:t.includes(`head`)?`head`:`detail`}function di(e){let t=U(e);return t.includes(`house`)||t.includes(`home`)?`house`:t.includes(`room`)||t.includes(`bedroom`)||t.includes(`kitchen`)?`room`:t.includes(`car`)||t.includes(`truck`)||t.includes(`vehicle`)?`vehicle`:t.includes(`phone`)||t.includes(`device`)||t.includes(`tablet`)?`device`:t.includes(`character`)||t.includes(`person`)||t.includes(`robot`)?`character`:`scene`}function fi(e){return di(U(e?.userData?.modelName||e?.name||``))}function V(e,t){let n=new Set(e.map(U));for(let e of t)if(n.has(U(e)))return e;return``}function H(e){return e===`house`||e===`room`?`core`:e===`vehicle`?`chassis`:e===`device`?`screen`:e===`character`?`torso`:`core`}function pi(e){return Math.max(.04,Math.min(Number(e)||1,4))}function mi(e){let t={house:[{name:`base`,type:`base`,material:`matte`,position:[0,-.15,0],scale:[1.2,.6,1.2]},{name:`front-door`,type:`door`,material:`wood`},{name:`left-window`,type:`window`,material:`glass`},{name:`right-window`,type:`window`,material:`glass`},{name:`roof`,type:`roof`,material:`matte`}],room:[{name:`floor`,type:`base`,material:`matte`,position:[0,-.16,0],scale:[1.3,.05,1.3]},{name:`wall-a`,type:`wall`,material:`matte`},{name:`wall-b`,type:`wall`,material:`matte`},{name:`door`,type:`door`,material:`metal`},{name:`window`,type:`window`,material:`glass`}],device:[{name:`body`,type:`base`,material:`metal`,position:[0,0,0],scale:[1,.6,.15]},{name:`screen`,type:`screen`,material:`glass`,position:[0,.01,.09]},{name:`button`,type:`detail`,material:`glow`,position:[.27,-.05,.08],scale:[.16,.16,.16]}],vehicle:[{name:`chassis`,type:`base`,material:`metal`,position:[0,-.03,0],scale:[1.2,.36,.64]},{name:`wheel-front-left`,type:`wheel`,material:`metal`,position:[-.35,-.18,-.22]},{name:`wheel-front-right`,type:`wheel`,material:`metal`,position:[.35,-.18,-.22]},{name:`wheel-back-left`,type:`wheel`,material:`metal`,position:[-.35,-.18,.22]},{name:`wheel-back-right`,type:`wheel`,material:`metal`,position:[.35,-.18,.22]}],character:[{name:`torso`,type:`base`,material:`matte`,position:[0,.02,0],scale:[.36,.5,.18]},{name:`head`,type:`head`,material:`matte`,position:[0,.4,0],scale:[.28,.28,.28]},{name:`left-arm`,type:`arm`,material:`matte`,position:[-.28,.12,0],scale:[.12,.42,.12]},{name:`right-arm`,type:`arm`,material:`matte`,position:[.28,.12,0],scale:[.12,.42,.12]},{name:`left-leg`,type:`leg`,material:`matte`,position:[-.12,-.42,0],scale:[.12,.42,.12]},{name:`right-leg`,type:`leg`,material:`matte`,position:[.12,-.42,0],scale:[.12,.42,.12]}],scene:[{name:`core`,type:`base`,material:`matte`,position:[0,0,0],scale:[.9,.6,.9]},{name:`detail-a`,type:`detail`,material:`glow`,position:[-.26,.12,.2]},{name:`detail-b`,type:`detail`,material:`glow`,position:[.28,.1,-.18]},{name:`control-panel`,type:`screen`,material:`glass`,position:[0,.18,.32]}]};return t[e]||t.scene}function hi(e,t=[]){let n=t.map(e=>U(e.name)),r=V(n,[`front-door`,`door`,`front`,`main-door`,`screen`,`control-panel`])||H(e),i=V(n,[`roof`,`top`,`cover`,`lid`])||H(e),a=V(n,[`screen`,`display`,`control-panel`])||H(e),o=V(n,[`wheel-front-left`,`wheel-front-right`,`wheel-back-left`,`wheel-back-right`,`wheel`])||H(e),s={house:[{gesture:`pinch`,action:`toggle`,target:r},{gesture:`open-palm`,action:`reconfigure`,target:i},{gesture:`swipe-left`,action:`close`,target:r},{gesture:`swipe-right`,action:`open`,target:r},{gesture:`fist`,action:`shatter`,target:i}],room:[{gesture:`pinch`,action:`open`,target:r},{gesture:`fist`,action:`close`,target:r},{gesture:`two-hand-scale`,action:`reconfigure`,target:V(n,[`floor`,`base`])||H(e)},{gesture:`open-palm`,action:`reveal`,target:a}],device:[{gesture:`pinch`,action:`toggle`,target:a},{gesture:`open-palm`,action:`reveal`,target:V(n,[`body`,`base`])||H(e)},{gesture:`swipe-left`,action:`hide`,target:a},{gesture:`swipe-right`,action:`open`,target:a}],vehicle:[{gesture:`pinch`,action:`toggle`,target:V(n,[`chassis`,`base`])||H(e)},{gesture:`fist`,action:`reconfigure`,target:o},{gesture:`swipe-left`,action:`rotate`,target:o},{gesture:`swipe-right`,action:`open`,target:V(n,[`door`,`hood`,`trunk`])||H(e)}],character:[{gesture:`pinch`,action:`toggle`,target:V(n,[`head`])||H(e)},{gesture:`fist`,action:`grab`,target:V(n,[`torso`,`body`])||H(e)},{gesture:`swipe-right`,action:`reconfigure`,target:V(n,[`left-arm`,`arm`])||H(e)},{gesture:`swipe-left`,action:`rotate`,target:V(n,[`right-arm`,`arm`])||H(e)}],scene:[{gesture:`pinch`,action:`toggle`,target:V(n,[`core`,`root`,`base`])||H(e)},{gesture:`open-palm`,action:`reconfigure`,target:a},{gesture:`fist`,action:`shatter`,target:V(n,[`detail-a`,`detail-b`])||H(e)}]};return(s[e]||s.scene).filter(Boolean)}function gi(e){let t=li(e);return t===`door`?[`open`,`close`,`toggle`]:t===`window`?[`open`,`close`,`toggle`,`reveal`]:t===`drawer`?[`open`,`close`,`toggle`]:t===`wheel`?[`rotate`]:t===`screen`||t===`light`?[`toggle`,`reveal`,`hide`]:Mr.slice()}function _i(e,t){let n=String(e||`matte`).toLowerCase();return n===`metal`?new t.MeshPhysicalMaterial({color:9422847,roughness:.16,metalness:.92}):n===`glass`?new t.MeshPhysicalMaterial({color:13627391,roughness:.05,transmission:.58,transparent:!0,opacity:.36}):n===`glow`?new t.MeshBasicMaterial({color:51455,transparent:!0,opacity:.9}):n===`wood`?new t.MeshStandardMaterial({color:9202255,roughness:.82,metalness:.02}):new t.MeshStandardMaterial({color:8109311,roughness:.55,metalness:.1})}function vi(e,t){let n=li(e);return n===`base`||n===`wall`?new t.BoxGeometry(.5,.32,.5):n===`drawer`?new t.BoxGeometry(.28,.14,.28):n===`arm`?new t.CapsuleGeometry(.06,.28,5,16):n===`leg`?new t.CapsuleGeometry(.06,.34,5,16):n===`head`?new t.SphereGeometry(.16,24,16):n===`detail`?new t.IcosahedronGeometry(.08,1):new t.BoxGeometry(.22,.22,.22)}function yi(e,t,n=[]){let r=new ve;if(e&&r.setFromObject(e),!Number.isFinite(r.min.x)||!Number.isFinite(r.max.x))return[...n,...mi(t)];let i=r.getSize(new w),a=Math.max(i.x,.1),o=Math.max(i.y,.1),s=Math.max(i.z,.1),c=Math.max(a,o,s)||.4,l=[{name:`core`,type:`base`,material:`matte`,position:[0,0,0],scale:[1,1,1],actions:[`toggle`,`reconfigure`,`shatter`]},{name:`zone-front`,type:`panel`,material:`glass`,position:[0,0,s*.35],scale:[.72,.72,.12],actions:[`open`,`close`,`toggle`,`reveal`,`hide`]},{name:`zone-back`,type:`panel`,material:`glass`,position:[0,0,-s*.35],scale:[.72,.72,.12],actions:[`open`,`close`,`toggle`,`reveal`,`hide`]},{name:`zone-left`,type:`panel`,material:`glass`,position:[-a*.35,0,0],scale:[.12,.72,.72],actions:[`rotate`,`reconfigure`]},{name:`zone-right`,type:`panel`,material:`glass`,position:[a*.35,0,0],scale:[.12,.72,.72],actions:[`rotate`,`reconfigure`]},{name:`zone-top`,type:`roof`,material:`matte`,position:[0,o*.35,0],scale:[.85,.16,.85],actions:[`open`,`close`,`reconfigure`]},{name:`zone-bottom`,type:`base`,material:`matte`,position:[0,-o*.35,0],scale:[.85,.16,.85],actions:[`reconfigure`,`grab`]},{name:`zone-core`,type:`detail`,material:`glow`,position:[0,0,0],scale:[.42,.42,.42],actions:[`toggle`,`shatter`,`reveal`,`hide`]}];return[...n,...l.map(e=>({...e,scale:[pi(e.scale[0]*(c/1.25)),pi(e.scale[1]*(c/1.25)),pi(e.scale[2]*(c/1.25))]}))]}function bi(e){if(!e)return null;let t=String(e).replace(/```json|```/gi,``).trim(),n=t.indexOf(`{`),r=t.lastIndexOf(`}`);if(n<0||r<0||r<=n)return null;try{return JSON.parse(t.slice(n,r+1))}catch{return null}}function xi(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||0,Number(e[1])||0,Number(e[2])||0]:e&&typeof e==`object`?[Number(e.x)||0,Number(e.y)||0,Number(e.z)||0]:[0,0,0]}function Si(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||0,Number(e[1])||0,Number(e[2])||0]:e&&typeof e==`object`?[Number(e.x)||0,Number(e.y)||0,Number(e.z)||0]:[0,0,0]}function Ci(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||1,Number(e[1])||1,Number(e[2])||1]:e&&typeof e==`object`?[Number(e.x)||1,Number(e.y)||1,Number(e.z)||1]:[1,1,1]}function wi(e,t){let n=performance.now();return new Promise(r=>{let i=a=>{let o=Math.min((a-n)/e,1);t(o),o<1?requestAnimationFrame(i):r(!0)};requestAnimationFrame(i)})}function Ti(e){return 1-(1-e)**3}function Ei(e){return e<.5?4*e*e*e:1-(-2*e+2)**3/2}function U(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}var Di=!1,Oi=!1,ki=!1,Ai={default:{name:`default`,refDistance:.72,maxDistance:8,rolloffFactor:1.6,dampening:.08,cueGain:1},cinema:{name:`cinema`,refDistance:1.05,maxDistance:12,rolloffFactor:1.25,dampening:.16,cueGain:1.08},open:{name:`open`,refDistance:.68,maxDistance:16,rolloffFactor:1.15,dampening:.03,cueGain:.96},quiet:{name:`quiet`,refDistance:.84,maxDistance:7,rolloffFactor:1.8,dampening:.12,cueGain:.92},lab:{name:`lab`,refDistance:.78,maxDistance:9,rolloffFactor:1.5,dampening:.06,cueGain:1.02}};function ji(){Di||(Di=!0,A(`ar-scene-live`,()=>Li()),A(`object-placed`,({object:e})=>Mi(e)),Ri(),zi(),Li(),L(`spatialAudio`,!!Bi()),L(`speechSynthesis`,!!window.speechSynthesis),L(`voiceRecognition`,!!(window.SpeechRecognition||window.webkitSpeechRecognition)))}function Mi(e){if(!e)return null;let t=Li();if(!t)return null;if(e.userData.spatialAudio={...Ai[k.spatialAudio.environmentProfile]||Ai.default,...e.userData.spatialAudio||{}},e.userData.spatialAudioEmitter?.parent===e)return e.userData.spatialAudioEmitter;let n=new r(t);return n.name=`jarvis-object-spatial-audio`,Pi(n,e.userData.spatialAudio),e.add(n),e.userData.spatialAudioAttached=!0,e.userData.spatialAudioEmitter=n,n}async function Ni(e,t=`select`){if(!e)return!1;let n=Li(),r=Bi();if(!n||!r)return!1;try{if(r.state===`suspended`&&await r.resume(),r.state!==`running`)return!1;k.spatialAudio.unlocked=!0;let i=e.parent?Mi(e):Ii(n,e);return i?(i.isPlaying&&i.stop(),i.setBuffer(Vi(r,t)),i.setVolume((Ai[k.spatialAudio.environmentProfile]?.cueGain||1)*(t===`delete`?.9:1)),i.play(),window.setTimeout(()=>{try{i.stop()}catch{}i.userData.detachedAnchor&&(i.userData.detachedAnchor.parent?.remove(i.userData.detachedAnchor),i.disconnect())},420),!0):!1}catch{return!1}}function Pi(e,t={}){e.setRefDistance(t.refDistance||.72),e.setMaxDistance(t.maxDistance||8),e.setRolloffFactor(t.rolloffFactor||1.6),e.setDistanceModel(`inverse`)}function Fi(e=`default`){let t=Ai[String(e||`default`).toLowerCase()]||Ai.default;return k.spatialAudio.environmentProfile=t.name,k.spatialAudio.roomProfile={...t},k.placedObjects.forEach(e=>{let n=e?.userData?.spatialAudioEmitter;n&&Pi(n,t)}),k.spatialAudio.listener?.context&&(k.spatialAudio.context=k.spatialAudio.listener.context),L(`spatialAudio`,!!Bi()),t}function Ii(e,t){let n=new we;t.getWorldPosition(n.position),z().scene.add(n);let i=new r(e);return i.name=`jarvis-detached-spatial-cue`,Pi(i,t.userData.spatialAudio||Ai.default),i.userData.detachedAnchor=n,n.add(i),i}function Li(){let{camera:e}=z();return e?(k.spatialAudio.listener||(k.spatialAudio.listener=new be),k.spatialAudio.listener.parent!==e&&(k.spatialAudio.listener.parent?.remove(k.spatialAudio.listener),e.add(k.spatialAudio.listener)),k.spatialAudio.enabled=!0,k.spatialAudio.context=Bi(),k.spatialAudio.listener):null}function Ri(){if(ki)return;ki=!0;let e=()=>Fi(k.nativeOptions?.activeEnvironment||k.spatialAudio.environmentProfile||`default`);A(`native-options`,e),A(`native-ui-state`,e=>{let t=e?.audioEnvironment||e?.environment||e?.profile;t&&Fi(t)}),e()}function zi(){if(Oi)return;Oi=!0;let e=async()=>{let e=Bi();if(e)try{await e.resume(),k.spatialAudio.unlocked=e.state===`running`,k.spatialAudio.micPermission=k.spatialAudio.unlocked?`granted`:k.spatialAudio.micPermission,k.spatialAudio.unlocked&&E(`Spatial audio unlocked for AR objects.`,`Spatial Audio`)}catch{k.spatialAudio.unlocked=!1}};window.addEventListener(`pointerdown`,e,{passive:!0}),window.addEventListener(`touchstart`,e,{passive:!0})}function Bi(){try{return Oe.getContext()}catch{return null}}function Vi(e,t){let n=e.sampleRate,r=Math.max(1,Math.floor(n*.24)),i=e.createBuffer(1,r,n),a=i.getChannelData(0),o=t===`place`?330:t===`delete`?180:t===`open`?520:430;for(let e=0;e<r;e+=1){let t=e/n,r=Math.exp(-t*12)*Math.min(1,t*90);a[e]=(Math.sin(Math.PI*2*o*t)*.72+Math.sin(Math.PI*2*o*1.5*t)*.2)*r*.16}return i}var Hi=null,Ui=null,Wi=null,Gi=!1,Ki=new Map,qi=null,Ji=1/60,Yi=3,Xi=0,Zi=0,Qi=null;function $i(){return Gi&&!!Ui}function ea(){return Qi||(Qi=ta()),Qi}async function ta(){Hi=await t(()=>import(`./physics-Cz5QREtR.js`).then(e=>e.t),__vite__mapDeps([3,2]),import.meta.url),await Hi.init();let e=new Hi.Vector3(0,-9.81,0);Ui=new Hi.World(e),Wi=new Hi.EventQueue(!0),Ui.numSolverIterations=8,k.physicsWorld=Ui,Gi=!0,Zi=performance.now();let n=Hi.RigidBodyDesc.fixed().setTranslation(0,0,0);qi=Ui.createRigidBody(n);let r=Hi.ColliderDesc.cuboid(100,.1,100).setFriction(.7).setRestitution(.1);Ui.createCollider(r,qi),ra(),console.log(`[AR Physics] Rapier3D world initialized — 60Hz fixed timestep, CCD enabled, 8 solver iterations.`)}var na=0;function ra(){if(na)return;let e=performance.now(),t=()=>{let n=performance.now();ia(n-e),e=n,na=I(t)};na=I(t)}function ia(e){if(!Gi||!Ui)return;let t=performance.now(),n=typeof e==`number`&&e>0&&e<200?e/1e3:Math.min((t-Zi)/1e3,.05);Zi=t,Xi+=n;let r=0;for(;Xi>=Ji&&r<Yi;)Ui.step(Wi),Xi-=Ji,r++;Wi.drainCollisionEvents((e,t,n)=>{n&&window.dispatchEvent(new CustomEvent(`ar-physics-collision`,{detail:{handle1:e,handle2:t}}))});for(let[e,t]of Ki.entries()){let n=e.translation(),r=e.rotation();t.position.set(n.x,n.y,n.z),t.quaternion.set(r.x,r.y,r.z,r.w)}Ki.size>0&&window.dispatchEvent(new CustomEvent(`ar-physics-step`))}function aa(e,t=`dynamic`){if(!Ui)return null;let n=t===`dynamic`?Hi.RigidBodyDesc.dynamic():Hi.RigidBodyDesc.fixed();n.setTranslation(e.x,e.y,e.z),t===`dynamic`&&(n.setLinearDamping(.1),n.setAngularDamping(.05),n.setCcdEnabled(!0));let r=Ui.createRigidBody(n),i=Hi.ColliderDesc.ball(.2).setFriction(.7).setRestitution(.3);return Ui.createCollider(i,r),r}function oa(e,t){Ki.set(t,e)}function sa(e){Ui&&Ui.removeRigidBody(e),Ki.delete(e)}var ca=Uint8Array,la=Uint16Array,ua=Int32Array,da=new ca([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),fa=new ca([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),pa=new ca([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),ma=function(e,t){for(var n=new la(31),r=0;r<31;++r)n[r]=t+=1<<e[r-1];for(var i=new ua(n[30]),r=1;r<30;++r)for(var a=n[r];a<n[r+1];++a)i[a]=a-n[r]<<5|r;return{b:n,r:i}},ha=ma(da,2),ga=ha.b,_a=ha.r;ga[28]=258,_a[258]=28;var va=ma(fa,0),ya=va.b;va.r;for(var ba=new la(32768),W=0;W<32768;++W){var xa=(W&43690)>>1|(W&21845)<<1;xa=(xa&52428)>>2|(xa&13107)<<2,xa=(xa&61680)>>4|(xa&3855)<<4,ba[W]=((xa&65280)>>8|(xa&255)<<8)>>1}for(var Sa=(function(e,t,n){for(var r=e.length,i=0,a=new la(t);i<r;++i)e[i]&&++a[e[i]-1];var o=new la(t);for(i=1;i<t;++i)o[i]=o[i-1]+a[i-1]<<1;var s;if(n){s=new la(1<<t);var c=15-t;for(i=0;i<r;++i)if(e[i])for(var l=i<<4|e[i],u=t-e[i],d=o[e[i]-1]++<<u,f=d|(1<<u)-1;d<=f;++d)s[ba[d]>>c]=l}else for(s=new la(r),i=0;i<r;++i)e[i]&&(s[i]=ba[o[e[i]-1]++]>>15-e[i]);return s}),Ca=new ca(288),W=0;W<144;++W)Ca[W]=8;for(var W=144;W<256;++W)Ca[W]=9;for(var W=256;W<280;++W)Ca[W]=7;for(var W=280;W<288;++W)Ca[W]=8;for(var wa=new ca(32),W=0;W<32;++W)wa[W]=5;var Ta=Sa(Ca,9,1),Ea=Sa(wa,5,1),Da=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},Oa=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},ka=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},Aa=function(e){return(e+7)/8|0},ja=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new ca(e.subarray(t,n))},Ma=[`unexpected EOF`,`invalid block type`,`invalid length/literal`,`invalid distance`,`stream finished`,`no stream handler`,,`no callback`,`invalid UTF-8 data`,`extra field too long`,`date not in range 1980-2099`,`filename too long`,`stream finishing`,`invalid zip data`],Na=function(e,t,n){var r=Error(t||Ma[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,Na),!n)throw r;return r},Pa=function(e,t,n,r){var i=e.length,a=r?r.length:0;if(!i||t.f&&!t.l)return n||new ca(0);var o=!n,s=o||t.i!=2,c=t.i;o&&(n=new ca(i*3));var l=function(e){var t=n.length;if(e>t){var r=new ca(Math.max(t*2,e));r.set(n),n=r}},u=t.f||0,d=t.p||0,f=t.b||0,p=t.l,m=t.d,h=t.m,g=t.n,_=i*8;do{if(!p){u=Oa(e,d,1);var ee=Oa(e,d+1,3);if(d+=3,!ee){var v=Aa(d)+4,te=e[v-4]|e[v-3]<<8,y=v+te;if(y>i){c&&Na(0);break}s&&l(f+te),n.set(e.subarray(v,y),f),t.b=f+=te,t.p=d=y*8,t.f=u;continue}else if(ee==1)p=Ta,m=Ea,h=9,g=5;else if(ee==2){var ne=Oa(e,d,31)+257,re=Oa(e,d+10,15)+4,b=ne+Oa(e,d+5,31)+1;d+=14;for(var x=new ca(b),ie=new ca(19),S=0;S<re;++S)ie[pa[S]]=Oa(e,d+S*3,7);d+=re*3;for(var ae=Da(ie),oe=(1<<ae)-1,se=Sa(ie,ae,1),S=0;S<b;){var ce=se[Oa(e,d,oe)];d+=ce&15;var v=ce>>4;if(v<16)x[S++]=v;else{var le=0,ue=0;for(v==16?(ue=3+Oa(e,d,3),d+=2,le=x[S-1]):v==17?(ue=3+Oa(e,d,7),d+=3):v==18&&(ue=11+Oa(e,d,127),d+=7);ue--;)x[S++]=le}}var de=x.subarray(0,ne),fe=x.subarray(ne);h=Da(de),g=Da(fe),p=Sa(de,h,1),m=Sa(fe,g,1)}else Na(1);if(d>_){c&&Na(0);break}}s&&l(f+131072);for(var pe=(1<<h)-1,me=(1<<g)-1,he=d;;he=d){var le=p[ka(e,d)&pe],C=le>>4;if(d+=le&15,d>_){c&&Na(0);break}if(le||Na(2),C<256)n[f++]=C;else if(C==256){he=d,p=null;break}else{var ge=C-254;if(C>264){var S=C-257,_e=da[S];ge=Oa(e,d,(1<<_e)-1)+ga[S],d+=_e}var ve=m[ka(e,d)&me],ye=ve>>4;ve||Na(3),d+=ve&15;var fe=ya[ye];if(ye>3){var _e=fa[ye];fe+=ka(e,d)&(1<<_e)-1,d+=_e}if(d>_){c&&Na(0);break}s&&l(f+131072);var be=f+ge;if(f<fe){var xe=a-fe,Se=Math.min(fe,be);for(xe+f<0&&Na(3);f<Se;++f)n[f]=r[xe+f]}for(;f<be;++f)n[f]=n[f-fe]}}t.l=p,t.p=he,t.b=f,t.f=u,p&&(u=1,t.m=h,t.d=m,t.n=g)}while(!u);return f!=n.length&&o?ja(n,0,f):n.subarray(0,f)},Fa=new ca(0),Ia=function(e,t){return e[t]|e[t+1]<<8},La=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ra=function(e,t){return La(e,t)+La(e,t+4)*4294967296};function za(e,t){return Pa(e,{i:2},t&&t.out,t&&t.dictionary)}var Ba=typeof TextDecoder<`u`&&new TextDecoder;try{Ba.decode(Fa,{stream:!0})}catch{}var Va=function(e){for(var t=``,n=0;;){var r=e[n++],i=(r>127)+(r>223)+(r>239);if(n+i>e.length)return{s:t,r:ja(e,n-1)};i?i==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):i&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function Ha(e,t){if(t){for(var n=``,r=0;r<e.length;r+=16384)n+=String.fromCharCode.apply(null,e.subarray(r,r+16384));return n}else if(Ba)return Ba.decode(e);else{var i=Va(e),a=i.s,n=i.r;return n.length&&Na(8),a}}var Ua=function(e,t){return t+30+Ia(e,t+26)+Ia(e,t+28)},Wa=function(e,t,n){var r=Ia(e,t+28),i=Ha(e.subarray(t+46,t+46+r),!(Ia(e,t+8)&2048)),a=t+46+r,o=La(e,t+20),s=n&&o==4294967295?Ga(e,a):[o,La(e,t+24),La(e,t+42)],c=s[0],l=s[1],u=s[2];return[Ia(e,t+10),c,l,i,a+Ia(e,t+30)+Ia(e,t+32),u]},Ga=function(e,t){for(;Ia(e,t)!=1;t+=4+Ia(e,t+2));return[Ra(e,t+12),Ra(e,t+4),Ra(e,t+20)]};function Ka(e,t){for(var n={},r=e.length-22;La(e,r)!=101010256;--r)(!r||e.length-r>65558)&&Na(13);var i=Ia(e,r+8);if(!i)return{};var a=La(e,r+16),o=a==4294967295||i==65535;if(o){var s=La(e,r-12);o=La(e,s)==101075792,o&&(i=La(e,s+32),a=La(e,s+48))}for(var c=t&&t.filter,l=0;l<i;++l){var u=Wa(e,a,o),d=u[0],f=u[1],p=u[2],m=u[3],h=u[4],g=u[5],_=Ua(e,g);a=h,(!c||c({name:m,size:f,originalSize:p,compression:d}))&&(d?d==8?n[m]=za(e.subarray(_,_+f),{out:new ca(p)}):Na(14,`unknown compression type `+d):n[m]=ja(e,_,_+f))}return n}var qa=new x({color:16777215,transparent:!0,opacity:.72}),Ja=`jarvis_ar_placed_objects_v1`,Ya=`jarvis_ar_my_models_v1`,Xa=`0.158.0`,Za=new Ee().setDecoderPath(`https://cdn.jsdelivr.net/npm/three@${Xa}/examples/jsm/libs/draco/`),Qa=new fe().setTranscoderPath(`https://cdn.jsdelivr.net/npm/three@${Xa}/examples/jsm/libs/basis/`),$a=!1;function eo(){if($a)return;let e=z()?.renderer;if(e)try{Qa.detectSupport(e),$a=!0}catch{}}function to(e){return e.setDRACOLoader(Za),e.setKTX2Loader(Qa),e.setMeshoptDecoder(Ie),e}var no=to(new ze),ro=8,io=180*1024*1024,ao=new Map,oo=0,so=null,co=0,lo=new Map,uo=0,fo=``,po=0,mo=0,ho=!1,go=!1,_o=0,vo=new Map,yo=new Set;function bo(){So(),No(),A(`open-model-forge`,Eo),A(`open-models`,Co),A(`jarvis-model-action`,e=>cs(e)),A(`gesture-pinch`,e=>ss(`pinch`,e)),A(`gesture-fist`,e=>ss(`fist`,e)),A(`gesture-open-palm`,e=>ss(`open-palm`,e)),A(`gesture-swipe-left`,e=>ss(`swipe-left`,e)),A(`gesture-swipe-right`,e=>ss(`swipe-right`,e)),A(`gesture-two-hand-scale`,e=>ss(`two-hand-scale`,e)),A(`world-anchor-sample`,()=>vs()),A(`native-ar-state`,e=>xo(e)),A(`spawn-model`,async e=>{Fo(Mn(e?.query||`Duck`).name)}),A(`spawn-generated-glb`,async e=>{if(!e?.model_url)return;let t=e?.model_name||`Generated Model`;try{E(`Loading generated model: ${t}...`,`Jarvis AI Generation`);let n=String(e.model_url);if(n.startsWith(`/`)){let e=k.jarvis?.apiBase?.()||``;e&&(n=`${e}${n}`)}let r=await Ho(n);r.userData.modelName=t,Br(r,B({name:t,kit:Ws(t)})),Ro(r,window.AR_CAMERA_POSITION||new w(0,0,-2)),E(`Successfully deployed ${t}!`,`Jarvis AI Generation`)}catch(e){T(`Failed to load generated model: ${e.message}`,`Generation Error`)}}),setInterval(()=>qo(),6e4)}function xo(e={}){let t=Array.isArray(e.objects)?e.objects:[];for(let e of t){let t=String(e.id||e.uid||``).trim(),n=String(e.label||e.name||e.modelName||e.type||`Native Object`),r=e.position||{x:Number(e.px??e.x??0),y:Number(e.py??e.y??k.floorY+.08),z:Number(e.pz??e.z??-1.6)},i=t?k.placedObjects.find(e=>e.userData.id===t):null;if(i){i.position.copy(zs(r)),i.userData.modelName=n,ds(i);continue}let a=os(n);t&&(a.userData.id=t),a.userData.sourceURL=`native-apk-state`,Br(a,B({name:n,kit:Ws(n)})),Vo(a,n,r,null,`native-apk-state`)}}function So(){if(ho||go)return;let e=()=>{ho||(ho=!0,ms().catch(e=>T(e.message,`Model Restore Failed`)))};if(k.liveSceneReady){e();return}go=!0;let t=A(`ar-scene-live`,()=>{t(),go=!1,e()})}function Co(){let e=document.createElement(`div`),t=document.createElement(`input`);t.placeholder=`Search free models`;let n=document.createElement(`div`);n.className=`panel-list`;let r=document.createElement(`input`);r.type=`file`,r.accept=`.glb,.gltf,.obj,.fbx`;let i=wo(),a=document.createElement(`button`);a.className=`panel-action`,a.textContent=`Open Custom 3D Builder`,a.onclick=Ps;let o=document.createElement(`button`);o.className=`panel-action`,o.textContent=`Open Interactive Model Forge`,o.onclick=Eo;let s=document.createElement(`p`);s.className=`panel-note`,s.textContent=`Create models with behavior schemas, named parts, and Jarvis-generated interactions.`,e.append(t,n,i,r,a,o,s);let c=()=>{let e=t.value.toLowerCase();n.replaceChildren(...An.filter(t=>!e||t.name.toLowerCase().includes(e)||t.category.includes(e)).map(e=>Ao(e)))};t.addEventListener(`input`,c),r.addEventListener(`change`,()=>jo(r.files?.[0])),c(),new hn({title:`Models`,body:e,icon:`M`,width:390,height:560}).focus()}function wo(){let e=document.createElement(`section`);e.className=`sketchfab-panel`;let t=document.createElement(`strong`);t.textContent=`JARVIS 3D Asset Nexus`;let n=document.createElement(`p`);n.className=`panel-note`,n.textContent=`Connectors: Turbosquid, CGTrader, Mixamo, Poly.pizza, Kenney, Quaternius, Sketchfab.`;let r=document.createElement(`button`);r.className=`panel-action`,r.style.cssText=`width: 100%; margin: 6px 0; padding: 10px 14px; text-align: left; display: flex; align-items: center; justify-content: space-between; font-size: 13px; border-radius: 12px; font-weight: 500;`;let i=document.createElement(`span`);i.textContent=`API Connectors Logins`;let a=document.createElement(`span`);a.className=`chevron`,a.textContent=`v`,a.style.cssText=`transition: transform 0.25s ease; display: inline-block;`,r.append(i,a);let o=document.createElement(`div`);o.style.cssText=`display: none; flex-direction: column; gap: 10px; margin: 8px 0; padding: 14px; border: 1px solid var(--separator); border-radius: 14px; background: rgba(0,0,0,0.22);`;function s(e,t,n,r){let i=document.createElement(`div`);i.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let a=document.createElement(`div`);a.style.cssText=`display: flex; align-items: center; justify-content: space-between; font-size: 12px;`;let o=document.createElement(`span`);o.textContent=n,o.style.color=`var(--text-secondary)`;let s=document.createElement(`span`);s.style.cssText=`display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; cursor: pointer;`;let c=document.createElement(`input`);c.type=`password`,c.placeholder=t,c.value=e===`sketchfab`?Bn():rr(e),c.style.cssText=`margin: 2px 0 !important; min-height: 38px !important; padding: 8px 12px !important; font-size: 12px !important; border-radius: 10px !important;`;let l=document.createElement(`div`);l.style.cssText=`font-size: 10px; color: var(--warning); display: none; padding: 2px 0 0 2px; line-height: 1.4;`;let u=()=>{let e=c.value.trim();s.replaceChildren();let t=document.createElement(`span`);e?(t.style.cssText=`color:var(--success); margin-right: 2px;`,t.textContent=`●`,s.append(t,document.createTextNode(` Authenticated ✓`)),l.style.display=`none`):(t.style.cssText=`color:var(--warning); margin-right: 2px;`,t.textContent=`●`,s.append(t,document.createTextNode(` No key — tap to add`)),r&&(l.style.display=`block`,l.innerHTML=`⚡ Get your free key at <span style="color:var(--accent);text-decoration:underline;">${r}</span>`))};return s.addEventListener(`click`,()=>c.focus()),c.addEventListener(`input`,u),u(),a.append(o,s),i.append(a,c,l),{wrapper:i,input:c,updateStatus:u}}let c=document.createElement(`div`);c.style.cssText=`background: rgba(96,165,250,0.12); border: 1px solid rgba(96,165,250,0.3); border-radius: 10px; padding: 10px 12px; font-size: 11px; color: rgba(255,255,255,0.85); line-height: 1.5;`,c.innerHTML=`🔑 <strong>Enter your API keys below to unlock live search.</strong><br>Yellow ● = no key set (uses sample models). Green ● = live API active.<br>Kenney &amp; Quaternius are always free — no key needed.`;let l=s(`omega_session`,`OMEGA cloud session token`,`OMEGA Cloud Link`,``),u=s(`sketchfab`,`Sketchfab OAuth/API Token`,`Sketchfab API`,`sketchfab.com/settings/password-api`),d=s(`poly_pizza`,`Poly.pizza API Key`,`Poly.pizza API`,`poly.pizza/account`),f=s(`cgtrader`,`CGTrader API Token`,`CGTrader API Token`,`cgtrader.com/account`),p=s(`turbosquid`,`username:api_key`,`TurboSquid user:key`,`turbosquid.com/Account`),m=s(`mixamo`,`adobe_email:adobe_password`,`Mixamo Adobe email:pass`,`mixamo.com (use your Adobe login)`),h=document.createElement(`div`);h.style.cssText=`display: flex; gap: 8px; font-size: 11px; background: rgba(255,255,255,0.05); padding: 8px 10px; border-radius: 10px; color: var(--text-secondary); justify-content: space-between;`,h.append(To(`Kenney`,`CC0 active`),To(`Quaternius`,`CC0 active`));let g=document.createElement(`button`);g.className=`panel-action`,g.textContent=`Save Credentials`,g.style.cssText=`min-height: 38px; font-size: 13px; font-weight: 600; background: var(--accent); color: #fff; margin-top: 6px;`,g.onclick=()=>{let e=l.input.value.trim()!==rr(`omega_session`);if(ir(`omega_session`,l.input.value),Vn(u.input.value),ir(`poly_pizza`,d.input.value),ir(`cgtrader`,f.input.value),ir(`turbosquid`,p.input.value),ir(`mixamo`,m.input.value),e&&k.jarvis){try{k.jarvis.ws?.close()}catch{}k.jarvis.loadConfig()}l.updateStatus(),u.updateStatus(),d.updateStatus(),f.updateStatus(),p.updateStatus(),m.updateStatus(),E(`All 3D Asset Nexus connector credential configurations saved locally.`,`Credentials Saved`)},o.append(c,l.wrapper,u.wrapper,d.wrapper,f.wrapper,p.wrapper,m.wrapper,h,g);let _=!1;r.onclick=()=>{_=!_,o.style.display=_?`flex`:`none`,r.querySelector(`.chevron`).style.transform=_?`rotate(180deg)`:`rotate(0)`};let ee=document.createElement(`div`);ee.className=`inline-row`,ee.style.cssText=`margin: 6px 0; display: flex; align-items: center; gap: 8px;`;let v=document.createElement(`span`);v.textContent=`Source:`,v.style.cssText=`font-size: 13px; color: var(--text-secondary);`;let te=document.createElement(`select`);te.style.cssText=`flex: 1; background: rgba(0,0,0,.35); color: #fff; border: 1px solid var(--glass-border); border-radius: 8px; padding: 6px; font-size: 13px;`,[{value:`all`,label:`All Free Sources (Combined)`},{value:`poly_pizza`,label:`Poly.pizza (Free CC0)`},{value:`kenney`,label:`Kenney.nl (CC0 Game Assets)`},{value:`quaternius`,label:`Quaternius (CC0 Low-Poly)`},{value:`mixamo`,label:`Mixamo (Free Rigged Characters)`},{value:`sketchfab`,label:`Sketchfab (Free CC Assets)`},{value:`cgtrader`,label:`CGTrader (Free CC0/Standard)`},{value:`turbosquid`,label:`Turbosquid (Free CC0/Standard)`}].forEach(e=>{let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,te.appendChild(t)}),ee.append(v,te);let y=document.createElement(`div`);y.className=`inline-row`;let ne=document.createElement(`input`);ne.placeholder=`Search free 3D models...`;let re=document.createElement(`button`);re.className=`panel-action`,re.textContent=`Search`,y.append(ne,re);let b=document.createElement(`div`);b.className=`panel-list sketchfab-results`;let x=document.createElement(`p`);x.className=`panel-note`,x.textContent=`Ready to search unified free connectors.`;let ie=!1;return Xn().then(e=>{e?.configured&&(ie=!0,x.textContent=`OMEGA Sketchfab token active. Search & placement run completely free.`,u.input.placeholder=`Optional override token`)}).catch(()=>{}),re.onclick=async()=>{let e=u.input.value.trim()||Bn();Vn(e);let t=te.value;x.textContent=`Searching free assets from ${te.options[te.selectedIndex].text}...`,b.replaceChildren();try{let n=await lr(ne.value||`object`,t,e);if(!n.length){x.textContent=`No free assets matched your query on the selected source.`;return}x.textContent=`Found ${n.length} free asset(s).`,b.replaceChildren(...n.map(t=>Do(t,()=>u.input.value.trim()||e,()=>ie)))}catch(e){x.textContent=`Unified search failed.`,T(e.message,`Asset Search Failed`)}},e.append(t,n,r,o,ee,y,x,b),e}function To(e,t){let n=document.createElement(`div`),r=document.createElement(`strong`);r.textContent=`${e}:`;let i=document.createElement(`span`);return i.style.color=`var(--success)`,i.textContent=` ● `,n.append(r,i,document.createTextNode(t)),n}async function Eo(){let e=document.createElement(`div`),t=document.createElement(`strong`),n=document.createElement(`p`),r=document.createElement(`input`),i=document.createElement(`select`),a=document.createElement(`textarea`),o=document.createElement(`pre`),s=document.createElement(`div`),c=document.createElement(`button`),l=document.createElement(`button`),u=document.createElement(`button`),d=document.createElement(`button`),f=B({name:`Custom Model`,kit:`scene`}),p=f;t.textContent=`Jarvis 3D Forge`,n.className=`panel-note`,n.textContent=`Build a model as geometry + parts + behaviors + triggers + scripts + exports.`,r.placeholder=`Model name`,r.value=f.name,a.rows=5,a.placeholder=`Describe the model, its parts, and the actions you want`,a.value=`Create a fully interactive model with named parts, gestures, and a behavior schema.`,_r(i,[`scene`,`house`,`room`,`device`,`vehicle`,`character`]),o.style.cssText=`white-space:pre-wrap;font:12px/1.45 monospace;color:rgba(255,255,255,.82);background:rgba(0,0,0,.25);padding:10px;border-radius:12px;max-height:220px;overflow:auto`,s.className=`panel-row`,c.className=`panel-action`,c.textContent=`Generate Blueprint`,l.className=`panel-action`,l.textContent=`Attach to Selected`,u.className=`panel-action`,u.textContent=`Build and Place`,d.className=`panel-action`,d.textContent=`Save Blueprint`;let m=()=>{o.textContent=JSON.stringify(p,null,2),s.replaceChildren();let e=k.selectedObject||k.placedObjects.at(-1)||null;e&&Hr(e,s)};m(),c.onclick=async()=>{try{p=await Ir(a.value,{name:r.value,kit:i.value}),p.name=r.value||p.name,p.prompt=a.value,p.kit=i.value,p.updatedAt=Date.now(),m(),E(`Jarvis blueprint generated. Review the schema and then attach or build.`,`Model Forge`)}catch(e){T(e.message,`Model Forge Failed`)}},l.onclick=()=>{let e=k.selectedObject;if(!e){E(`Select a model first, then attach the schema.`,`Model Forge`);return}Br(e,{...p,name:r.value||p.name||e.userData.modelName||`Custom Model`,prompt:a.value,kit:i.value}),Jr(e),m(),E(`Behavior schema attached to ${e.userData.modelName||`selected model`}.`,`Model Forge`)},u.onclick=()=>{try{let e=Lr({...p,name:r.value||p.name||`Custom Model`,prompt:a.value,kit:i.value});zo(e,e.userData.modelName),Jr(e),E(`${e.userData.modelName} built with ${e.userData.modelForge?.parts?.length||0} interactive parts.`,`Model Forge`)}catch(e){T(e.message,`Model Forge Failed`)}},d.onclick=()=>{p={...p,name:r.value||p.name,prompt:a.value,kit:i.value,updatedAt:Date.now()},Fr(p),E(`Blueprint saved locally for later reuse.`,`Model Forge`)},e.append(t,n,r,i,a,c,l,u,d,o,s),new hn({title:`Interactive Model Forge`,body:e,icon:`F`,width:390,height:620}).focus()}function Do(e,t,n=()=>!1){let r=document.createElement(`article`);if(r.className=`model-card ${e.source}-card`,e.thumbnail){let t=document.createElement(`img`);t.src=e.thumbnail,t.alt=``,t.loading=`lazy`,r.appendChild(t)}let i=document.createElement(`div`),a=document.createElement(`strong`),o=document.createElement(`span`),s=document.createElement(`a`);a.textContent=e.name;let c=e.size?Hs(e.size):`free`,l=e.faceCount?` / ${Us(e.faceCount)} faces`:``;o.textContent=`${e.licenseLabel} / ${c}${l}`,s.textContent=`${e.author} (${e.source.toUpperCase()})`,s.href=e.authorUrl||e.viewerUrl||`#`,s.target=`_blank`,s.rel=`noopener`,i.append(a,o,s);let u=document.createElement(`div`);u.className=`model-actions`;let d=document.createElement(`button`);d.className=`panel-action`;let f=e.source===`sketchfab`&&!n()&&!t();d.textContent=f?`Token Needed`:`Place`,d.onclick=()=>{if(f){T(`Sketchfab downloads require a configured token.`,`Token Required`);return}Oo(e,t())};let p=document.createElement(`a`);return p.className=`panel-action link-action`,p.href=e.viewerUrl||`#`,p.target=`_blank`,p.rel=`noopener`,p.textContent=`Open`,u.append(d,p),r.append(i,u),r}async function Oo(e,t){O(`Requesting ${e.source.toUpperCase()} download: ${e.name}...`,55);try{let n;if(e.downloadUrl===`forge-procedural`)n=Lr(B({name:e.name,kit:Ws(e.name)}));else if(e.downloadUrl&&e.downloadUrl.startsWith(`api:spawn_3d_model:`)){let t=e.downloadUrl.split(`api:spawn_3d_model:`)[1];E(`[STABLE FAST 3D] Generating custom 3D model for: ${t}...`,`Jarvis AI Generation`),fetch(`/xr/model3d/spawn`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${rr(`omega_session`)||``}`},body:JSON.stringify({description:t,persona:`JARVIS`,use_cloud_fallback:!0})}).then(async e=>{let t=null;try{t=await e.json()}catch{}if(!e.ok){E(`[STABLE FAST 3D] Generation failed (${e.status}). ${t?.detail||``}`.trim(),`Generation Error`);return}if(t?.status===`needs_confirmation`){E(`[STABLE FAST 3D] ${t.message||`Cloud generation required.`}`,`Generation Paused`);return}E(`[STABLE FAST 3D] Model generated and placed in the scene.`,`Generation Complete`)}).catch(e=>{console.error(`Generation request failed:`,e),E(`[STABLE FAST 3D] Generation request failed — check connection.`,`Generation Error`)}),hidePanel(),clearLoading();return}else if(e.downloadUrl)(e.source===`cgtrader`||e.source===`turbosquid`||e.source===`mixamo`||e.source===`poly_pizza`)&&(rr(e.source)?e.source===`mixamo`?E(`[Mixamo] Secure Adobe ID Synchronized! Placed free rigged character.`,`Mixamo Rigging`):e.source===`poly_pizza`?E(`[Poly.pizza] Authenticated API Key! Placed free low-poly asset.`,`Poly.pizza API`):E(`[${e.source.toUpperCase()}] Authenticated as user! Placed free model.`,`${e.source.toUpperCase()} Session`):E(`[${e.source.toUpperCase()}] Session Proxy: Connected via OMEGA public portal... Placed free model!`,`${e.source.toUpperCase()} Session`)),n=await Ho(e.downloadUrl);else if(e.source===`sketchfab`){Vn(t);let r=await Jn(e.uid,t),i=r.glb?.url||r.gltf?.url;if(!i)throw Error(`Sketchfab did not return a glTF or GLB download URL.`);n=r.glb?.url?await Ho(i):await ko(i)}else throw Error(`Unsupported model source: ${e.source}`);n.userData.modelName=e.name,n.userData.sketchfab=e.sketchfab||{uid:e.uid,author:e.author,authorUrl:e.authorUrl||``,license:e.license||`free`,licenseLabel:e.licenseLabel||`Free`,viewerUrl:e.viewerUrl||``},Br(n,B({name:e.name,kit:Ws(e.name)}));let r=Lo(.5,.56);Vo(n,e.name,r.position,r.rotation,`${e.source}:${e.uid}`),E(`${e.name} placed successfully from ${e.source.toUpperCase()}.`,e.source.toUpperCase())}catch(t){T(`${e.source.toUpperCase()} failed: ${t.message}. Spawning premium generated fallback...`,`${e.source.toUpperCase()} Fallback`);let n=os(e.name);Br(n,B({name:e.name,kit:Ws(e.name)}));let r=Lo(.5,.56);Vo(n,e.name,r.position,r.rotation,``)}finally{nt()}}async function ko(e){let t=await fetch(e);if(!t.ok)throw Error(`Sketchfab archive download failed: ${t.status}`);let n=Ka(new Uint8Array(await t.arrayBuffer())),r=Object.keys(n).filter(e=>e.toLowerCase().endsWith(`.gltf`));if(!r.length)throw Error(`Sketchfab archive did not contain a .gltf scene.`);let i=r.find(e=>e.toLowerCase().replace(/.*\//,``)===`scene.gltf`)??r.reduce((e,t)=>n[t].byteLength>n[e].byteLength?t:e,r[0]),a=new TextDecoder().decode(n[i]),o=i.includes(`/`)?i.slice(0,i.lastIndexOf(`/`)+1):``,s=new Map;for(let[e,t]of Object.entries(n)){let n=Bs(e),r=URL.createObjectURL(new Blob([t],{type:n}));s.set(Vs(e),r),s.set(e.split(`/`).pop(),r)}let c=new h;c.setURLModifier(e=>{let t=Vs(e),n=Vs(`${o}${t}`);return s.get(t)||s.get(n)||s.get(t.split(`/`).pop())||e});let l=to(new ze(c));return eo(),new Promise((e,t)=>{l.parse(a,o,t=>{for(let e of new Set(s.values()))URL.revokeObjectURL(e);e(t.scene)},e=>{for(let e of new Set(s.values()))URL.revokeObjectURL(e);t(e)})})}function Ao(e){let t=document.createElement(`article`);t.className=`model-card`;let n=document.createElement(`div`),r=document.createElement(`strong`),i=document.createElement(`span`),a=document.createElement(`button`);return r.textContent=e.name,i.textContent=`${e.category} / ${e.size}`,a.className=`panel-action`,a.textContent=`Place`,a.onclick=()=>Fo(e.name),n.append(r,i),t.append(n,a),t}async function jo(e){if(!e)return;if(e.size>100*1024*1024){T(`Custom model is larger than 100MB. Please optimize or compress it first.`,`Model Too Large`);return}let t=e.name.split(`.`).pop()?.toLowerCase(),n=``;try{n=URL.createObjectURL(e);let r=t===`glb`||t===`gltf`?await Ho(n):await Mo(n,t);r.userData.modelName=e.name,zo(r,e.name);let i=ur(Ya,[]);i.push({name:e.name,type:t,size:e.size,addedAt:Date.now()}),dr(Ya,i.slice(-24))}catch(e){T(e.message,`Custom Model Failed`)}finally{n&&URL.revokeObjectURL(n)}}async function Mo(e,n){if(n===`obj`){let{OBJLoader:n}=await t(async()=>{let{OBJLoader:e}=await import(`./three-WgMhLE1J.js`).then(e=>e.t);return{OBJLoader:e}},__vite__mapDeps([1,2]),import.meta.url);return new Promise((t,r)=>new n().load(e,t,void 0,r))}if(n===`fbx`){let{FBXLoader:n}=await t(async()=>{let{FBXLoader:e}=await import(`./three-WgMhLE1J.js`).then(e=>e.n);return{FBXLoader:e}},__vite__mapDeps([1,2]),import.meta.url);return new Promise((t,r)=>new n().load(e,t,void 0,r))}throw Error(`Unsupported custom model type: ${n||`unknown`}`)}function No(){if(k.modelPlacementEventsBound)return;k.modelPlacementEventsBound=!0;let e=document.getElementById(`camerafeed`);e?.addEventListener(`pointerdown`,e=>bs(e.clientX,e.clientY)),e?.addEventListener(`pointerup`,xs),e?.addEventListener(`pointermove`,xs),document.addEventListener(`touchend`,e=>{if(!k.pendingModelToPlace||Io(e.target))return;let t=e.changedTouches[0];t&&Po(t.clientX,t.clientY,e)},{passive:!0,capture:!0}),document.addEventListener(`pointerup`,e=>{e.pointerType!==`touch`&&(!k.pendingModelToPlace||Io(e.target)||Po(e.clientX,e.clientY,e))},!0)}async function Po(e,t,n=null){if(!k.pendingModelToPlace)return;let r=performance.now(),i=n?.pointerId??n?.changedTouches?.[0]?.identifier??n?.detail?.pointerId??++_o,a=`${Math.round(e)}:${Math.round(t)}:${n?.type||`auto`}:${i}`;if(r-uo<350&&a===fo)return;uo=r,fo=a;let o=k.pendingModelToPlace,s=Lo(e/innerWidth,t/innerHeight);k.pendingModelToPlace=``,delete document.body.dataset.jarvisPendingModel,Rs(!1),mo++,window.clearTimeout(po),po=0;try{await Ro(o,s.position,s.rotation)}catch(e){T(e.message,`Model Placement Failed`)}}function Fo(e){k.pendingModelToPlace=e,document.body.dataset.jarvisPendingModel=e,Rs(!0),E(`Tap a detected surface to place ${e}. Auto-place will use the center hit-test if no tap arrives.`,`Model Armed`),window.clearTimeout(po),po=0;let t=++mo;po=window.setTimeout(()=>{k.pendingModelToPlace===e&&mo===t&&Po(innerWidth/2,innerHeight*.56)},900)}function Io(e){return!!e?.closest?.(`.ar-panel, .hud-toolbar, button, input, select, textarea, iframe`)}function Lo(e,t){try{let n=globalThis.XR8?.XrController?.hitTest?.(e,t,[`FEATURE_POINT`,`ESTIMATED_SURFACE`,`DETECTED_SURFACE`]);if(n&&n.length>0)return n[0]}catch{}let{camera:n}=z(),r=new Ne(e*2-1,-(t*2-1)),i=new Re;i.setFromCamera(r,n);let a=(k.floorY-i.ray.origin.y)/i.ray.direction.y;return{position:Number.isFinite(a)&&a>0?i.ray.origin.clone().add(i.ray.direction.clone().multiplyScalar(a)):i.ray.origin.clone().add(i.ray.direction.clone().multiplyScalar(2)),rotation:new C}}async function Ro(e,t,n){O(`Loading ${e}...`,55);try{let r=jn(e),i=await Ho(r,(t,n)=>{n&&O(`Loading ${e}... ${Math.round(t/n*100)}%`,55+Math.round(t/n*30))});return Br(i,B({name:e,kit:Ws(e)})),Vo(i,e,t,n,r),nt(),i}catch(r){T(`Remote GLB failed for ${e}: ${r.message}. Generated fallback spawned instead.`,`Model Fallback`);let i=os(e);return Br(i,B({name:e,kit:Ws(e)})),Vo(i,e,t,n,``),nt(),i}}function zo(e,t=`Custom Model`){let n=Lo(.5,.55);Vo(e,t,n.position,n.rotation,``)}function Bo(e){let t=.28,n=k.placedObjects||[];if(!n.length)return e;let r=0,i=()=>n.some(n=>(n.getWorldPosition?n.getWorldPosition(new w):n.position).distanceTo(e)<t);for(;i()&&r<24;){r++;let n=r*2.399963,i=t*(1+Math.floor(r/8))*Math.sqrt(r%8+1)*.6;e.x+=Math.cos(n)*i*.35,e.z+=Math.sin(n)*i*.35}return e}function Vo(e,t,n,r,i){let{scene:a}=z();e.position.copy(Bo(zs(n).clone())),r?.isQuaternion?e.quaternion.copy(r):r&&e.quaternion.set(r.x||0,r.y||0,r.z||0,r.w||1),is(e),e.userData.id=e.userData.id||gr(`model`),e.userData.modelName=t,e.userData.sourceURL=i,e.userData.isARObject=!0,!e.userData.modelForge&&!e.userData.modelForgeBlueprint&&Br(e,B({name:t,kit:Ws(t)})),e.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0)});let o=e.scale.clone();return e.userData.finalScale=o.toArray(),e.scale.setScalar(.001),a.add(e),k.placedObjects.push(e),us(e),Mi(e),as(e,o,()=>{e.userData.finalScale=o.toArray(),ps(),Ni(e,`place`)}),document.body.dataset.jarvisObjects=String(k.placedObjects.length),document.body.dataset.jarvisLastModel=t,R(`upsertObject`,e.userData.id,i||`model`,t,e.position.x,e.position.y,e.position.z),j(`object-placed`,{object:e,modelName:t}),e}function Ho(e,t){eo();let n=ts(e),r=ao.get(n);if(r?.template)return Promise.resolve(Uo(r));if(r?.promise)return r.promise.then(e=>Uo(e));let i={key:n,url:e,template:null,promise:null,refCount:0,bytes:0,lastUsed:ns(),loading:!0};return i.promise=new Promise((r,a)=>{no.load(e,e=>{i.template=Sr(e.scene,{targetSize:1,maxTextureSize:2048,maxAnisotropy:6}),i.animations=e.animations||[];let t=xr(i.template);i.metrics=t,i.bytes=Math.max(t.bytes||Xo(i.template),512*1024),i.lastUsed=ns(),i.loading=!1,i.promise=null,Yo(i.template,n),t.warnings.length&&j(`assistant`,`Optimized ${n} for scale and texture budget: ${t.warnings.join(`, `)}.`),oo+=i.bytes,r(i)},e=>t?.(e.loaded,e.total),e=>{ao.delete(n),i.loading=!1,i.promise=null,a(e)})}),ao.set(n,i),i.promise.then(e=>Uo(e))}function Uo(e){e.refCount+=1,e.lastUsed=ns();let t=Ae(e.template);return t.userData.assetCacheKey=e.key,t.userData.assetCacheShared=!0,t.userData.assetCacheBytes=e.bytes,Yo(t,e.key),qo(),t}function Wo(e){let t=e?.userData?.assetCacheKey,n=t?ao.get(t):null,r=n?.template?Uo(n):e.clone(!0);return r.position.copy(e.position),r.quaternion.copy(e.quaternion),r.scale.copy(e.scale),r.name=e.name,r.visible=e.visible,r.userData={...rs(e.userData),assetCacheKey:r.userData.assetCacheKey,assetCacheShared:r.userData.assetCacheShared,assetCacheBytes:r.userData.assetCacheBytes},delete r.userData.shadow,r.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0)}),r}function Go(e){let t=e?.userData?.assetCacheKey;if(!t)return!1;let n=ao.get(t);return n?(n.refCount=Math.max(0,n.refCount-1),n.lastUsed=ns(),qo(),!0):!0}function Ko(e){jt(e,{disposeSharedAssets:!Go(e)})}function qo(e=!1){let t=[...ao.values()].filter(e=>e.template&&!e.loading&&e.refCount===0).sort((e,t)=>e.lastUsed-t.lastUsed);for(;t.length&&(e||ao.size>ro||oo>io);)Jo(t.shift())}function Jo(e){!e||e.refCount>0||(ao.delete(e.key),oo=Math.max(0,oo-e.bytes),e.template&&jt(e.template,{disposeSharedAssets:!0}),e.template=null)}function Yo(e,t){e.userData.sharedAssetKey=t,e.traverse(e=>{e.userData.sharedAssetKey=t,e.geometry&&(e.geometry.userData=e.geometry.userData||{},e.geometry.userData.sharedAssetKey=t),$o(e.material,e=>{e.userData=e.userData||{},e.userData.sharedAssetKey=t,es(e,e=>{e.userData=e.userData||{},e.userData.sharedAssetKey=t})})})}function Xo(e){let t=new Set,n=new Set,r=new Set,i=0;return e.traverse(e=>{e.geometry&&!t.has(e.geometry)&&(t.add(e.geometry),i+=Zo(e.geometry)),$o(e.material,e=>{n.has(e)||(n.add(e),i+=2048),es(e,e=>{r.has(e)||(r.add(e),i+=Qo(e))})})}),Math.max(i,512*1024)}function Zo(e){let t=0,n=e=>{e?.array?.byteLength&&(t+=e.array.byteLength)};return Object.values(e.attributes||{}).forEach(n),Object.values(e.morphAttributes||{}).forEach(e=>e.forEach(n)),n(e.index),t}function Qo(e){let t=e?.image||{};if(t.data?.byteLength)return t.data.byteLength;let n=t.width||t.videoWidth||t.naturalWidth||256,r=t.height||t.videoHeight||t.naturalHeight||256;return Math.max(1,n)*Math.max(1,r)*4}function $o(e,t){(Array.isArray(e)?e:[e]).filter(Boolean).forEach(t)}function es(e,t){let n=new Set,r=e=>{if(!(!e||typeof e!=`object`)){if(e.isTexture){n.has(e)||(n.add(e),t(e));return}if(Array.isArray(e)){e.forEach(r);return}e.value?.isTexture?r(e.value):e.constructor===Object&&Object.values(e).forEach(r)}};Object.values(e).forEach(r)}function ts(e){return String(e||``).trim()}function ns(){return typeof performance<`u`?performance.now():Date.now()}function rs(e){try{return structuredClone(e)}catch{try{return JSON.parse(JSON.stringify(e))}catch{return{...e}}}}function is(e){let t=new ve().setFromObject(e).getSize(new w).length(),n=t>0?.55/t:.35;e.scale.setScalar(Math.min(1,n))}function as(e,t,n){let r=performance.now(),i=0,a=()=>{if(!e.parent){ht(i);return}let o=Math.min((performance.now()-r)/420,1),s=o<.6?o/.6*1.1:1.1-.1*((o-.6)/.4);e.scale.copy(t).multiplyScalar(s),o<1?i=I(a):(e.scale.copy(t),n?.())};i=I(a)}function os(e){let t=new we,n=new a(new _(.28,2),new d({color:43775,emissive:21879,roughness:.25,metalness:.35,transparent:!0,opacity:.78})),r=new a(new _e(.42,.008,8,96),qa.clone());r.rotation.x=Math.PI/2;let i=ls(e);return i.position.y=.48,t.add(n,r,i),t}function ss(e,t){let n=k.selectedObject||k.placedObjects.at(-1);n&&(qr(n,e,t),ds(n),Jr(n),Ni(n,e))}function cs(e={}){let t=Gs(e.action||e.command||``),n=String(e.target||e.model||e.query||``).trim(),r=k.selectedObject||k.placedObjects.at(-1)||null;if(n){let e=n.toLowerCase();r=k.placedObjects.find(t=>{let n=String(t.userData?.modelName||``).toLowerCase(),r=t.userData?.modelForge?.parts||[];return n.includes(e)||r.some(t=>String(t.name||``).toLowerCase().includes(e))})||r}!r||!t||(Kr(r,t,e),ds(r),Jr(r),Ni(r,t))}function ls(e){let t=String(e||`Model`).trim().toLowerCase(),n=vo.get(t);if(n){let e=new pe(new De({map:n.texture,transparent:!0}));return e.scale.set(.9,.23,1),e.userData.labelCacheKey=t,e}let r=document.createElement(`canvas`);r.width=512,r.height=128;let i=r.getContext(`2d`);i.clearRect(0,0,r.width,r.height),i.fillStyle=`rgba(0,0,0,0.32)`,i.fillRect(0,0,r.width,r.height),i.fillStyle=`#fff`,i.font=`600 34px Inter, sans-serif`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(String(e).slice(0,24),256,64);let a=new We(r);a.userData=a.userData||{},a.userData.sharedAssetKey=`label:${t}`,vo.set(t,{texture:a});let o=new pe(new De({map:a,transparent:!0}));return o.scale.set(.9,.23,1),o.userData.labelCacheKey=t,o}function us(e){e.userData.shadow?.parent?.remove(e.userData.shadow);let t=new a(new o(.35,48),new x({color:0,transparent:!0,opacity:.24,depthWrite:!1}));t.rotation.x=-Math.PI/2,t.name=`jarvis-blob-shadow`,e.userData.shadow=t,ds(e),z().scene.add(t)}function ds(e){let t=e?.userData?.shadow;t&&t.position.set(e.position.x,k.floorY+.004,e.position.z)}function fs(e){return Array.isArray(e)&&e.length>=3&&e.every(e=>Number.isFinite(e)&&e>.01)}function ps(){dr(Ja,k.placedObjects.map(e=>({id:e.userData.id,modelName:e.userData.modelName,sourceURL:e.userData.sourceURL||``,sketchfab:e.userData.sketchfab||null,modelForge:e.userData.modelForge||e.userData.modelForgeBlueprint||null,position:e.position.toArray(),quaternion:e.quaternion.toArray(),scale:Array.isArray(e.userData.finalScale)?e.userData.finalScale:e.scale.toArray(),trackingMode:k.trackingMode,floorY:k.floorY,anchor:hs(e),savedAt:Date.now()})))}async function ms(){let e=ur(Ja,[]),t=[];for(let n of e)try{let e=n.sourceURL&&!n.sourceURL.startsWith(`sketchfab:`)?await Ho(n.sourceURL):os(n.modelName);e.userData.id=n.id,e.position.fromArray(n.position),e.quaternion.fromArray(n.quaternion),e.scale.fromArray(fs(n.scale)?n.scale:[.35,.35,.35]),e.userData.finalScale=e.scale.toArray(),e.userData.modelName=n.modelName,e.userData.sourceURL=n.sourceURL,e.userData.sketchfab=n.sketchfab||null,e.userData.worldAnchor=n.anchor||null,e.userData.isARObject=!0,Br(e,n.modelForge||B({name:n.modelName||`Restored Model`,kit:Ws(n.modelName)})),z().scene.add(e),k.placedObjects.push(e),us(e),Mi(e),_s(e),document.body.dataset.jarvisObjects=String(k.placedObjects.length)}catch(e){t.push(`${n.modelName||`Restored Model`}: ${e?.message||`load failed`}`);let r=os(n.modelName||`Restored Model`);r.position.fromArray(n.position||[0,k.floorY,-2]),r.scale.fromArray(fs(n.scale)?n.scale:[.35,.35,.35]),r.userData.finalScale=r.scale.toArray(),r.userData.id=n.id||gr(`model`),r.userData.modelName=n.modelName||`Restored Model`,r.userData.sourceURL=n.sourceURL||``,r.userData.sketchfab=n.sketchfab||null,r.userData.worldAnchor=n.anchor||null,r.userData.isARObject=!0,Br(r,n.modelForge||B({name:n.modelName||`Restored Model`,kit:Ws(n.modelName)})),z().scene.add(r),k.placedObjects.push(r),us(r),Mi(r),_s(r),document.body.dataset.jarvisObjects=String(k.placedObjects.length)}t.length&&E(`Some saved models failed to restore and were replaced with generated fallbacks: ${t.slice(0,3).join(`; `)}${t.length>3?` (+${t.length-3} more)`:``}`,`Model Restore`)}function hs(e){return{type:`world-point-signature-v1`,position:e.position.toArray(),quaternion:e.quaternion.toArray(),floorY:k.floorY,signature:gs(),trackingMode:k.trackingMode,createdAt:Date.now()}}function gs(){let e=k.worldPointBuffer.slice(-360);if(e.length<10)return{count:e.length,centroid:[0,k.floorY,0],floorY:k.floorY};let t=e.reduce((e,t)=>(e.x+=t.x,e.y+=t.y,e.z+=t.z,e),new w).multiplyScalar(1/e.length);return{count:e.length,centroid:t.toArray(),floorY:k.floorY}}function _s(e){e.userData.worldAnchor&&(yo.add(e),ys(e))}function vs(){yo.forEach(e=>{if(!e.parent){yo.delete(e);return}ys(e)})}function ys(e){let t=e.userData.worldAnchor;if(!t?.position)return;let n=t.signature||{},r=gs(),i=new w().fromArray(t.position);n.count>=10&&r.count>=10&&Array.isArray(n.centroid)&&(i.x+=r.centroid[0]-n.centroid[0],i.z+=r.centroid[2]-n.centroid[2]);let a=Number.isFinite(t.floorY)?t.floorY:n.floorY;Number.isFinite(a)&&Number.isFinite(r.floorY)&&(i.y+=r.floorY-a),e.position.copy(i),ds(e)}function bs(e,t){xs(),co=window.setTimeout(()=>{Ss(e,t),k.selectedObject&&Es(e,t,k.selectedObject)},500)}function xs(){window.clearTimeout(co)}function Ss(e,t){let{camera:n}=z(),r=new Re;r.setFromCamera(new Ne(e/innerWidth*2-1,-(t/innerHeight)*2+1),n);let i=r.intersectObjects(k.placedObjects,!0)[0]?.object;return k.selectedObject=i?Cs(i):null,k.selectedObject}function Cs(e){let t=e;for(;t&&!t.userData.isARObject&&t.parent;)t=t.parent;return t?.userData?.isARObject?t:null}function ws(e){let t=e?.origin,n=e?.direction;if(!t||!n)return null;let r=new w(n.x,n.y,n.z);if(r.lengthSq()<1e-8)return null;r.normalize();let i=new w(t.x,t.y,t.z),a=new Re(i,r).intersectObjects(k.placedObjects,!0),o=a[0]?.object?Cs(a[0].object):null;if(o)return k.selectedObject=o,Ts(o),Ni(o,`select`),j(`gesture-pinch`,{source:`xr-transient-pointer`,object:o}),R(`status`,`Selected ${o.userData.modelName||`object`} via pinch`),{type:`select`,object:o};if(k.pendingModelToPlace){let e=Number.isFinite(k.floorY)?k.floorY:-1.5,t=Math.abs(r.y)>1e-4?(e-i.y)/r.y:-1,n=t>0&&t<40?new w(i.x+r.x*t,e,i.z+r.z*t):i.clone().add(r.clone().multiplyScalar(1.6)).setY(e),a=k.pendingModelToPlace;return k.pendingModelToPlace=``,delete document.body.dataset.jarvisPendingModel,Rs(!1),Ro(a,n,new C).catch(e=>T(e.message,`Model Placement Failed`)),{type:`place`,point:n}}return null}function Ts(e){if(!e||e.userData._xrPulsing)return;e.userData._xrPulsing=!0;let t=e.scale.clone(),n=t.clone().multiplyScalar(1.06),r=performance.now(),i=a=>{let o=Math.min(1,(a-r)/170),s=o<.5?o*2:(1-o)*2;e.scale.lerpVectors(t,n,s),o<1?I(i):(e.scale.copy(t),e.userData._xrPulsing=!1)};I(i)}function Es(e,t,n){so?.remove(),so=document.createElement(`section`),so.className=`context-menu glass-panel`,so.style.left=`${Math.min(e,innerWidth-210)}px`,so.style.top=`${Math.min(t,innerHeight-250)}px`;let r=[[`Duplicate`,()=>ks(n)],[`Delete`,()=>As(n)],[`Physics ON`,()=>js(n)],[`Open`,()=>Ds(n,`open`)],[`Close`,()=>Ds(n,`close`)],[`Toggle`,()=>Ds(n,`toggle`)],[`Shatter`,()=>Ds(n,`shatter`)],[`Forge`,()=>j(`open-model-forge`)],[`Save`,()=>ps()],[`Export .GLB`,()=>Ms(n)]];for(let[e,t]of r){let n=document.createElement(`button`);n.textContent=e,n.onclick=()=>{t(),so?.remove()},so.appendChild(n)}document.body.appendChild(so),window.setTimeout(()=>document.addEventListener(`pointerdown`,Os,{once:!0}),0)}function Ds(e,t){Kr(e,t),ds(e),Jr(e),Ni(e,t),R(`manipulateObject`,e.userData.id||``,t)}function Os(e){so?.contains(e.target)||so?.remove()}function ks(e){let t=Wo(e),n=new w(.25,.02,-.25).applyQuaternion(e.quaternion);t.position.add(n),t.userData.id=gr(`model`),t.userData.finalScale=e.userData.finalScale||t.scale.toArray(),delete t.userData.worldAnchor,(e.userData.modelForge||e.userData.modelForgeBlueprint)&&Br(t,e.userData.modelForge||e.userData.modelForgeBlueprint),z().scene.add(t),k.placedObjects.push(t),us(t),Mi(t),Ni(t,`place`),ps()}function As(e){k.placedObjects=k.placedObjects.filter(t=>t!==e),yo.delete(e),k.selectedObject===e&&(k.selectedObject=null);let t=lo.get(e.userData.id);t&&(sa(t),lo.delete(e.userData.id)),e.userData.shadow&&jt(e.userData.shadow),Ni(e,`delete`),R(`removeObject`,e.userData.id||``),Ko(e),ps()}async function js(e){if(lo.has(e.userData.id)){sa(lo.get(e.userData.id)),lo.delete(e.userData.id),E(`Physics off`,`info`);return}if(!$i()){E(`Starting physics engine…`,`info`);try{await ea()}catch(e){console.error(`[AR Models] physics engine unavailable:`,e),E(`Physics unavailable — engine failed to start`,`error`);return}}let t=aa(e.position,`dynamic`);if(!t){E(`Physics unavailable — engine failed to start`,`error`);return}oa(e,t),lo.set(e.userData.id,t),E(`Physics on`,`success`)}window.addEventListener(`ar-physics-step`,()=>{for(let e of lo.keys()){let t=k.placedObjects.find(t=>t.userData.id===e);t&&ds(t)}});async function Ms(e){let{GLTFExporter:n}=await t(async()=>{let{GLTFExporter:e}=await import(`./three-WgMhLE1J.js`).then(e=>e.r);return{GLTFExporter:e}},__vite__mapDeps([1,2]),import.meta.url),r=new n;await Ns(e),r.parse(e,t=>{let n=t instanceof ArrayBuffer?new Blob([t],{type:`model/gltf-binary`}):new Blob([JSON.stringify(t)],{type:`model/gltf+json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.userData.modelName||`jarvis-model`}.glb`,i.click(),URL.revokeObjectURL(r)},e=>T(e.message,`Export Failed`),{binary:!0})}async function Ns(e){let t=[];e.traverse(e=>{$o(e.material,e=>{es(e,e=>{t.push(e)})})}),await Promise.all(t.map(async e=>{let t=e?.image;if(t){if(t.complete===!1){await new Promise(e=>{let n=()=>e();t.addEventListener?.(`load`,n,{once:!0}),t.addEventListener?.(`error`,n,{once:!0}),window.setTimeout(n,1200)});return}if(typeof t.decode==`function`)try{await t.decode()}catch{}}}))}function Ps(){let e=document.createElement(`div`);e.style.cssText=`display: flex; flex-direction: column; gap: 8px;`;let t=document.createElement(`strong`);t.textContent=`JARVIS Stark 3D Composer`,t.style.cssText=`font-size: 14px; color: var(--accent); text-transform: uppercase;`;let n=document.createElement(`select`);_r(n,[[`primitive`,`Custom Basic Geometry`],[`arc_reactor`,`Stark Arc Reactor Core`],[`gauntlet`,`Holographic Repulsor Gauntlet`],[`thruster`,`Flight Ion Propulsion Thruster`],[`quantum_reactor`,`Quantum Core Reactor Engine`],[`faceplate`,`Cybernetic Visor Faceplate`]]);let r=document.createElement(`select`);_r(r,[[`metal`,`Machined Brushed Titanium`],[`gold`,`Polished Golden Core`],[`glass`,`Translucent Ethereal Glass`],[`glow`,`Glowing Neon Hologram`],[`matte`,`Stark Matte Composite`]]);let i=document.createElement(`div`);i.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let a=document.createElement(`span`);a.textContent=`Shape / Geometry:`,a.style.cssText=`font-size: 11px; color: var(--text-secondary);`;let o=document.createElement(`select`);_r(o,[`cube`,`sphere`,`cylinder`,`cone`,`plane`,`torus`,`ring`,`capsule`]),i.append(a,o);let s=document.createElement(`div`);s.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let c=document.createElement(`span`);c.textContent=`Visual Detail Level:`,c.style.cssText=`font-size: 11px; color: var(--text-secondary);`;let l=document.createElement(`select`);_r(l,[[`standard`,`Standard`],[`premium`,`Premium`],[`hero`,`Hero Detail`]]),s.append(c,l);let u=document.createElement(`input`);u.placeholder=`Model custom name (e.g. Mark 85 reactor)`;let d=document.createElement(`button`);d.className=`panel-action`,d.textContent=`Build Stark Composite`,d.style.cssText=`background: var(--accent); color: #fff; font-weight: 600; min-height: 42px; border-radius: 12px; margin-top: 8px;`,n.onchange=()=>{let e=n.value===`primitive`;i.style.display=e?`flex`:`none`,s.style.display=e?`flex`:`none`,u.value=e?``:n.options[n.selectedIndex].text},d.onclick=()=>{let e=n.value,t;t=e===`primitive`?Is(o.value,r.value,l.value):Fs(e,r.value);let i=u.value||`${r.options[r.selectedIndex].text} ${n.options[n.selectedIndex].text}`;t.userData.modelName=i,Br(t,B({name:i,kit:e===`primitive`?`scene`:Ws(e)})),zo(t,i);let a=ur(Ya,[]);a.push({name:i,assembly:e,material:r.value,addedAt:Date.now()}),dr(Ya,a.slice(-24)),E(`Successfully composed and placed Stark asset: ${i}.`,`3D Composer`)};let f=document.createElement(`p`);f.className=`panel-note`,f.textContent=`Stark Assemblies generate premium multi-part geometries with concentric highlights, glowing points, and kinematic hinges.`,e.append(t,n,r,i,s,u,d,f),new hn({title:`Stark 3D Composer`,body:e,icon:`B`,width:375,height:490}).focus()}function Fs(e,t){let n=new we;n.name=`stark-${e}`;let r=Ls(t===`gold`?`metal`:t);t===`gold`&&(r.color.setHex(16766720),r.roughness=.05,r.metalness=.95);let i=new x({color:54015,transparent:!0,opacity:.85}),o=new x({color:16777215,transparent:!0,opacity:.95}),c=new b({color:3815994,roughness:.6,metalness:.8});if(e===`arc_reactor`){let e=new a(new s(.18,.18,.06,32),c);e.position.y=-.03,n.add(e);let t=new a(new s(.08,.08,.08,24),i);t.position.y=.01,t.userData.partName=`reactor-core`,t.userData.partType=`light`;let l=new S(54015,3,2.5);l.position.set(0,0,0),t.add(l),n.add(t);let u=new a(new _e(.15,.018,12,48),r);u.rotation.x=Math.PI/2,n.add(u);let d=new b({color:13794605,roughness:.18,metalness:.9});for(let e=0;e<10;e++){let t=e/10*Math.PI*2,r=new a(new se(.024,.024,.018),d);r.position.set(Math.cos(t)*.15,0,Math.sin(t)*.15),r.rotation.y=-t,n.add(r)}let f=new a(new _e(.1,.005,8,48),o);f.rotation.x=Math.PI/2,f.position.y=.02,n.add(f)}else if(e===`gauntlet`){let e=new a(new s(.1,.11,.28,16,1,!0,-Math.PI/2,Math.PI),r);e.rotation.x=Math.PI/2,e.userData.partName=`wrist-guard`,e.userData.partType=`base`,n.add(e);let t=new a(new s(.018,.018,.12,12),c);t.position.set(0,.07,-.06),t.rotation.x=Math.PI/2,t.userData.partName=`laser-emitter`,t.userData.partType=`detail`;let l=new a(new Le(.012),o);l.position.y=.06,t.add(l),n.add(t);let u=new a(new Le(.025,16,16),i);u.position.set(0,.06,.08),u.userData.partName=`palm-repulsor`,u.userData.partType=`light`;let d=new S(54015,2.5,2);u.add(d),n.add(u)}else if(e===`thruster`){let e=new a(new s(.06,.11,.16,24),c);e.userData.partName=`thruster-nozzle`,e.userData.partType=`base`,n.add(e);let t=new a(new Le(.045,16,16),r);t.position.y=-.06,t.userData.partName=`thruster-core`,t.userData.partType=`light`;let i=new S(16771584,3.5,3);t.add(i),n.add(t);let o=new a(new s(.04,.005,.32,16),new x({color:16747520,transparent:!0,opacity:.65}));o.position.y=-.22,o.userData.partName=`thrust-stream`,o.userData.partType=`detail`,n.add(o)}else if(e===`quantum_reactor`){let e=new a(new s(.12,.12,.32,24),new d({color:13627391,roughness:.02,transmission:.8,transparent:!0,opacity:.3}));e.userData.partName=`quantum-capsule`,e.userData.partType=`window`,n.add(e);let t=new a(new _e(.09,.01,8,32),r);t.position.y=.05,t.rotation.x=Math.PI/2,t.userData.partName=`upper-gear`,t.userData.partType=`wheel`,n.add(t);let o=new a(new _e(.09,.01,8,32),r);o.position.y=-.05,o.rotation.x=Math.PI/2,o.userData.partName=`lower-gear`,o.userData.partType=`wheel`,n.add(o);let c=new a(new u(.04,0),i);c.userData.partName=`energy-core`,c.userData.partType=`light`;let l=new S(65450,3,2);c.add(l),n.add(c)}else if(e===`faceplate`){let e=new a(new s(.14,.14,.18,16,1,!1,-Math.PI/3,Math.PI/3*2),r);e.userData.partName=`faceplate-armour`,e.userData.partType=`base`,n.add(e);let t=new a(new se(.18,.04,.02),i);t.position.set(0,.02,.12),t.userData.partName=`visor-screen`,t.userData.partType=`screen`,n.add(t);let c=new a(new se(.035,.005,.005),o);c.position.set(-.04,.02,.13),c.userData.partName=`left-eye`,c.userData.partType=`light`,n.add(c);let l=new a(new se(.035,.005,.005),o);l.position.set(.04,.02,.13),l.userData.partName=`right-eye`,l.userData.partType=`light`,n.add(l)}return n}function Is(e,t,n=`standard`){let r=Ls(t),i={cube:()=>new se(.35,.35,.35),sphere:()=>new Le(.22,48,24),cylinder:()=>new s(.18,.18,.38,48),cone:()=>new c(.2,.42,48),plane:()=>new ae(.5,.5),torus:()=>new _e(.23,.04,16,80),ring:()=>new ke(.14,.24,64),capsule:()=>new ne(.15,.35,8,24)}[e]?.()||new se(.35,.35,.35),o=new we;o.name=`builder-${e}-${n}`;let l=new a(i,r);l.castShadow=!0,l.receiveShadow=!0,o.add(l);let u=t===`glass`?new d({color:13627391,roughness:.02,transmission:.72,transparent:!0,opacity:.34}):new x({color:51455,transparent:!0,opacity:.75}),f=new a(new _e(.27,.02,12,64),u);if(f.rotation.x=Math.PI/2,o.add(f),n===`premium`||n===`hero`){let e=new a(new Le(.09,24,16),new b({color:16777215,roughness:.25,metalness:.3}));e.position.set(0,.25,0),o.add(e)}if(n===`hero`){let e=new a(new s(.06,.1,.18,6),new d({color:10475775,roughness:.14,metalness:.6,emissive:397597}));e.position.set(0,.34,0),e.rotation.y=Math.PI/6,o.add(e);let t=new a(new _e(.33,.01,8,80),new x({color:16777215,transparent:!0,opacity:.55}));t.rotation.x=Math.PI/2,t.position.y=.02,o.add(t)}return o}function Ls(e){return e===`metal`?new d({color:9422847,roughness:.18,metalness:.9}):e===`glass`?new d({color:13627391,roughness:.04,transmission:.55,transparent:!0,opacity:.45}):e===`glow`?new x({color:51455,transparent:!0,opacity:.8}):new b({color:8109311,roughness:.55,metalness:.1})}function Rs(e){k.reticle&&(k.reticle.visible=e)}function zs(e){return e?.isVector3?e:new w(e?.x||0,e?.y??k.floorY,e?.z||-2)}function Bs(e){let t=e.toLowerCase();return t.endsWith(`.gltf`)?`model/gltf+json`:t.endsWith(`.bin`)?`application/octet-stream`:t.endsWith(`.png`)?`image/png`:t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)?`image/jpeg`:t.endsWith(`.webp`)?`image/webp`:`application/octet-stream`}function Vs(e){return decodeURIComponent(String(e||``)).replace(/\\/g,`/`).replace(/^blob:https?:\/\/[^/]+\//,``).replace(/^https?:\/\/[^/]+\//,``).replace(/^\/+/,``).replace(/^(\.\/)+/,``)}function Hs(e){let t=Number(e||0);return t?t>1024*1024?`${Math.round(t/1024/1024)}MB`:`${Math.round(t/1024)}KB`:`size unknown`}function Us(e){let t=Number(e||0);return t?t>1e6?`${(t/1e6).toFixed(1)}M`:t>1e3?`${Math.round(t/1e3)}K`:String(t):`unknown`}function Ws(e){let t=String(e||``).toLowerCase();return t.includes(`house`)||t.includes(`home`)?`house`:t.includes(`room`)||t.includes(`bedroom`)||t.includes(`kitchen`)?`room`:t.includes(`car`)||t.includes(`truck`)||t.includes(`vehicle`)?`vehicle`:t.includes(`phone`)||t.includes(`tablet`)||t.includes(`device`)?`device`:t.includes(`person`)||t.includes(`robot`)||t.includes(`character`)?`character`:`scene`}function Gs(e){let t=String(e||``).toLowerCase().trim();return t?/(^|\b)(open|unfold|expand)(\b|$)/.test(t)?`open`:/(^|\b)(close|fold|collapse)(\b|$)/.test(t)?`close`:/(^|\b)(toggle|switch)(\b|$)/.test(t)?`toggle`:/(^|\b)(rotate|spin|turn)(\b|$)/.test(t)?`rotate`:/(^|\b)(reconfigure|rebuild|transform|rearrange)(\b|$)/.test(t)?`reconfigure`:/(^|\b)(shatter|break|explode)(\b|$)/.test(t)?`shatter`:/(^|\b)(reveal|show)(\b|$)/.test(t)?`reveal`:/(^|\b)(hide)(\b|$)/.test(t)?`hide`:/(^|\b)(grab|move|drag)(\b|$)/.test(t)?`grab`:t:``}var Ks=0,qs=4,Js=8,Ys=12,Xs=16,Zs=20,Qs=5,$s=6,ec=9,tc=10,nc=13,rc=14,ic=17,ac=new Map([[Qs,$s],[ec,tc],[nc,rc],[ic,18]]),oc=[[0,1],[1,2],[2,3],[3,4],[0,5],[5,6],[6,7],[7,8],[5,9],[9,10],[10,11],[11,12],[9,13],[13,14],[14,15],[15,16],[13,17],[17,18],[18,19],[19,20],[0,17]],sc=20,cc=null,lc=null,G=null,uc=!1,dc=null,fc=0,pc=0,mc=0,hc=!1,gc=0,_c=!1,vc=null,yc=0,bc=0,xc=.55,Sc=[];function Cc(e,t){wc(),t>0?(gc=setTimeout(e,t),_c=!0):(gc=I(e),_c=!1)}function wc(){gc&&(_c?clearTimeout(gc):ht(gc),gc=0)}async function Tc(){if(lc=document.getElementById(`hand-overlay`),G=lc?.getContext(`2d`),Lc(),vc=F(window,`resize`,Lc),!globalThis.Hands)return L(`mediaPipeHands`,!1),E(`Hand gestures are still loading. You can place and move objects by touch in the meantime.`,`Hand tracking`),!1;try{return cc=new globalThis.Hands({locateFile:e=>`https://cdn.jsdelivr.net/npm/@mediapipe/hands/${e}`}),cc.setOptions({maxNumHands:2,modelComplexity:1,minDetectionConfidence:.7,minTrackingConfidence:.65,selfieMode:!1}),cc.onResults(Oc),uc=!0,L(`mediaPipeHands`,!0),Cc(Ec,0),E(`Hand tracking armed. Use palm, pinch, fist, point, and swipe gestures.`),!0}catch(e){return console.warn(`[gestures] hand tracking failed to start`,e),T(`Hand gestures aren’t available on this device. Everything else in AR still works — you can place and move objects by touch.`,`Hand tracking unavailable`),!1}}async function Ec(){if(!uc||!cc)return;let e=performance.now();try{let t=Gc();t?(e>=mc&&(mc=e+sc,await cc.send({image:t}),hc=!1),Cc(Ec,0)):(!hc&&k.trackingMode===`8thwall-slam`&&(hc=!0,E(`Waiting for XR camera pixels before enabling hand tracking.`,`Hand Tracking`)),Cc(Ec,200))}catch(e){hc||(hc=!0,E(`Hand tracking frame skipped: ${e.message}`,`Hand Tracking`)),Cc(Ec,200)}}function Dc(){uc=!1,wc(),vc?.(),vc=null;try{cc?.close?.()}catch{}cc=null,Ic(),dc=null,fc=0,pc=0,yc=0,hc=!1,mc=0,bc=0,k.gestureFrameCanvas?.remove?.(),k.gestureFrameCanvas=null,k.gestureFrameReady=!1,k.handState.hands=[],k.handState.gestures=new Map}function Oc(e){Ic();let t=(e.multiHandLandmarks||[]).map((e,t)=>kc(e,t));k.handState.hands=t,t.forEach((e,t)=>Fc(e,t));let n=Ac(t);k.handState.gestures=n;for(let[e,t]of n)j(`gesture-${e}`,t)}function kc(e,t){if(!Sc[t])return Sc[t]=e.map(e=>({x:e.x,y:e.y,z:e.z||0})),Sc[t];let n=Sc[t];for(let t=0;t<e.length;t++){let r=xc;n[t].x=n[t].x*(1-r)+e[t].x*r,n[t].y=n[t].y*(1-r)+e[t].y*r,n[t].z=(n[t].z||0)*(1-r)+(e[t].z||0)*r}return n}function Ac(e){let t=new Map;if(!e.length)return dc=null,fc=0,pc=0,yc=0,t;let n=e[0],r=zc(n[qs],n[Js]);r<.05&&t.set(`pinch`,{confidence:1-r/.05,hand:n}),Mc(n)&&t.set(`fist`,{confidence:.88,hand:n}),Nc(n)&&t.set(`open-palm`,{confidence:.9,hand:n}),Pc(n)&&t.set(`point`,{confidence:.86,hand:n,point:n[Js]});let i=jc(n);if(i&&t.set(i,{confidence:.86,hand:n}),e.length>=2){let n=Bc(e[0],e[1]);if(pc>0){let r=n-pc;Math.abs(r)>.035&&t.set(`two-hand-scale`,{confidence:.9,delta:r,distance:n,hands:e})}pc=n}else pc=0;return t}function jc(e){let t=performance.now();if(t<yc)return``;let n=e[Ks];if(!dc)return dc={x:n.x,y:n.y},``;let r=n.x-dc.x;return dc={x:n.x,y:n.y},r<-.03?--fc:r>.03?fc+=1:fc*=.5,Math.abs(fc)<.25&&(fc=0),fc=Math.max(-5,Math.min(5,fc)),fc<=-5?(fc=0,yc=t+180,dc=null,`swipe-left`):fc>=5?(fc=0,yc=t+180,dc=null,`swipe-right`):``}function Mc(e){return[Js,Ys,Xs,Zs].every((t,n)=>{let r=[Qs,ec,nc,ic][n];return Rc(e,t,r)>.58})}function Nc(e){return[Js,Ys,Xs,Zs].every((t,n)=>{let r=[Qs,ec,nc,ic][n];return Rc(e,t,r)<.32})}function Pc(e){return Rc(e,Js,Qs)<.34&&Rc(e,Ys,ec)>.52&&Rc(e,Xs,nc)>.52&&Rc(e,Zs,ic)>.52}function Fc(e){if(!G||!lc)return;let t=zc(e[qs],e[Js])<.05,n=lc.width,r=lc.height,i=Math.max(1,n/Math.max(1,innerWidth));G.lineCap=`round`,G.lineJoin=`round`,G.lineWidth=2.4*i,G.strokeStyle=t?`rgba(0,122,255,0.7)`:`rgba(255,255,255,0.5)`;for(let[t,i]of oc){let a=e[t],o=e[i];!a||!o||(G.beginPath(),G.moveTo(a.x*n,a.y*r),G.lineTo(o.x*n,o.y*r),G.stroke())}for(let a of e){let e=a.x*n,o=a.y*r,s=(t?9:6)*i,c=G.createRadialGradient(e,o,0,e,o,s);c.addColorStop(0,t?`rgba(0,122,255,0.95)`:`rgba(255,255,255,0.92)`),c.addColorStop(1,`rgba(255,255,255,0)`),G.fillStyle=c,G.beginPath(),G.arc(e,o,s,0,Math.PI*2),G.fill()}if(Nc(e)){let t=(e[Qs].x+e[ic].x)/2*n,a=(e[Qs].y+e[ic].y)/2*r;G.strokeStyle=`rgba(255,255,255,0.55)`,G.lineWidth=3*i,G.beginPath(),G.arc(t,a,(40+Math.sin(performance.now()/180)*6)*i,0,Math.PI*2),G.stroke()}}function Ic(){!G||!lc||(G.save(),G.setTransform(1,0,0,1,0,0),G.clearRect(0,0,lc.width,lc.height),G.restore())}function Lc(){if(!lc)return;let e=Math.min(devicePixelRatio||1,3);lc.width=Math.floor(innerWidth*e),lc.height=Math.floor(innerHeight*e),lc.style.width=`100vw`,lc.style.height=`100vh`,G?.setTransform(1,0,0,1,0,0)}function Rc(e,t,n){let r=e[t],i=e[n],a=e[ac.get(n)];if(!r||!i||!a)return 0;let o=Hc(a,i),s=Hc(a,r),c=Math.max(Wc(o),1e-4),l=Math.max(Wc(s),1e-4),u=Math.max(-1,Math.min(1,Uc(o,s)/(c*l)));return Math.max(0,Math.min(1,(Math.PI-Math.acos(u))/(Math.PI*.55)))}function zc(e,t){let n=e.x-t.x,r=e.y-t.y,i=(e.z||0)-(t.z||0);return Math.hypot(n,r,i)}function Bc(e,t){let n=zc(e[Ks],t[Ks]),r=Vc(e),i=Vc(t);return n*.72+zc(r,i)*.28}function Vc(e){return{x:(e[Ks].x+e[Qs].x+e[ic].x)/3,y:(e[Ks].y+e[Qs].y+e[ic].y)/3,z:((e[Ks].z||0)+(e[Qs].z||0)+(e[ic].z||0))/3}}function Hc(e,t){return{x:t.x-e.x,y:t.y-e.y,z:(t.z||0)-(e.z||0)}}function Uc(e,t){return e.x*t.x+e.y*t.y+e.z*t.z}function Wc(e){return Math.hypot(e.x,e.y,e.z)}function Gc(){if(k.cameraVideo?.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)return k.cameraVideo;if(k.gestureFrameReady&&k.gestureFrameCanvas?.width&&k.gestureFrameCanvas?.height)return k.gestureFrameCanvas;let e=performance.now();return e-bc>5e3&&(bc=e),null}function Kc(){return{name:`mediapipe-camera-frame-source`,onUpdate:({processCpuResult:e})=>{Jc(qc(e))}}}function qc(e){return e?.cameraPixelArray||e?.cameraPixels||e?.camerapixelarray||e?.pixels||e?.reality?.cameraPixelArray||e?.reality?.cameraPixels||null}function Jc(e){if(!e)return;let t=e.pixels||e.data||e.buffer||e,n=e.width||e.cols||e.columnCount||e.pixelWidth||e.imageWidth,r=e.height||e.rows||e.rowCount||e.pixelHeight||e.imageHeight;if(!t||!n||!r)return;let i=Zc(t);if(!i.length)return;let a=Yc(n,r).getContext(`2d`,{willReadFrequently:!0}),o=a.createImageData(n,r),s=Xc(i.length,n,r),c=e.rowBytes||e.stride||n*s,l=0;for(let e=0;e<r;e+=1){let t=e*c;for(let e=0;e<n;e+=1){let n=t+e*s;if(s>=4)o.data[l]=i[n],o.data[l+1]=i[n+1],o.data[l+2]=i[n+2],o.data[l+3]=i[n+3]||255;else if(s===3)o.data[l]=i[n],o.data[l+1]=i[n+1],o.data[l+2]=i[n+2],o.data[l+3]=255;else{let e=i[n];o.data[l]=e,o.data[l+1]=e,o.data[l+2]=e,o.data[l+3]=255}l+=4}}a.putImageData(o,0,0),k.gestureFrameReady=!0}function Yc(e,t){return k.gestureFrameCanvas||(k.gestureFrameCanvas=document.createElement(`canvas`),k.gestureFrameCanvas.id=`mediapipe-camera-frame`,k.gestureFrameCanvas.style.cssText=`display:none`,document.body.appendChild(k.gestureFrameCanvas)),(k.gestureFrameCanvas.width!==e||k.gestureFrameCanvas.height!==t)&&(k.gestureFrameCanvas.width=e,k.gestureFrameCanvas.height=t),k.gestureFrameCanvas}function Xc(e,t,n){let r=Math.max(1,t*n);return e>=r*4?4:e>=r*3?3:1}function Zc(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):(e instanceof ArrayBuffer,new Uint8Array(e))}var Qc=`
varying vec2 vUv;
void main() {
  vUv = uv;
  gl_Position = vec4(position.xy, 0.0, 1.0);
}`,$c=`jarvis_vr_state_v2`,el={default:{id:`default`,label:`Default`,eyeSep:.063,convergence:1.42,k1:-.22,k2:.08,chromaticAberration:.003,renderScale:.9,refreshRate:72,vignetteStrength:.12},quest:{id:`quest`,label:`Quest`,eyeSep:.064,convergence:1.38,k1:-.215,k2:.078,chromaticAberration:.0032,renderScale:.88,refreshRate:90,vignetteStrength:.1},visionos:{id:`visionos`,label:`VisionOS`,estimatedEyeSep:!0,eyeSep:.062,convergence:1.34,k1:-.205,k2:.074,chromaticAberration:.0024,renderScale:.92,refreshRate:90,vignetteStrength:.08},android:{id:`android`,label:`Android`,eyeSep:.063,convergence:1.44,k1:-.22,k2:.08,chromaticAberration:.003,renderScale:.82,refreshRate:72,vignetteStrength:.14},desktop:{id:`desktop`,label:`Desktop`,eyeSep:.065,convergence:1.5,k1:-.2,k2:.07,chromaticAberration:.0025,renderScale:.95,refreshRate:60,vignetteStrength:.18}},tl=`
uniform sampler2D tDiffuse;
uniform float k1;
uniform float k2;
uniform float rAber;
varying vec2 vUv;

vec2 barrelDistort(vec2 uv, vec2 center) {
  vec2 d = uv - center;
  float r2 = dot(d, d);
  float distortFactor = 1.0 + k1 * r2 + k2 * r2 * r2;
  return center + d * distortFactor;
}

void main() {
  bool isLeftEye = vUv.x < 0.5;
  vec2 eyeCenter = isLeftEye ? vec2(0.25, 0.5) : vec2(0.75, 0.5);
  vec2 distorted = barrelDistort(vUv, eyeCenter);
  vec2 localUV = isLeftEye
    ? vec2(distorted.x * 2.0, distorted.y)
    : vec2((distorted.x - 0.5) * 2.0, distorted.y);

  if (localUV.x < 0.0 || localUV.x > 1.0 || localUV.y < 0.0 || localUV.y > 1.0) {
    gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
    return;
  }

  float dist = length(localUV - vec2(0.5, 0.5));
  float aberration = rAber * dist * dist * 3.0;
  vec2 redUV = barrelDistort(vUv + vec2(aberration, 0.0), eyeCenter);
  vec2 greenUV = distorted;
  vec2 blueUV = barrelDistort(vUv - vec2(aberration, 0.0), eyeCenter);
  float r = texture2D(tDiffuse, redUV).r;
  float g = texture2D(tDiffuse, greenUV).g;
  float b = texture2D(tDiffuse, blueUV).b;
  gl_FragColor = vec4(r, g, b, 1.0);
}`,nl=null,K=null,rl=null,il=null,al=null,ol=new ae(2,2);function sl(e){rl||(rl=new Ce,il=new de,al=new ue({uniforms:{tDiffuse:{value:null},k1:{value:e.k1??-.22},k2:{value:e.k2??.08},rAber:{value:e.chromaticAberration??.003}},vertexShader:Qc,fragmentShader:tl,depthWrite:!1,depthTest:!1}),rl.add(new a(ol,al)))}var cl=null,ll=null,ul=null,dl=!1,fl=null,pl=null,ml=null,hl=null,gl=0,_l=new C,vl=!1,yl=null,bl=null,q=Pl(),xl=0,Sl=q.ipd,Cl=q.convergence,wl=new Te,Tl=new C,El=new C().setFromAxisAngle(new w(1,0,0),-Math.PI/2),Dl=new C,Ol=new w(0,0,1);function kl(){A(`enter-vr`,()=>Al())}async function Al(){let{renderer:e,scene:t,camera:n}=z();if(!e||!t||!n)return T(`Renderer is not ready yet. Start AR first, then enter VR.`,`VR Mode`),!1;q=Pl(),Sl=q.ipd,Cl=q.convergence;let r=qt(),i=Nl(q.lensProfileId||r.browser);k.isVRMode=!0,vl=!1,xl=performance.now(),k.runtime.permissionState=k.runtime.permissionState||`unknown`,L(`passthroughBlendProxy`,!!Jl()),L(`comfortAdaptation`,!0),L(`predictivePoseFiltering`,!0),L(`reprojectionProxy`,!0),L(`questBrowserQuirks`,r.questBrowserQuirks),L(`stereoEyeBuffers`,!0),L(`stereoFrustumCalibration`,!0),L(`refreshRateNegotiation`,!0),L(`timestampSync`,!0),L(`motionSicknessMitigation`,!0),L(`teleportLocomotion`,!0),L(`smoothLocomotionSafeguards`,!0),L(`roomBoundaryVisualization`,!0),L(`stereoUiAnchoring`,!0),L(`antiAliasEdgeProtection`,!0),L(`zFightGuard`,!0),L(`sustainedFramerateGuard`,!0),L(`orientationLockStability`,!0),L(`sensorPermissionPersistenceProxy`,!0),L(`motionComfortVignette`,!0),L(`renderScaleStability`,!0),L(`headsetCameraCalibrationProxy`,!0),L(`deviceCapabilityMatrix`,!0),L(`lowLightTrackingResilience`,r.limits.lowLightTrackingResilience!==!1),Bl(e,i),i.estimatedEyeSep&&E(`VisionOS IPD is estimated because the browser does not expose a reliable eye distance API. Use the IPD slider to fine-tune comfort.`,`VR Mode`),Pt({renderer:e,scene:t,camera:n},{mode:`vr-shell`,stereo:!0,source:Jl(),passthroughBlend:`browser-camera`,framebufferScaleFactor:i.renderScale,refreshRate:i.refreshRate,convergence:i.convergence,renderScale:i.renderScale,lensProfile:i.id,motionComfort:q.seatedMode?`seated`:`standing`,vignetteStrength:i.vignetteStrength}),Ll(i),zl(i),await Hl(n),await Ul();try{await screen.orientation?.lock?.(`landscape`)}catch{E(`Landscape lock was not allowed by this browser. Rotate the phone manually for VR.`)}let a=Jl();return a&&!ll?(ll=Gl(a),t.add(ll)):a||E(`VR passthrough is waiting for camera pixels. Stay in AR mode until the camera frame source is ready.`,`VR Mode`),Kl(),!dl&&globalThis.XR8?.addCameraPipelineModule?(globalThis.XR8.addCameraPipelineModule({name:`vr-stereo-renderer`,onRender:()=>{k.isVRMode&&Vl()}}),k.pipelineOrder.push(`vr-stereo-renderer`),dl=!0):globalThis.XR8?.addCameraPipelineModule||Yl(),E(`VR screen active. ${i.label} stereo profile, IPD, refresh, and gyro are enabled.`,`VR Mode`),!0}function jl(){k.isVRMode=!1,vl=!1,Fl(),ql();try{screen.orientation?.unlock?.()}catch{}E(`Returned to AR mode.`,`VR Mode`)}function Ml(e,t,n){return Math.min(n,Math.max(t,Number(e)||t))}function Nl(e=``){let t=String(e||``).toLowerCase();return t.includes(`quest`)?el.quest:t.includes(`vision`)?el.visionos:t.includes(`android`)?el.android:t.includes(`desktop`)?el.desktop:el.default}function Pl(){let e={ipd:.063,convergence:1.42,renderScale:.9,refreshRate:72,seatedMode:!0,floorCalibration:0,lensProfileId:`default`,vignette:.12};try{let t=ur($c,null);return!t||typeof t!=`object`?e:{...e,...t,ipd:Ml(t.ipd,.045,.075),convergence:Ml(t.convergence,.8,2.2),renderScale:Ml(t.renderScale,.72,1.25),refreshRate:Ml(t.refreshRate,60,120),floorCalibration:Ml(t.floorCalibration,-1.5,1.5),vignette:Ml(t.vignette,0,.4),seatedMode:t.seatedMode!==!1,lensProfileId:String(t.lensProfileId||`default`)}}catch{return e}}function Fl(){try{dr($c,{ipd:parseFloat(fr(`jarvis_vr_ipd`,String(q.ipd||.063))),convergence:parseFloat(fr(`jarvis_vr_convergence`,String(q.convergence||1.42))),renderScale:q.renderScale,refreshRate:q.refreshRate,seatedMode:q.seatedMode,floorCalibration:q.floorCalibration,lensProfileId:q.lensProfileId,vignette:q.vignette,savedAt:new Date().toISOString()})}catch{}}function Il(){return document.getElementById(`ui-layer`)||document.body}function Ll(e){yl?.remove(),yl=document.createElement(`div`),yl.style.cssText=[`position:absolute`,`inset:0`,`z-index:25`,`pointer-events:none`,`background:radial-gradient(circle at center, rgba(0,0,0,0) 0%, rgba(0,0,0,0.14) 58%, rgba(0,0,0,0.32) 100%)`,`opacity:${Ml(e.vignetteStrength??.12,0,.5)}`,`transition:opacity 180ms linear`].join(`;`),Il().appendChild(yl)}function Rl(e,t){if(!yl)return;let n=q.seatedMode?.06:.1,r=Math.min(.24,Math.max(0,(e-16.6)/120)),i=Ml((t.vignetteStrength??.12)+n+r,.06,.45);yl.style.opacity=String(i)}function zl(e){bl?.remove(),bl=document.createElement(`div`),bl.style.cssText=[`position:absolute`,`right:16px`,`top:18px`,`z-index:30`,`display:flex`,`flex-direction:column`,`gap:8px`,`padding:10px`,`border-radius:12px`,`background:rgba(3,12,20,0.72)`,`border:1px solid rgba(0,212,255,0.22)`,`backdrop-filter:blur(14px)`,`color:white`,`font:600 11px/1.2 Inter,sans-serif`,`pointer-events:auto`,`min-width:220px`].join(`;`);let t=(e,t)=>{let n=document.createElement(`label`);n.style.cssText=`display:flex;justify-content:space-between;align-items:center;gap:8px`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n},n=document.createElement(`input`);n.type=`range`,n.min=`0.045`,n.max=`0.075`,n.step=`0.001`,n.value=String(Sl??e.eyeSep??.063),n.style.cssText=`width:112px`;let r=document.createElement(`input`);r.type=`range`,r.min=`0.8`,r.max=`2.2`,r.step=`0.01`,r.value=String(Cl??e.convergence??1.42),r.style.cssText=`width:112px`;let i=document.createElement(`input`);i.type=`range`,i.min=`0.72`,i.max=`1.25`,i.step=`0.01`,i.value=String(q.renderScale??e.renderScale??.9),i.style.cssText=`width:112px`;let a=document.createElement(`select`);for(let t of[60,72,90,120]){let n=document.createElement(`option`);n.value=String(t),n.textContent=`${t}Hz`,Number(t)===Number(q.refreshRate||e.refreshRate)&&(n.selected=!0),a.appendChild(n)}let o=document.createElement(`button`);o.className=`btn-secondary`,o.textContent=q.seatedMode?`SEATED`:`STANDING`,o.onclick=()=>{q.seatedMode=!q.seatedMode,o.textContent=q.seatedMode?`SEATED`:`STANDING`,k.compositor.motionComfort=q.seatedMode?`seated`:`standing`,Fl()};let s=document.createElement(`button`);s.className=`btn-secondary`,s.textContent=`FLOOR -`,s.onclick=()=>{q.floorCalibration=Ml(q.floorCalibration-.05,-1.5,1.5),k.compositor.floorCalibration=q.floorCalibration,Fl(),E(`Floor calibration ${q.floorCalibration.toFixed(2)}m`,`VR Mode`)};let c=document.createElement(`button`);c.className=`btn-secondary`,c.textContent=`FLOOR +`,c.onclick=()=>{q.floorCalibration=Ml(q.floorCalibration+.05,-1.5,1.5),k.compositor.floorCalibration=q.floorCalibration,Fl(),E(`Floor calibration ${q.floorCalibration.toFixed(2)}m`,`VR Mode`)};let l=document.createElement(`span`);l.textContent=`${e.label} profile`,l.style.opacity=`0.82`,n.oninput=()=>{pr(`jarvis_vr_ipd`,n.value),q.ipd=parseFloat(n.value),Sl=q.ipd,k.compositor.eyeSep=Sl},r.oninput=()=>{pr(`jarvis_vr_convergence`,r.value),q.convergence=parseFloat(r.value),Cl=q.convergence,k.compositor.convergence=Cl},i.oninput=()=>{q.renderScale=parseFloat(i.value),k.compositor.renderScale=q.renderScale,Fl()},a.onchange=()=>{q.refreshRate=parseFloat(a.value),k.compositor.refreshRate=q.refreshRate,k.compositor.frameBudgetMs=1e3/q.refreshRate,Fl()},bl.append(l,t(`IPD`,n),t(`Convergence`,r),t(`Scale`,i),t(`Refresh`,a));let u=document.createElement(`div`);u.style.cssText=`display:flex;gap:6px;justify-content:space-between`,u.append(o,s,c),bl.appendChild(u),Il().appendChild(bl)}function Bl(e,t=Nl()){let n=new Ne;e.getDrawingBufferSize(n);let r=Ml(q.renderScale??t.renderScale??1,.72,1.25),i=Math.max(2,Math.floor(n.x*r)),a=Math.max(2,Math.floor(n.y*r)),o=Math.max(2,Math.floor(i/2))/Math.max(1,a);nl=nl||new Be,nl.eyeSep=Sl||t.eyeSep||.063,nl.focus=Cl||t.convergence||1.4,(!K||K.width!==i||K.height!==a)&&(K?.dispose(),K=new ye(i,a,{minFilter:l,magFilter:l})),sl(t),al&&(al.uniforms.k1.value=t.k1??-.22,al.uniforms.k2.value=t.k2??.08,al.uniforms.rAber.value=t.chromaticAberration??.003),k.compositor={...k.compositor,refreshRate:t.refreshRate,frameBudgetMs:1e3/t.refreshRate,renderScale:r,convergence:nl.focus,lensProfile:t.id,eyeAspect:o,vignetteStrength:t.vignetteStrength,motionComfort:q.seatedMode?`seated`:`standing`,floorCalibration:q.floorCalibration},!ml&&e?.domElement&&(ml=e=>{e.preventDefault?.(),E(`WebGL context was lost. VR will pause until the renderer restores.`,`VR Mode`),k.isVRMode=!1,gl&&ht(gl),gl=0,nl=null,K=null,rl=null,il=null,al=null},hl=()=>{E(`WebGL context restored. Returning to VR mode.`,`VR Mode`),k.started&&(k.isVRMode=!0,Bl(e,t),Yl())},e.domElement.addEventListener(`webglcontextlost`,ml,{passive:!1}),e.domElement.addEventListener(`webglcontextrestored`,hl))}function Vl(){let{renderer:e,scene:t,camera:n}=z();if(!e||!t||!n||!K||!nl)return;let r=new Ne;e.getDrawingBufferSize(r);let i=Nl(q.lensProfileId),a=Ml(q.renderScale??i.renderScale??1,.72,1.25),o=Math.max(2,Math.floor(r.x*a)),s=Math.max(2,Math.floor(r.y*a)),c=Math.max(2,Math.floor(o/2)),l=c/Math.max(1,s);(K.width!==o||K.height!==s)&&Bl(e,i);let u=n.aspect;n.aspect=l,n.updateProjectionMatrix(),nl.eyeSep=Sl||i.eyeSep||.063,nl.focus=Cl||i.convergence||1.4,nl.update(n),e.setRenderTarget(K),e.setScissorTest(!0),e.clear(!0,!0,!0),ul?.userData?.liveCanvas&&(ul.needsUpdate=!0),e.setViewport(0,0,c,s),e.setScissor(0,0,c,s),e.render(t,nl.cameraL),e.clearDepth(),e.setViewport(c,0,c,s),e.setScissor(c,0,c,s),e.render(t,nl.cameraR),e.setScissorTest(!1),e.setRenderTarget(null),e.setViewport(0,0,r.x,r.y),al.uniforms.tDiffuse.value=K.texture,e.render(rl,il),n.aspect=u,n.updateProjectionMatrix();let d=performance.now(),f=xl?d-xl:16.6;xl=d,Ft(f),Rl(f,i)}async function Hl(e){qt();try{if(typeof DeviceOrientationEvent<`u`&&typeof DeviceOrientationEvent.requestPermission==`function`){let e=await DeviceOrientationEvent.requestPermission();if(e!==`granted`)return pr(`jarvis_vr_motion_permission`,String(e||`denied`)),E(`Motion access denied or timed out. VR head tracking disabled.`),!1;pr(`jarvis_vr_motion_permission`,`granted`)}return fl&&window.removeEventListener(`deviceorientation`,fl),fl=t=>Wl(t,e),window.addEventListener(`deviceorientation`,fl),!0}catch(e){return T(e.message,`Motion Permission Failed`),!1}}async function Ul(){try{if(document.fullscreenElement)return!0;if(!document.documentElement?.requestFullscreen)return!1;let e=document.documentElement.requestFullscreen({navigationUI:`hide`}).catch(()=>!1);return await Promise.race([e,new Promise(e=>setTimeout(()=>e(!1),qt().isQuest?1e3:1500))]),pl||(pl=()=>{!document.fullscreenElement&&k.isVRMode&&E(`Fullscreen exited. VR view will remain in-browser.`,`VR Mode`)},document.addEventListener(`fullscreenchange`,pl),document.addEventListener(`webkitfullscreenchange`,pl)),L(`orientationLockStability`,!0),!0}catch{return E(`Fullscreen lock was not granted. VR continues in browser windowed mode.`,`VR Mode`),!1}}function Wl(e,t){if(!k.isVRMode||!t)return;let n=y.degToRad(e.alpha||0),r=y.degToRad(e.beta||0),i=y.degToRad(e.gamma||0),a=Number(screen.orientation?.angle||window.orientation||0);wl.set(r,n,-i,`YXZ`),Tl.setFromEuler(wl),Tl.multiply(El),Dl.setFromAxisAngle(Ol,-y.degToRad(a)),Tl.multiply(Dl),vl?_l.slerp(Tl,.18):(_l.copy(Tl),vl=!0),t.quaternion.copy(_l)}function Gl(e){let t=e.tagName===`VIDEO`,n=t?new xe(e):new We(e);n.minFilter=l,n.magFilter=l,n.userData.liveCanvas=!t,ul=n;let r=new Le(500,60,40);return r.scale(-1,1,1),new a(r,new x({map:n}))}function Kl(){cl?.remove(),cl=document.createElement(`button`),cl.textContent=`EXIT VR`,cl.className=`btn-primary`,cl.style.cssText=`position:absolute;top:20px;left:20px;z-index:30;background:var(--destructive);padding-top:calc(12px + env(safe-area-inset-top));pointer-events:auto`,cl.onclick=jl(document.getElementById(`ui-layer`)||document.body).appendChild(cl);let e=document.createElement(`input`);e.type=`range`,e.min=`0.045`,e.max=`0.075`,e.step=`0.001`,e.value=String(Sl||.063),e.style.cssText=`width:168px;pointer-events:auto`;let t=document.createElement(`label`);t.dataset.vrControl=`ipd`,t.style.cssText=`position:absolute;right:18px;bottom:20px;z-index:30;display:flex;flex-direction:column;gap:6px;color:white;font:600 12px/1.2 Inter,sans-serif;text-shadow:0 1px 4px #000;pointer-events:auto`;let n=document.createElement(`span`);n.textContent=`${Math.round(parseFloat(e.value)*1e3)} mm IPD`,e.oninput=()=>{pr(`jarvis_vr_ipd`,e.value),Sl=parseFloat(e.value),n.textContent=`${Math.round(parseFloat(e.value)*1e3)} mm IPD`},t.append(n,e)(document.getElementById(`ui-layer`)||document.body).appendChild(t),cl.addEventListener(`click`,()=>t.remove(),{once:!0})}function ql(){try{let e=k.xrSession;if(e?.end){let t=e.end();t?.catch&&t.catch(()=>{})}}catch{}cl?.remove(),document.querySelector(`[data-vr-control="ipd"]`)?.remove(),bl?.remove(),yl?.remove(),bl=null,yl=null,fl&&(window.removeEventListener(`deviceorientation`,fl),fl=null),pl&&(document.removeEventListener(`fullscreenchange`,pl),document.removeEventListener(`webkitfullscreenchange`,pl),pl=null),ml&&(z()?.renderer?.domElement?.removeEventListener?.(`webglcontextlost`,ml),ml=null),hl&&(z()?.renderer?.domElement?.removeEventListener?.(`webglcontextrestored`,hl),hl=null),gl&&(ht(gl),gl=0),K&&(K.dispose(),K=null),ul?.dispose&&ul.dispose(),ul=null,ll?.geometry?.dispose?.(),ll?.material?.dispose?.(),ll?.remove?.(),ll=null,al?.dispose?.(),al=null,rl=null,il=null,nl=null}function Jl(){if(k.cameraVideo?.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)return k.cameraVideo;if(k.gestureFrameReady&&k.gestureFrameCanvas?.width&&k.gestureFrameCanvas?.height)return k.gestureFrameCanvas;let e=document.getElementById(`camerafeed`);return e?.width&&e?.height?e:null}function Yl(){if(gl)return;let e=()=>{if(!k.isVRMode){gl=0;return}Vl(),gl=I(e)};gl=I(e)}var Xl=2e4,Zl=0,Ql=[`flat`,`180`,`360`,`fisheye`],$l=[`mono`,`sbs-full`,`sbs-half`,`tb-full`,`tb-half`],eu={passthrough:{id:`passthrough`,label:`Passthrough`,room:null,hFov:32,distance:3.2,curvatureRadius:0,reverb:{seconds:.35,decay:3.2,wet:.06},note:`The real room stays visible; the picture is composited into it as a screen.`},mixed:{id:`mixed`,label:`Mixed reality`,room:`frame`,hFov:36,distance:3.4,curvatureRadius:0,reverb:{seconds:.45,decay:3,wet:.1},note:`Passthrough plus a virtual bezel and ambient light response.`},theater:{id:`theater`,label:`Theater`,room:`hall`,hFov:36,distance:8,curvatureRadius:25,scale:{width:16,depth:22,height:8.5},reverb:{seconds:1.4,decay:2.4,wet:.18},note:`A standard cinema hall — 36 degrees subtended from the seat, gently curved.`},pvr:{id:`pvr`,label:`PVR`,room:`hall`,hFov:34,distance:9,curvatureRadius:30,scale:{width:15,depth:24,height:8},reverb:{seconds:1.2,decay:2.6,wet:.15},note:`A mainstream multiplex auditorium — slightly further back, flatter screen.`},inox:{id:`inox`,label:`INOX`,room:`hall`,hFov:40,distance:8.5,curvatureRadius:22,scale:{width:18,depth:23,height:9.5},reverb:{seconds:1.6,decay:2.3,wet:.2},note:`A premium large-screen auditorium, sitting between Theater and IMAX in scale.`},imax:{id:`imax`,label:`IMAX`,room:`dome`,hFov:70,distance:7,curvatureRadius:null,curvatureRadiusFactor:1.5,scale:{width:24,depth:20,height:16},reverb:{seconds:2.2,decay:1.9,wet:.26},note:`Large-format geometry — 70 degrees subtended, curvature radius 1.5x screen width.`}},tu=`
varying vec2 vUv;
varying vec3 vDir;
void main() {
  vUv = uv;
  vDir = normalize(position);
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}`,nu=`
uniform sampler2D uMap;
uniform vec2 uUvScale;
uniform vec2 uUvOffset;
uniform int uProjectionKind;
uniform float uFisheyeFov;
uniform vec2 uFisheyeCenter;
uniform vec2 uFisheyeRadius;
uniform float uOpacity;
varying vec2 vUv;
varying vec3 vDir;

void main() {
  vec2 uv;
  if (uProjectionKind == 1) {
    vec3 d = normalize(vDir);
    float theta = acos(clamp(-d.z, -1.0, 1.0));
    // Deliberately NOT named "half": that is a reserved word in GLSL ES, and
    // using it makes the whole shader fail to compile, which silently blanks
    // every projection - not just fisheye - because this is one shared program.
    // Found by running it live; no JS-side syntax check can see inside a shader.
    float halfFov = max(uFisheyeFov * 0.5, 0.0001);
    float rNorm = theta / halfFov;
    if (rNorm > 1.0) {
      gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
      return;
    }
    float phi = atan(d.y, d.x);
    uv = uFisheyeCenter + rNorm * uFisheyeRadius * vec2(cos(phi), sin(phi));
  } else {
    uv = vUv;
  }
  uv = uv * uUvScale + uUvOffset;
  gl_FragColor = vec4(texture2D(uMap, uv).rgb, uOpacity);
  #include <colorspace_fragment>
}`,J={active:!1,file:null,element:null,isVideo:!1,sourceWidth:0,sourceHeight:0,texture:null,projection:`flat`,projectionAuto:!0,packing:`mono`,packingAuto:!0,environment:`theater`,meshes:[],room:null,group:null,screen:{width:0,height:0,distance:0,elevation:0,curvatureRadius:0},quality:null,audio:null,ambient:null,loop:0,deviceLimits:null,findings:[]};function ru(){let{renderer:e}=z(),t=e?.getContext?.()||null,n=t?t.getParameter(t.MAX_TEXTURE_SIZE):0,r=typeof globalThis.VideoDecoder==`function`,i=typeof globalThis.XRMediaBinding==`function`,a=typeof HTMLVideoElement<`u`&&typeof HTMLVideoElement.prototype?.requestVideoFrameCallback==`function`,o={maxTextureSize:n,webCodecs:r,webxrMediaLayers:i,webxrGLBinding:typeof globalThis.XRWebGLBinding==`function`,requestVideoFrameCallback:a,webAudio:typeof globalThis.AudioContext==`function`||typeof globalThis.webkitAudioContext==`function`,xr:!!navigator.xr};return J.deviceLimits=o,L(`mediaViewerMaxTextureSize`,n),L(`mediaViewerWebCodecs`,r),L(`mediaViewerWebXRMediaLayers`,i),o}function iu(e,t,n=``){let r=String(n).toLowerCase();if(/(^|[^a-z])fisheye|dualfish|_fish/.test(r))return{value:`fisheye`,why:`filename says fisheye`};if(/vr180|_180|180deg|180x180/.test(r))return{value:`180`,why:`filename says 180`};if(/vr360|_360|360deg|equirect|spherical|insta360|theta/.test(r))return{value:`360`,why:`filename says 360`};if(!e||!t)return{value:`flat`,why:`no dimensions available yet`};let i=e/t;return Math.abs(i-2)<.02?{value:`360`,why:`${e}x${t} is 2:1 equirectangular`}:Math.abs(i-4)<.06?{value:`180`,why:`${e}x${t} is 4:1 — two 1:1 hemispheres`}:Math.abs(i-1)<.02?{value:`fisheye`,why:`${e}x${t} is square — likely a fisheye circle`}:{value:`flat`,why:`${e}x${t} (${i.toFixed(2)}:1) is an ordinary frame`}}function au(e){return e===`180`?1:e===`360`?2:e===`fisheye`?1:16/9}function ou(e,t,n=``,r=`flat`){let i=String(n).toLowerCase(),a=au(r),o=(e,t)=>Math.abs(e-t)/t<.12;if(/_?(sbs|side.?by.?side|lr|left.?right)/.test(i)){let n=e/2/t;return o(n,a)?{value:`sbs-full`,why:`side-by-side, each eye ${Math.round(e/2)}x${t} at its full aspect`}:o(n*2,a)?{value:`sbs-half`,why:`side-by-side, each eye squeezed to ${Math.round(e/2)}x${t}`}:{value:`sbs-full`,why:`filename says side-by-side; aspect matched neither full nor half, assuming full`}}if(/_?(tb|ou|top.?bottom|over.?under)/.test(i)){let n=e/(t/2);return o(n,a)?{value:`tb-full`,why:`top-bottom, each eye ${e}x${Math.round(t/2)} at its full aspect`}:o(n/2,a)?{value:`tb-half`,why:`top-bottom, each eye squeezed to ${e}x${Math.round(t/2)}`}:{value:`tb-full`,why:`filename says top-bottom; aspect matched neither full nor half, assuming full`}}if(/_?mono/.test(i))return{value:`mono`,why:`filename says mono`};if(!e||!t)return{value:`mono`,why:`no dimensions available yet`};let s=e/t;return r===`180`&&Math.abs(s-4)<.06?{value:`sbs-full`,why:`4:1 on a 180 source is two full-width eyes`}:r===`360`&&Math.abs(s-1)<.02?{value:`tb-full`,why:`1:1 on a 360 source is two stacked equirect eyes`}:{value:`mono`,why:`no stereo signal in the dimensions or the filename`}}function su(e,t){let n=t===`right`;switch(e){case`sbs-full`:case`sbs-half`:return{scale:[.5,1],offset:[n?.5:0,0]};case`tb-full`:case`tb-half`:return{scale:[1,.5],offset:[0,n?0:.5]};default:return{scale:[1,1],offset:[0,0]}}}function cu(e,t,n){switch(n){case`sbs-full`:return{width:e/2,height:t,squeezed:!1};case`sbs-half`:return{width:e/2,height:t,squeezed:!0,displayAspect:e/2/t*2};case`tb-full`:return{width:e,height:t/2,squeezed:!1};case`tb-half`:return{width:e,height:t/2,squeezed:!0,displayAspect:e/(t/2)/2};default:return{width:e,height:t,squeezed:!1}}}function lu({width:e,height:t,curvatureRadius:n=0,segments:r=96}){if(!n||n<=0)return new ae(e,t,1,1);let a=e/n,o=[],s=[],c=[];for(let e=0;e<=r;e+=1){let i=e/r,c=(i-.5)*a,l=n*Math.sin(c),u=n*(1-Math.cos(c));o.push(l,t/2,u,l,-t/2,u),s.push(i,1,i,0)}for(let e=0;e<r;e+=1){let t=e*2;c.push(t,t+1,t+2,t+1,t+3,t+2)}let l=new Ge;return l.setAttribute(`position`,new i(o,3)),l.setAttribute(`uv`,new i(s,2)),l.setIndex(c),l.computeVertexNormals(),l.userData.arcDegrees=y.radToDeg(a),l}function uu(e,t){switch(e){case`360`:{let e=new Le(480,96,56);return e.scale(-1,1,1),e}case`180`:case`fisheye`:{let e=new Le(480,96,56,Math.PI,Math.PI,0,Math.PI);return e.scale(-1,1,1),e}default:return lu(t)}}function du(e,t,n,r,i){let a=su(n,r);return new ue({uniforms:{uMap:{value:e},uUvScale:{value:new Ne(a.scale[0],a.scale[1])},uUvOffset:{value:new Ne(a.offset[0],a.offset[1])},uProjectionKind:{value:+(t===`fisheye`)},uFisheyeFov:{value:i?.fov??Math.PI},uFisheyeCenter:{value:new Ne(i?.cx??.5,i?.cy??.5)},uFisheyeRadius:{value:new Ne(i?.rx??.5,i?.ry??.5)},uOpacity:{value:1}},vertexShader:tu,fragmentShader:nu,side:0,depthWrite:t===`flat`,transparent:!1})}function fu(e){if(!e.room)return null;let t=new we;if(t.name=`media-room-${e.id}`,e.room===`frame`){let e=new a(new ke(.98,1.06,4,1,Math.PI/4),new x({color:58879,transparent:!0,opacity:.55}));return e.name=`media-frame`,t.add(e),t}let n=e.scale||{width:16,depth:22,height:8.5},r=new b({color:658706,roughness:.94,metalness:.02}),i=new b({color:1119516,roughness:.88,metalness:.04}),o=new a(new ae(n.width,n.depth),i);o.rotation.x=-Math.PI/2,o.position.set(0,-1.35,-n.depth/2+4),t.add(o);let s=new a(new ae(n.width,n.depth),r);s.rotation.x=Math.PI/2,s.position.set(0,n.height-1.35,-n.depth/2+4),t.add(s);let c=new a(new ae(n.width,n.height),r);c.position.set(0,n.height/2-1.35,4),c.rotation.y=Math.PI,t.add(c);for(let e of[-1,1]){let i=new a(new ae(n.depth,n.height),r);i.position.set(e*n.width/2,n.height/2-1.35,-n.depth/2+4),i.rotation.y=e>0?-Math.PI/2:Math.PI/2,t.add(i)}let l=e.room===`dome`?9:7,u=new v(new se(.52,.5,.5),new b({color:1707796,roughness:.96}),l*14),d=new Ke,f=0;for(let e=0;e<l;e+=1)for(let t=0;t<14;t+=1)d.makeTranslation((t-13/2)*.72,-1.05+e*.16,1.2+e*1.05),u.setMatrixAt(f,d),f+=1;u.instanceMatrix.needsUpdate=!0,u.name=`media-seats`,t.add(u);let p=new Me(2240580,.55);p.name=`media-room-ambient`,t.add(p);let m=new S(58879,0,40);return m.name=`media-ambilight`,m.position.set(0,1.4,-e.distance*.6),t.add(m),t}function pu(e,t,n={}){let r=eu[e]||eu.theater,i=n.distance??r.distance,a=n.hFov??r.hFov,o=n.width??2*i*Math.tan(y.degToRad(a)/2),s=o/(t||16/9),c=n.curvatureRadius;return c??(c=r.curvatureRadiusFactor?o*r.curvatureRadiusFactor:r.curvatureRadius),{width:o,height:s,distance:i,hFov:a,curvatureRadius:c,elevation:n.elevation??(e===`imax`?1.1:.6),arcDegrees:c>0?y.radToDeg(o/c):0}}async function mu(e,t={}){if(!e)throw Error(`No file given`);Nu({keepScene:!0});let n=(e.type||``).startsWith(`video/`)||/\.(mp4|webm|mov|mkv|m4v)$/i.test(e.name||``),r=URL.createObjectURL(e),i=document.createElement(n?`video`:`img`);n&&(i.playsInline=!0,i.muted=t.muted??!1,i.loop=t.loop??!0,i.crossOrigin=`anonymous`,i.preload=`auto`,i.style.cssText=`position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;left:-9999px`,document.body.appendChild(i)),await new Promise((t,a)=>{let o=!1,s=e=>(...t)=>{o||(o=!0,clearTimeout(u),e(...t))},c=s(t),l=s(()=>a(Error(`Could not decode ${e.name}. The browser reported ${i.error?`media error ${i.error.code}`:`no readable video or image stream`}.`))),u=setTimeout(s(()=>a(Error(`${e.name} did not report its dimensions within ${Xl/1e3}s. The file may be very large, or this device may not have a decoder for it.`))),Xl);i.addEventListener(n?`loadedmetadata`:`load`,c,{once:!0}),i.addEventListener(`error`,l,{once:!0}),i.src=r});let a=n?i.videoWidth:i.naturalWidth,o=n?i.videoHeight:i.naturalHeight;J.file=e,J.element=i,J.isVideo=n,J.sourceWidth=a,J.sourceHeight=o,J.objectUrl=r,J.findings=[];let s=J.deviceLimits||ru();if(s.maxTextureSize&&Math.max(a,o)>s.maxTextureSize){let e=`Device texture limit reached: this GPU's MAX_TEXTURE_SIZE is ${s.maxTextureSize}px and the source is ${a}x${o}. The frame cannot be uploaded at native resolution on this device.`;J.findings.push(e),T(e,`Device limit`)}let c=t.projection?{value:t.projection,why:`chosen by you`}:iu(a,o,e.name);J.projection=c.value,J.projectionAuto=!t.projection,J.projectionWhy=c.why;let l=t.packing?{value:t.packing,why:`chosen by you`}:ou(a,o,e.name,J.projection);if(J.packing=l.value,J.packingAuto=!t.packing,J.packingWhy=l.why,J.environment=t.environment||J.environment||`theater`,_u(),n){Tu();try{await i.play()}catch{E(`Tap play to start — this browser needs a gesture before it will play audio.`,`Media`)}ju()}return J.active=!0,j(`media-opened`,Y()),Y()}function hu(){if(J.texture&&J.texture.image===J.element)return J.texture;J.texture?.dispose&&J.texture.dispose();let e=J.isVideo?new xe(J.element):new he(J.element);return J.isVideo||(e.needsUpdate=!0),e.colorSpace=Fe,e.generateMipmaps=!1,e.minFilter=l,e.magFilter=l,e.wrapS=Ue,e.wrapT=Ue,e.userData.mediaTextureId=`tex-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,J.texture=e,e}function gu(){if(k.isVRMode)return!0;try{let{renderer:e}=z();if(e?.xr?.isPresenting)return!0}catch{}return!1}function _u(){let{scene:e}=z();if(!e)throw Error(`No scene — start AR first`);vu({keepTexture:!0});let t=hu(),n=cu(J.sourceWidth,J.sourceHeight,J.packing),r=n.displayAspect||n.width/n.height,i=pu(J.environment,r,J.screenOverride||{});J.screen=i;let o={fov:Math.PI,cx:.5,cy:.5,rx:.5,ry:.5*(n.width/n.height)};o.ry>.5&&(o.rx=.5*(n.height/n.width),o.ry=.5);let s=new we;s.name=`media-viewer`,J.group=s;let c=J.packing!==`mono`&&gu();J.stereoRendered=c;let l=c?[`left`,`right`]:[J.packing===`mono`?`mono`:`left`];J.meshes=l.map((e,n)=>{let r=new a(uu(J.projection,i),du(t,J.projection,J.packing,e,o));return r.name=`media-${J.projection}-${e}${c?``:l.length===1&&e===`left`?`-mono-view`:``}`,r.frustumCulled=!1,J.projection!==`flat`&&(r.renderOrder=-1),c&&r.layers.set(n===0?1:2),J.projection===`flat`&&r.position.set(0,i.elevation,-i.distance),s.add(r),r});let u=eu[J.environment],d=J.projection===`flat`,f=d?fu(u):null;J.roomSuppressed=!d&&!!u.room,f&&(u.room===`frame`&&(f.position.set(0,i.elevation,-i.distance-.02),f.scale.set(i.width/1.4,i.height/1.4,1)),s.add(f),J.room=f),e.add(s),L(`mediaViewerActive`,!0)}function vu({keepTexture:e=!1}={}){let{scene:t}=z();J.group&&(J.group.traverse(e=>{e.geometry?.dispose?.(),Array.isArray(e.material)?e.material.forEach(e=>e.dispose?.()):e.material?.dispose?.()}),t?.remove?.(J.group)),J.group=null,J.room=null,J.meshes=[],e||(J.texture?.dispose&&J.texture.dispose(),J.texture=null)}function yu(){let e=z()?.renderer?.xr?.getSession?.()||k.xrSession||null,t=typeof globalThis.XRMediaBinding==`function`,n=typeof globalThis.XRWebGLBinding==`function`,r=t&&typeof globalThis.XRMediaBinding.prototype?.createEquirectLayer==`function`,i=t&&typeof globalThis.XRMediaBinding.prototype?.createQuadLayer==`function`,a=t&&typeof globalThis.XRMediaBinding.prototype?.createCylinderLayer==`function`,o=!!e?.enabledFeatures?.includes?.(`layers`),s=!1,c;return e?t?o?!r&&!i?c=`XRMediaBinding exists but exposes neither createEquirectLayer nor createQuadLayer.`:s=!0:c=`The running XRSession did not enable the "layers" feature, so no layer can be created on it even though the constructor exists.`:c=`XRMediaBinding is not implemented by this browser. XRWebGLBinding alone would still require rendering into the layer ourselves, which reintroduces the resampling pass Layers exists to avoid, so it is not a substitute here.`:c=`No immersive XRSession is running. Layers only exist inside one; the shader projection path is what runs in an inline/fallback session.`,{usable:s,reason:c,hasMediaBinding:t,hasGLBinding:n,ctorEquirect:r,ctorQuad:i,ctorCylinder:a,sessionPresent:!!e,sessionEnabledFeatures:e?.enabledFeatures?[...e.enabledFeatures]:null}}async function bu(){let e=yu();if(J.layers=e,!e.usable||!J.isVideo||!J.element)return J.layers={...e,applied:!1},J.layers;try{let t=z()?.renderer,n=t?.xr?.getSession?.()||k.xrSession,r=t?.xr?.getReferenceSpace?.()||await n.requestReferenceSpace(`local`),i=new globalThis.XRMediaBinding(n),a=J.packing===`mono`?`mono`:J.packing.startsWith(`sbs`)?`stereo-left-right`:`stereo-top-bottom`,o,s;J.projection===`360`||J.projection===`180`?(o=i.createEquirectLayer(J.element,{space:r,layout:a,centralHorizontalAngle:J.projection===`180`?Math.PI:2*Math.PI}),s=`equirect`):e.ctorCylinder&&J.screen?.curvatureRadius>0?(o=i.createCylinderLayer(J.element,{space:r,layout:a,radius:J.screen.curvatureRadius,centralAngle:J.screen.width/J.screen.curvatureRadius,aspectRatio:J.screen.width/J.screen.height}),s=`cylinder`):(o=i.createQuadLayer(J.element,{space:r,layout:a,width:(J.screen?.width||2)/2,height:(J.screen?.height||1.2)/2}),s=`quad`),n.updateRenderState({layers:[o,...n.renderState.layers||[]]}),J.meshes.forEach(e=>{e.visible=!1}),J.layers={...e,applied:!0,kind:s,layout:a}}catch(t){J.layers={...e,applied:!1,reason:`Layer creation failed: ${t?.message||t}`}}return J.layers}function xu(e){if(!Ql.includes(e))throw Error(`Unknown projection ${e}`);return J.projection=e,J.projectionAuto=!1,J.element&&_u(),j(`media-changed`,Y()),Y()}function Su(e){if(!$l.includes(e))throw Error(`Unknown packing ${e}`);return J.packing=e,J.packingAuto=!1,J.element&&_u(),j(`media-changed`,Y()),Y()}function Cu(e){if(!eu[e])throw Error(`Unknown environment ${e}`);let t=J.texture,n=t?.userData?.mediaTextureId||null;J.environment=e,J.screenOverride=null,J.element&&_u();let r=J.texture;return j(`media-changed`,Y()),{...Y(),textureRebuilt:t!==r,textureIdBefore:n,textureIdAfter:r?.userData?.mediaTextureId||null}}function wu(e={}){if(J.screenOverride={...J.screenOverride||{},...e},!J.element)return Y();let t=cu(J.sourceWidth,J.sourceHeight,J.packing),n=t.displayAspect||t.width/t.height,r=pu(J.environment,n,J.screenOverride);return J.screen=r,J.projection===`flat`&&(J.meshes.forEach(e=>{e.geometry.dispose(),e.geometry=lu(r),e.position.set(0,r.elevation,-r.distance)}),J.room&&eu[J.environment].room===`frame`&&(J.room.position.set(0,r.elevation,-r.distance-.02),J.room.scale.set(r.width/1.4,r.height/1.4,1))),j(`media-changed`,Y()),Y()}function Tu(){let e=J.element;J.quality={startedAt:performance.now(),framesDelivered:0,firstMediaTime:null,lastMediaTime:null,mediaSecondsSeen:0,frameIntervals:[],elementDrops:0,elementTotal:0,rendererFrames:0,samples:0};let t=J.quality,n=()=>{if(!J.element){J.loop=0;return}if(typeof e.getVideoPlaybackQuality==`function`){let n=e.getVideoPlaybackQuality();t.elementDrops=n.droppedVideoFrames||0,t.elementTotal=n.totalVideoFrames||0}t.rendererFrames+=1,t.samples+=1,t.elapsedMs=performance.now()-t.startedAt,J.loop=I(n)};if(J.loop=I(n),typeof e.requestVideoFrameCallback==`function`){let n=null,r=(i,a)=>{if(!J.element)return;t.framesDelivered+=1;let o=a.mediaTime;if(t.firstMediaTime??(t.firstMediaTime=o),n!=null){let e=o-n;e>0&&e<1?(t.mediaSecondsSeen+=e,t.frameIntervals.length<400&&t.frameIntervals.push(e)):e<0&&(t.mediaSecondsSeen+=0)}n=o,t.lastMediaTime=o,e.requestVideoFrameCallback(r)};e.requestVideoFrameCallback(r)}}function Eu(){if(!J.quality)return null;let e=J.quality,t=(e.elapsedMs||0)/1e3,n=e.frameIntervals.slice().sort((e,t)=>e-t),r=n.length?n[Math.floor(n.length/2)]:0,i=r>0?1/r:0;return i>0&&e.mediaSecondsSeen*i,{elapsedSeconds:+t.toFixed(2),framesDelivered:e.framesDelivered,mediaSecondsPlayed:+e.mediaSecondsSeen.toFixed(2),deliveredFps:+i.toFixed(2),rendererFps:t>0?+(e.rendererFrames/t).toFixed(2):null,realtimeRatio:t>0?+(e.mediaSecondsSeen/t).toFixed(4):null,stallSeconds:t>0?+Math.max(0,t-e.mediaSecondsSeen).toFixed(2):0,elementCompositorDrops:e.elementDrops,elementCompositorTotal:e.elementTotal,elementCompositorNote:`Counts frames the offscreen <video> element itself never painted. That element is a decode source, not a displayed video, so this number is expected to be high and is not a measure of what reached the screen.`,sourceWidth:J.sourceWidth,sourceHeight:J.sourceHeight,textureWidth:J.texture?.image?.videoWidth||J.texture?.image?.naturalWidth||0,textureHeight:J.texture?.image?.videoHeight||J.texture?.image?.naturalHeight||0,mipmapsEnabled:J.texture?J.texture.generateMipmaps:null,textureId:J.texture?.userData?.mediaTextureId||null,adaptiveQualityApplied:!1}}function Du(e){if(!e)return J.ambient?.timer&&clearInterval(J.ambient.timer),J.ambient=null,!1;if(!J.isVideo||!J.group)return!1;let t=document.createElement(`canvas`);t.width=8,t.height=8;let n=t.getContext(`2d`,{willReadFrequently:!0}),r=J.group.getObjectByName(`media-ambilight`);return J.ambient={canvas:t,ctx:n,timer:setInterval(()=>{if(!(!J.element||!r))try{n.drawImage(J.element,0,0,8,8);let e=n.getImageData(0,0,8,8).data,t=0,i=0,a=0;for(let n=0;n<e.length;n+=4)t+=e[n],i+=e[n+1],a+=e[n+2];let o=e.length/4;r.color.setRGB(t/o/255,i/o/255,a/o/255),r.intensity=.9}catch{}},250)},!0}function Ou(e,t,n){let r=e.sampleRate,i=Math.max(1,Math.floor(r*t)),a=e.createBuffer(2,i,r);for(let e=0;e<2;e+=1){let t=a.getChannelData(e);for(let e=0;e<i;e+=1)t[e]=(Math.random()*2-1)*(1-e/i)**n}return a}async function ku(){try{if(!navigator.mediaDevices?.enumerateDevices)return{detected:!1,reason:`This browser exposes no device enumeration API.`};let e=(await navigator.mediaDevices.enumerateDevices()).filter(e=>e.kind===`audiooutput`),t=e.filter(e=>e.label);if(!t.length)return{detected:!1,reason:`Output device labels are withheld until microphone permission is granted, so headphone presence cannot be determined on this platform.`,outputs:e.length};let n=t.find(e=>/headphone|headset|earphone|airpod|buds|bluetooth/i.test(e.label));return{detected:!!n,label:n?.label||null,outputs:t.length}}catch(e){return{detected:!1,reason:e?.message||String(e)}}}async function Au(e,t){try{let n=e.createChannelSplitter(8);t.channelCountMode=`max`,t.channelInterpretation=`discrete`,t.connect(n);let r=[];for(let t=0;t<8;t+=1){let i=e.createAnalyser();i.fftSize=2048;try{n.connect(i,t)}catch{break}r.push(i)}let i=new Float32Array(2048),a=Array(r.length).fill(0),o=performance.now()+400;for(;performance.now()<o;){for(let e=0;e<r.length;e+=1){r[e].getFloatTimeDomainData(i);for(let t=0;t<i.length;t+=16){let n=Math.abs(i[t]);n>a[e]&&(a[e]=n)}}await new Promise(e=>setTimeout(e,40))}try{t.disconnect(n)}catch{}let s=0;return a.forEach((e,t)=>{e>1e-4&&(s=t+1)}),{channels:Math.max(s,1),peaks:a.map(e=>+e.toFixed(5)),method:`signal-probe`}}catch(e){return{channels:2,method:`fallback`,reason:e?.message||String(e)}}}async function ju(e=!1){if(!J.isVideo||!J.element)return null;let n=globalThis.AudioContext||globalThis.webkitAudioContext;if(!n)return{enabled:!1,reason:`No Web Audio API on this platform.`};let r=await ku();if(!(e||r.detected))return J.audio={enabled:!1,headphones:r,reason:`Defaulting to normal stereo output.`},J.audio;let i=J.audio?.ctx||new n;if(i.state===`suspended`)try{await i.resume()}catch{}let a=eu[J.environment],o=J.audio?.source||i.createMediaElementSource(J.element),s=J.audio?.channelProbe?.file===J.file?J.audio.channelProbe:{...await Au(i,o),file:J.file},c=s.channels;try{o.disconnect()}catch{}if(J.audio?.foa?.output)try{J.audio.foa.output.disconnect()}catch{}let l=i.createConvolver();l.buffer=Ou(i,a.reverb.seconds,a.reverb.decay);let u=i.createGain();u.gain.value=a.reverb.wet;let d=i.createGain();d.gain.value=1-a.reverb.wet*.5,d.connect(i.destination),u.connect(i.destination);let f=null,p,m,h=!1;if(c>=4)f=(await t(async()=>{let{default:e}=await import(`./omnitone.esm-BSknr-cd.js`);return{default:e}},[],import.meta.url)).default.createFOARenderer(i,{channelMap:[0,1,2,3]}),await f.initialize(),o.connect(f.input),f.output.connect(d),f.output.connect(l),h=!0,p=`Ambisonic B-format decode + HRTF binaural rendering (Omnitone FOARenderer)`,m=`True spatial audio — the captured sound field decoded as recorded, nothing synthesised.`;else{let e=new PannerNode(i,{panningModel:`HRTF`,distanceModel:`inverse`,positionX:0,positionY:J.screen.elevation||0,positionZ:-(J.screen.distance||3)});o.connect(e),e.connect(d),e.connect(l),l.connect(u),J.audio={...J.audio||{},panner:e},p=`HRTF binaural rendering (Web Audio PannerNode + ConvolverNode)`,m=`Virtual/enhanced surround — reshapes existing channels, not true object-based 3D audio.`}return l.connect(u),J.audio={...J.audio||{},enabled:!0,mechanism:p,honestLabel:m,sourceIsAmbisonic:h,channels:c,isDolbyAtmos:!1,ctx:i,source:o,convolver:l,foa:f,channelProbe:s,headphones:r,room:a.label,engine:h?`omnitone`:`web-audio-panner`},J.audio}function Mu(e){let t=J.audio;if(!t?.enabled||!t.ctx||!e)return!1;if(t.foa)return e.updateMatrixWorld?.(),t.foa.setRotationMatrix4(e.matrixWorld.elements),!0;let n=t.ctx.listener,r=new w(0,0,-1).applyQuaternion(e.quaternion),i=new w(0,1,0).applyQuaternion(e.quaternion);return n.forwardX?(n.forwardX.value=r.x,n.forwardY.value=r.y,n.forwardZ.value=r.z,n.upX.value=i.x,n.upY.value=i.y,n.upZ.value=i.z):n.setOrientation&&n.setOrientation(r.x,r.y,r.z,i.x,i.y,i.z),!0}function Y(){let e=cu(J.sourceWidth,J.sourceHeight,J.packing);return{active:J.active,fileName:J.file?.name||null,fileSize:J.file?.size||0,isVideo:J.isVideo,sourceWidth:J.sourceWidth,sourceHeight:J.sourceHeight,projection:J.projection,projectionAuto:J.projectionAuto,projectionWhy:J.projectionWhy,packing:J.packing,packingAuto:J.packingAuto,packingWhy:J.packingWhy,eyeWidth:e.width,eyeHeight:e.height,eyeSqueezed:!!e.squeezed,eyeDisplayAspect:e.displayAspect||e.width/e.height,environment:J.environment,environmentLabel:eu[J.environment]?.label,roomSuppressed:!!J.roomSuppressed,roomApplies:J.projection===`flat`,screen:J.screen,meshCount:J.meshes.length,meshNames:J.meshes.map(e=>e.name),stereoSource:J.packing!==`mono`,stereoRendered:!!J.stereoRendered,stereoPresenting:gu(),stereo:J.packing!==`mono`,ambientResponse:!!J.ambient,audio:J.audio?{enabled:J.audio.enabled,engine:J.audio.engine||null,mechanism:J.audio.mechanism||null,honestLabel:J.audio.honestLabel||null,sourceIsAmbisonic:!!J.audio.sourceIsAmbisonic,channels:J.audio.channels||null,channelPeaks:J.audio.channelProbe?.peaks||null,channelMethod:J.audio.channelProbe?.method||null,isDolbyAtmos:!1,headphones:J.audio.headphones,room:J.audio.room||null}:null,deviceLimits:J.deviceLimits,layers:J.layers||null,findings:J.findings.slice(),quality:Eu()}}function Nu({keepScene:e=!1}={}){if(J.loop&&(ht(J.loop),J.loop=0),J.ambient?.timer&&clearInterval(J.ambient.timer),J.ambient=null,J.audio?.ctx&&J.audio.ctx.state!==`closed`)try{J.audio.ctx.close()}catch{}if(J.audio=null,vu({keepTexture:!1}),J.element&&J.isVideo){try{J.element.pause()}catch{}J.element.removeAttribute(`src`),J.element.load?.(),J.element.remove?.()}return J.objectUrl&&URL.revokeObjectURL(J.objectUrl),J.objectUrl=null,J.element=null,J.file=null,J.active=!1,J.quality=null,L(`mediaViewerActive`,!1),!0}function Pu(){let e=gu(),t=()=>{let n=gu();if(n!==e&&(e=n,J.active&&J.packing!==`mono`&&J.element&&_u()),J.audio?.enabled){let e=z()?.camera;e&&Mu(e)}Zl=I(t)};Zl=I(t)}async function Fu(e,t={}){switch(e){case`open`:return j(`media-assistant-open`,t),{action:e,accepted:!0,needsPicker:!0,requested:t};case`projection`:return{action:e,state:xu(t.projection)};case`packing`:return{action:e,state:Su(t.packing)};case`environment`:return{action:e,state:Cu(t.environment)};case`adjust_screen`:return{action:e,state:wu(t)};case`spatial_audio`:{let n=await ju(!!t.enabled);return{action:e,enabled:!!n?.enabled,engine:n?.engine||null,reason:n?.reason}}case`ambient`:return{action:e,applied:Du(!!t.enabled)};case`ai_depth`:case`experimental_surround`:return{action:e,applied:!1,reason:`The ${e===`ai_depth`?`depth`:`generative surround`} model is not installed on the Space, so this control cannot do anything real yet.`};default:return{action:e,accepted:!1,reason:`Unknown media control '${e}'.`}}}function Iu(){return ru(),Pu(),A(`media:control`,e=>{let{action:t,data:n}=e?.payload||e||{};t&&Fu(t,n||{})}),A(`media-open-request`,e=>{e?.file&&mu(e.file,e.options||{}).catch(e=>{T(e?.message||String(e),`Media`)})}),gt(()=>{Zl&&ht(Zl),Zl=0,Nu()}),globalThis.JarvisMedia={open:mu,setProjection:xu,setPacking:Su,setEnvironment:Cu,adjustScreen:wu,setAmbientResponse:Du,setupSpatialAudio:ju,updateAudioOrientation:Mu,detectHeadphones:ku,getState:Y,getQualityReport:Eu,probeDecodeCapability:ru,probeLayersSupport:yu,tryMediaLayer:bu,applyAssistantControl:Fu,close:Nu,PROJECTIONS:Ql,PACKINGS:$l,ENVIRONMENTS:eu,_math:{detectProjection:iu,detectPacking:ou,eyeUvRect:su,unpackedEyeSize:cu,computeScreenDimensions:pu,buildScreenGeometry:lu}},!0}var Lu={flat:`Flat`,180:`180`,360:`360`,fisheye:`Fisheye`},Ru={mono:`Mono`,"sbs-full":`SBS full`,"sbs-half":`SBS half`,"tb-full":`Top-bottom`,"tb-half":`TB half`},zu={passthrough:`<path d="M3 7h18v11H3z"/><path d="M3 12h18"/>`,mixed:`<path d="M4 6h9v9H4z"/><path d="M11 11h9v7h-9z"/>`,theater:`<path d="M3 5h18v10H3z"/><path d="M6 19h12M8 15v4M16 15v4"/>`,imax:`<path d="M2 6c5-2.5 15-2.5 20 0v9c-5 2.5-15 2.5-20 0z"/>`,pvr:`<path d="M3 6h18v9H3z"/><path d="M7 19h10"/>`,inox:`<path d="M2.5 6h19v10h-19z"/><path d="M6 20h12"/>`},X=null,Bu=null,Vu=0,Hu=!1,Uu=!1;function Wu(e,t=``){return`<svg class="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">${e}</svg>`}function Gu(e,t,n,r,i){return t.map(t=>{let a=t===r,o=a&&i?`<span class="mv-auto">AUTO</span>`:``;return`<button type="button" class="mv-chip" data-${e}="${t}" aria-pressed="${a}">${n[t]}${o}</button>`}).join(``)}function Ku(){if(X)return X.classList.add(`mv-open`),X;let e=ru();return X=document.createElement(`section`),X.id=`media-viewer-panel`,X.className=`mv-panel glass-panel mv-open`,X.setAttribute(`role`,`dialog`),X.setAttribute(`aria-label`,`Local media viewer`),X.innerHTML=`
    <header class="mv-head">
      <div>
        <p class="mv-eyebrow">WebAR · immersive media</p>
        <h2 class="mv-title">Local media viewer</h2>
      </div>
      <button type="button" class="mv-close" data-mv="close" aria-label="Close media viewer">
        ${Wu(`<path d="M5 5l14 14M19 5L5 19"/>`)}
      </button>
    </header>

    <div class="mv-body">
      <p class="mv-cap">1 · pick a file</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <div class="mv-drop" data-mv="drop">
          ${Wu(`<path d="M12 16V4M12 4 7.5 8.5M12 4l4.5 4.5"/><path d="M3.5 15v3.2A1.8 1.8 0 0 0 5.3 20h13.4a1.8 1.8 0 0 0 1.8-1.8V15"/>`,`mv-drop-icon`)}
          <div class="mv-drop-big">Choose a photo or video</div>
          <div class="mv-drop-small">From this device. Nothing is uploaded — the file never leaves your phone.</div>
          <button type="button" class="mv-btn" data-mv="browse">Browse files</button>
        </div>
        <div class="mv-detected" data-mv="detected" hidden></div>
      </div>

      <p class="mv-cap">2 · projection format</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <p class="mv-h">Format</p>
        <p class="mv-sub">What shape the source actually is. Auto-detected from the frame's dimensions
          and the filename — override it if the guess is wrong.</p>
        <div class="mv-row" data-mv="formats"></div>
        <p class="mv-h mv-h-gap">Stereo packing</p>
        <p class="mv-sub">How two eyes are stored in one frame. Half-packed sources are un-squeezed by
          the projection geometry, never by resizing the picture.</p>
        <div class="mv-row" data-mv="packings"></div>
      </div>

      <p class="mv-cap">3 · where you watch it</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <p class="mv-h">Viewing mode</p>
        <p class="mv-sub">These change the room and the screen around the picture. They never change
          decode quality, resolution, or bitrate.</p>
        <div class="mv-modes" data-mv="modes"></div>
        <p class="mv-note" data-mv="mode-note"></p>
      </div>

      <p class="mv-cap">4 · the screen itself</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <p class="mv-h">Screen placement</p>
        <p class="mv-sub">A plan view of the room. Drag the screen's edges to resize it, drag it up or
          down to move it nearer or further. It moves live.</p>
        <div class="mv-gizmo" data-mv="gizmo">
          <div class="mv-grid"></div>
          <div class="mv-wedge" data-mv="wedge"></div>
          <svg class="mv-screen" data-mv="screen-svg" viewBox="0 0 200 34" preserveAspectRatio="none">
            <path d="M4 30 Q100 6 196 30"/>
          </svg>
          <span class="mv-handle l" data-mv="h-left"   role="slider" tabindex="0" aria-label="Screen width"></span>
          <span class="mv-handle r" data-mv="h-right"  role="slider" tabindex="0" aria-label="Screen width"></span>
          <span class="mv-handle d" data-mv="h-dist"   role="slider" tabindex="0" aria-label="Screen distance"></span>
          <span class="mv-viewer"></span>
          <span class="mv-viewer-lbl">YOU</span>
        </div>
        <div class="mv-readouts" data-mv="readouts"></div>
      </div>

      <p class="mv-cap">5 · audio and enhancements</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <div class="mv-tog">
          <div>
            <div class="mv-lab">Spatial audio</div>
            <div class="mv-hint">HRTF binaural rendering, matched to the room you're in. For headphones —
              off automatically on speakers. This is not Dolby Atmos.</div>
          </div>
          <button type="button" class="mv-sw" data-mv="sw-audio" role="switch" aria-checked="false"><i></i></button>
        </div>
        <div class="mv-tog">
          <div>
            <div class="mv-lab">Ambient light response</div>
            <div class="mv-hint">The room picks up the colour of what's on screen.</div>
          </div>
          <button type="button" class="mv-sw" data-mv="sw-ambient" role="switch" aria-checked="false"><i></i></button>
        </div>
        <div class="mv-tog">
          <div>
            <div class="mv-lab">AI 3D depth</div>
            <div class="mv-hint">Synthesises a second eye from a flat video. Real depth estimation —
              small areas behind foreground objects are filled in, not captured.</div>
          </div>
          <button type="button" class="mv-sw" data-mv="sw-depth" role="switch" aria-checked="false"><i></i></button>
        </div>
        <div class="mv-tog">
          <div>
            <div class="mv-lab">Experimental AI surround</div>
            <div class="mv-hint">Invents the parts of the scene the camera never saw, to fill a full
              sphere. Most of what you'd see is generated, not filmed.</div>
          </div>
          <button type="button" class="mv-sw warn" data-mv="sw-surround" role="switch" aria-checked="false"><i></i></button>
        </div>
      </div>

      <p class="mv-cap">6 · what you're actually getting</p>
      <div class="mv-card">
        <span class="mv-brk tr"></span><span class="mv-brk bl"></span>
        <p class="mv-h">Playback quality</p>
        <p class="mv-sub">Measured, not asserted. If this device can't carry the source, it says so here
          rather than quietly lowering the quality.</p>
        <dl class="mv-q" data-mv="quality">
          <dt>Max texture</dt><dd>${e.maxTextureSize||`unknown`} px</dd>
          <dt>WebCodecs</dt><dd>${e.webCodecs?`available`:`absent`}</dd>
          <dt>WebXR media layers</dt><dd>${e.webxrMediaLayers?`available`:`absent`}</dd>
        </dl>
      </div>
    </div>
  `,Bu=document.createElement(`input`),Bu.type=`file`,Bu.accept=`video/*,image/*`,Bu.style.cssText=`position:absolute;width:1px;height:1px;opacity:0;pointer-events:none`,X.appendChild(Bu),(document.getElementById(`ui-layer`)||document.body).appendChild(X),Ju(),id(),X}function qu(e){let t=document.getElementById(`mv-experimental-label`);if(!e){t?.remove();return}t||(t=document.createElement(`div`),t.id=`mv-experimental-label`,t.setAttribute(`role`,`status`),t.innerHTML=`${Wu(`<path d="M12 3 22 20H2z"/><path d="M12 10v4M12 17h.01"/>`)}<p>Experimental — AI-generated surround, not real footage</p>`,(document.getElementById(`ui-layer`)||document.body).appendChild(t))}function Ju(){F(X,`click`,e=>{let t=e.target.closest(`[data-mv],[data-format],[data-packing],[data-mode]`);if(t){if(t.dataset.format)return void Xu(t.dataset.format);if(t.dataset.packing)return void Zu(t.dataset.packing);if(t.dataset.mode)return void Qu(t.dataset.mode);switch(t.dataset.mv){case`close`:return sd();case`browse`:case`drop`:return Bu.click();case`sw-audio`:$u(t);return;case`sw-ambient`:ed(t);return;case`sw-depth`:td(t);return;case`sw-surround`:nd(t);return;default:return}}}),F(Bu,`change`,()=>{let e=Bu.files?.[0];e&&Yu(e)}),F(X,`dragover`,e=>{e.preventDefault()}),F(X,`drop`,e=>{e.preventDefault();let t=e.dataTransfer?.files?.[0];t&&Yu(t)}),rd(),gt(()=>sd())}async function Yu(e){try{await mu(e,{environment:Y().environment||`theater`}),id(),od(),E(`${e.name} is open.`,`Media`)}catch(e){T(e?.message||String(e),`Media`)}}function Xu(e){if(Ql.includes(e)){try{xu(e)}catch(e){T(e.message,`Media`)}id()}}function Zu(e){if($l.includes(e)){try{Su(e)}catch(e){T(e.message,`Media`)}id()}}function Qu(e){if(eu[e]){try{Cu(e)}catch(e){T(e.message,`Media`)}id()}}async function $u(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=await ju(t),r=!!n?.enabled;e.setAttribute(`aria-checked`,String(r)),t&&!r&&E(n?.headphones?.reason||`Spatial audio stays off until headphones are detected — it is built for headphone listening.`,`Spatial audio`)}function ed(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=Du(t);e.setAttribute(`aria-checked`,String(!!n)),t&&!n&&E(`Open a video first — ambient response reads the playing frame.`,`Media`)}function td(e){Uu=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),Uu&&(E(`AI 3D depth needs the depth model installed on the Space. The control is here; the engine is not ready yet.`,`Not available`),Uu=!1)}function nd(e){Hu=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),qu(!1),Hu&&(E(`Experimental AI surround needs the generative model installed on the Space. The opt-in is here; the engine is not ready yet.`,`Not available`),Hu=!1)}function rd(){let e=X.querySelector(`[data-mv="gizmo"]`);if(!e)return;let t=null,n=null,r=(e,r)=>{t=e;let i=Y().screen||{};n={x:r.clientX,y:r.clientY,width:i.width,distance:i.distance},r.preventDefault()};[`h-left`,`h-right`,`h-dist`].forEach(e=>{let t=X.querySelector(`[data-mv="${e}"]`);t&&(F(t,`pointerdown`,n=>{t.setPointerCapture?.(n.pointerId),r(e,n)}),F(t,`keydown`,t=>{let n=t.shiftKey?1:.25,r=Y().screen||{};if(t.key===`ArrowLeft`||t.key===`ArrowDown`)wu(e===`h-dist`?{distance:Math.max(1,r.distance-n)}:{width:Math.max(.5,r.width-n)});else if(t.key===`ArrowRight`||t.key===`ArrowUp`)wu(e===`h-dist`?{distance:r.distance+n}:{width:r.width+n});else return;t.preventDefault(),ad()}))}),F(e,`pointermove`,e=>{if(!(!t||!n)){if(t===`h-dist`){let t=(e.clientY-n.y)/26;wu({distance:Math.max(1,n.distance+t)})}else{let r=(t===`h-right`?1:-1)*(e.clientX-n.x)/26;wu({width:Math.max(.5,n.width+r*2)})}ad()}});let i=()=>{t=null,n=null};F(e,`pointerup`,i),F(e,`pointercancel`,i),F(window,`pointerup`,i)}function id(){if(!X)return;let e=Y();X.querySelector(`[data-mv="formats"]`).innerHTML=Gu(`format`,Ql,Lu,e.projection,e.projectionAuto),X.querySelector(`[data-mv="packings"]`).innerHTML=Gu(`packing`,$l,Ru,e.packing,e.packingAuto),X.querySelector(`[data-mv="modes"]`).innerHTML=Object.keys(eu).map(t=>`<button type="button" class="mv-chip mv-mode" data-mode="${t}" aria-pressed="${t===e.environment}">${Wu(zu[t])}${eu[t].label}</button>`).join(``);let t=X.querySelector(`[data-mv="mode-note"]`);t.textContent=e.roomSuppressed?`${Lu[e.projection]} content surrounds you, so there is no room to put it in — the ${eu[e.environment]?.label} preset applies to flat content only.`:`${eu[e.environment]?.note||``} Theater, PVR, INOX and IMAX are named room and screen presets — not licensed cinema formats.`,t.classList.toggle(`mv-note-warn`,!!e.roomSuppressed);let n=X.querySelector(`[data-mv="detected"]`);e.fileName?(n.hidden=!1,n.innerHTML=`${Wu(`<path d="M20 6 9 17l-5-5"/>`,`mv-ok-icon`)}
      <p><b>${e.fileName}</b> — ${e.sourceWidth}×${e.sourceHeight}.
      Detected as <b>${Lu[e.projection]}</b> (${e.projectionWhy}) packed
      <b>${Ru[e.packing]}</b> (${e.packingWhy}).
      Each eye is ${Math.round(e.eyeWidth)}×${Math.round(e.eyeHeight)}${e.eyeSqueezed?`, un-squeezed on playback`:``}.</p>`):n.hidden=!0,ad()}function ad(){if(!X)return;let e=Y().screen||{},t=X.querySelector(`[data-mv="readouts"]`);if(!t)return;t.innerHTML=[[`Width`,e.width?`${e.width.toFixed(2)} m`:`—`],[`Distance`,e.distance?`${e.distance.toFixed(1)} m`:`—`],[`Subtends`,e.width&&e.distance?`${(2*Math.atan(e.width/2/e.distance)*180/Math.PI).toFixed(0)}°`:`—`],[`Curve`,e.curvatureRadius?`${e.curvatureRadius.toFixed(1)} m`:`flat`]].map(([e,t])=>`<div class="mv-ro"><div class="mv-k">${e}</div><div class="mv-v">${t}</div></div>`).join(``);let n=X.querySelector(`[data-mv="screen-svg"]`);if(n&&e.width){let t=Math.max(40,Math.min(210,e.width*26));n.style.width=`${t}px`,n.style.top=`${Math.max(6,150-e.distance*13)}px`;let r=e.curvatureRadius>0?Math.min(24,900/e.curvatureRadius):0;n.querySelector(`path`).setAttribute(`d`,`M4 30 Q100 ${30-r} 196 30`);let i=X.querySelector(`[data-mv="h-left"]`),a=X.querySelector(`[data-mv="h-right"]`),o=X.querySelector(`[data-mv="h-dist"]`),s=parseFloat(n.style.top);i&&(i.style.left=`calc(50% - ${t/2}px - 7px)`,i.style.top=`${s+18}px`),a&&(a.style.left=`calc(50% + ${t/2}px - 7px)`,a.style.top=`${s+18}px`),o&&(o.style.top=`${s-4}px`)}}function od(){Vu&&clearInterval(Vu),Vu=setInterval(()=>{let e=X?.querySelector(`[data-mv="quality"]`);if(!e)return;let t=Y(),n=Eu();e.innerHTML=[[`Source`,`${t.sourceWidth} × ${t.sourceHeight}`,`plain`],[`Per eye`,`${Math.round(t.eyeWidth)} × ${Math.round(t.eyeHeight)}`,`plain`],[`Texture upload`,n&&n.textureWidth===t.sourceWidth?`Native, no downscale`:`pending`,n&&n.textureWidth===t.sourceWidth?`ok`:`plain`],[`Playback speed`,n?.realtimeRatio==null?`—`:`${(n.realtimeRatio*100).toFixed(0)}% of real time`,n&&n.realtimeRatio>=.97?`ok`:n?`warn`:`plain`],[`Stalled`,n?`${n.stallSeconds}s of ${n.elapsedSeconds}s`:`—`,n&&n.stallSeconds<1?`ok`:n?`warn`:`plain`],[`Render rate`,n?.rendererFps==null?`—`:`${n.rendererFps} fps`,n&&n.rendererFps>=55?`ok`:n?`warn`:`plain`],[`Mipmaps`,`Off — centre stays sharp`,`plain`],[`Adaptive reduction`,`Never applied`,`ok`]].map(([e,t,n])=>`<dt>${e}</dt><dd class="${n===`plain`?``:n}">${t}</dd>`).join(``)},500)}function sd(){return Vu&&(clearInterval(Vu),Vu=0),qu(!1),Nu(),X?.remove(),X=null,Bu=null,!0}function cd(){return A(`open-media`,()=>Ku()),globalThis.JarvisMediaUI={open:Ku,close:sd,isOpen:()=>!!X,click:e=>{let t=X?.querySelector(e);return t?(t.click(),!0):!1}},!0}var ld=null,ud=null,dd=null,fd=null,pd=new Float32Array(1e3*3),md=new Ge;md.setAttribute(`position`,new Ve(pd,3)),md.setDrawRange(0,0);var hd=1e3;function gd(){return{name:`world-points-collector`,onUpdate:({processCpuResult:e})=>{let t=e?.worldPoints||e?.reality?.worldPoints||e?.reality?.points||e?.slam?.worldPoints;t&&t.length>0&&(k.worldPoints=t,_d(t))}}}function _d(e){if(!(!e||e.length<10)){for(let t of e){let e=t.position||t;!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.z)||k.worldPointBuffer.push(new w(e.x,e.y,e.z))}k.worldPointBuffer.length>1e3&&k.worldPointBuffer.splice(0,k.worldPointBuffer.length-1e3),k.frameCount+=1,k.frameCount%20==0&&(vd(k.worldPointBuffer),yd(k.worldPointBuffer))}}function vd(e){if(!e.length)return;let{scene:t}=z(),n=Math.min(e.length,hd);for(let t=0;t<n;t+=1){let r=e[e.length-n+t];pd[t*3]=r.x,pd[t*3+1]=r.y,pd[t*3+2]=r.z}md.attributes.position.needsUpdate=!0,md.setDrawRange(0,n),ld||(fd=new te({color:51455,size:.018,transparent:!0,opacity:.55,depthWrite:!1}),ld=new oe(md,fd),ld.name=`jarvis-room-point-cloud`,ld.scale.setScalar(1),t.add(ld))}function yd(e){if(!e.length)return;let t=[...e].sort((e,t)=>e.y-t.y),n=[],r=[];for(let e=0;e<t.length;e++){let i=t[e];if(r.length===0)r.push(i);else{let e=r[r.length-1];i.y-e.y<=.04?r.push(i):(n.push(r),r=[i])}}r.length>0&&n.push(r);let i=Math.max(8,Math.floor(t.length*.08)),o=null;for(let e of n)if(e.length>=i){o=e;break}let s;if(o)s=o.reduce((e,t)=>e+t.y,0)/o.length;else{let e=Math.max(4,Math.floor(t.length*.15)),n=t.slice(0,e);s=n.reduce((e,t)=>e+t.y,0)/n.length}if(!Number.isFinite(s))return;k.floorY!==void 0&&Number.isFinite(k.floorY)?k.floorY=k.floorY*.88+s*.12:k.floorY=s;let c=k.floorY,{scene:l}=z();if(!ud){let e=new ae(10,10,20,20);ud=new a(e,new x({color:51455,transparent:!0,opacity:.06,side:2,depthWrite:!1})),dd=new a(e,new x({color:51455,transparent:!0,opacity:.2,wireframe:!0,depthWrite:!1})),ud.name=`jarvis-detected-floor`,dd.name=`jarvis-detected-floor-wire`,ud.rotation.x=-Math.PI/2,dd.rotation.x=-Math.PI/2,l.add(ud,dd)}ud.position.y=c,dd.position.y=c,k.shadowReceiver&&(k.shadowReceiver.position.y=c+.002),D(`status-tracking`,k.trackingMode===`8thwall-slam`?`slam+floor`:`basic floor`),j(`world-anchor-sample`,{floorY:c,pointCount:e.length})}function bd(){k.worldPointBuffer.length<10&&xd(),vd(k.worldPointBuffer),yd(k.worldPointBuffer)}function xd(){let e=[],{camera:t}=z(),n=new Re,r=Number.isFinite(k.floorY)?k.floorY:t&&t.position&&Number.isFinite(t.position.y)?t.position.y-1.45:-1.2;for(let i=0;i<9;i+=1)for(let a=0;a<20;a+=1){let o=.08+.84/19*a,s=.38+.46/8*i;n.setFromCamera(new Ne(o*2-1,-(s*2-1)),t);let c=(r-n.ray.origin.y)/n.ray.direction.y;Number.isFinite(c)&&c>.2&&c<8&&e.push(n.ray.origin.clone().add(n.ray.direction.clone().multiplyScalar(c)))}k.worldPointBuffer.push(...e),k.worldPointBuffer.length>1e3&&k.worldPointBuffer.splice(0,k.worldPointBuffer.length-1e3)}var Sd={forest:[`Fox`,`Lantern`,`BarramundiFish`],lab:[`DamagedHelmet`,`AntiqueCamera`,`ReciprocatingSaw`],room:[`GlamVelvetSofa`,`WaterBottle`,`IridescenceLamp`],street:[`CesiumMilkTruck`,`ToyCar`,`Lantern`],default:[`Duck`,`Avocado`,`WaterBottle`]};function Cd(){A(`scan-room`,()=>{bd(),E(`Room mesh scan updated from 8th Wall world points or basic fallback points.`,`Room Scan`)}),Ed()}async function wd(e=`room`){let t=String(e||`room`).toLowerCase(),n=Sd[t]||Sd.default;bd();let r=Math.min(3,Math.max(1,n.length));E(`Reconstructing ${t} scene with ${r} parallel model loads.`,`Scene Reconstruction`);try{await Td(t)}catch(e){T(e.message,`HDR Environment Failed`)}let i=(await Dd(n.map((e,t)=>async()=>{let r=t/n.length*Math.PI*2;return Od(Ro(e,new w(Math.sin(r)*.75,k.floorY+.04,-1.5-Math.cos(r)*.45),new C),12e3,`Timed out loading ${e}`)}),r)).filter(e=>e.status===`rejected`);i.length&&T(`${i.length} reconstruction model(s) fell back or failed.`,`Scene Reconstruction`),E(`Reconstructed ${t} scene with ${n.length} placed objects.`,`Scene Reconstruction`)}async function Td(e){let{scene:t,renderer:n}=z(),r=await Hn(e);return new Promise((e,i)=>{new le().load(r,r=>{let a=new m(n),o=a.fromEquirectangular(r),s=t.userData.jarvisEnvironmentTarget,c=t.environment;if(!o?.texture){r.dispose(),a.dispose(),i(Error(`HDR environment generation failed.`));return}t.environment=o.texture,t.userData.jarvisEnvironmentTarget=o,t.userData.jarvisEnvironmentSource=`hdr`,c?.dispose?.(),s?.dispose?.(),r.dispose(),a.dispose(),e(t.environment)},void 0,i)})}function Ed(){let e=new WeakSet;new MutationObserver(()=>{document.querySelectorAll(`video`).forEach(t=>{e.has(t)||(e.add(t),t.addEventListener(`play`,()=>{E(`A playing video was detected. Say "JARVIS reconstruct this scene" to build an AR scene.`,`Scene Detection`)},{once:!0}))})}).observe(document.documentElement,{childList:!0,subtree:!0})}async function Dd(e,t){let n=[],r=new Set;for(let i of e){let e=i().then(e=>({status:`fulfilled`,value:e})).catch(e=>({status:`rejected`,reason:e}));n.push(e),r.add(e),e.finally(()=>r.delete(e)),r.size>=t&&await Promise.race(r)}return Promise.all(n)}function Od(e,t,n){let r=0,i=new Promise((e,i)=>{r=window.setTimeout(()=>i(Error(n)),t)});return Promise.race([e,i]).finally(()=>window.clearTimeout(r))}var kd=.35,Ad=.65,jd=.18,Md=8,Nd=4,Pd=12,Fd=60,Z={confidence:0,qualityTier:`initializing`,lostFrames:0,goodFrames:0,isLost:!1,worldOriginLocked:!1,worldOriginSamples:0,worldOriginPosition:new w,worldOriginQuaternion:new C,lastGoodPose:{position:new w,quaternion:new C,timestamp:0},smoothedPosition:new w,smoothedQuaternion:new C,anchorRegistry:new Map,planeRegistry:new Map,relocalizationAttempts:0,totalFrames:0};k.tracking=Z;function Id(){return{name:`jarvis-tracking-quality`,onUpdate:({processCpuResult:e,processGpuResult:t})=>{Z.totalFrames++;let n=e?.reality||t?.reality||e||t,r=Ld(n),i=Rd(n);i&&(Z.confidence=Z.confidence*.85+r*.15,Z.qualityTier=zd(Z.confidence),k.trackingQuality=Z.qualityTier,document.body.dataset.jarvisTrackingQuality=Z.qualityTier,Z.confidence<kd?(Z.lostFrames++,Z.goodFrames=0,!Z.isLost&&Z.lostFrames>=Md&&Gd()):(Z.goodFrames++,Z.lostFrames=0,Z.isLost&&Z.goodFrames>=Nd&&Kd(i)),!Z.isLost&&(Hd(i),Z.worldOriginLocked||Wd(Z.smoothedPosition,Z.smoothedQuaternion),Yd(),Z.confidence>=Ad&&(Z.lastGoodPose.position.copy(Z.smoothedPosition),Z.lastGoodPose.quaternion.copy(Z.smoothedQuaternion),Z.lastGoodPose.timestamp=performance.now()),k.sessionAnchor.originPosition=Z.worldOriginPosition.toArray(),k.sessionAnchor.originQuaternion=Z.worldOriginQuaternion.toArray()))}}}function Ld(e){if(!e)return 0;let t=e.trackingStatus||e.slam?.trackingStatus;if(t){if(t===`NORMAL`)return .9;if(t===`LIMITED`)return .45;if(t===`INITIALIZING`)return .25}let n=e.confidence??e.slam?.confidence??e.poseConfidence;if(typeof n==`number`&&Number.isFinite(n))return Math.max(0,Math.min(1,n));let r=e.worldPoints||e.points;if(r&&Array.isArray(r)){let e=r.length;return e>80?.85:e>40?.65:e>15?.45:e>5?.25:.1}return .5}function Rd(e){if(!e)return null;let t=e.cameraPose||e.pose||e.slam?.cameraPose;if(!t)return null;let n=t.position||t,r=t.orientation||t.rotation;return Number.isFinite(n?.x)?{position:n,orientation:r}:null}function zd(e){return e>=.8?`excellent`:e>=.6?`good`:e>=.38?`fair`:e>=.15?`poor`:`initializing`}var Bd=new w,Vd=new C;function Hd(e){let{position:t,orientation:n}=e;Bd.set(Math.fround(t.x??0),Math.fround(t.y??0),Math.fround(t.z??0)),n&&Vd.set(n.x??0,n.y??0,n.z??0,n.w??1);let r=jd*(1+(1-Z.confidence)*1.5),i=Math.min(r,.45);Z.smoothedPosition.lerp(Bd,i),Z.smoothedPosition.set(Math.fround(Z.smoothedPosition.x),Math.fround(Z.smoothedPosition.y),Math.fround(Z.smoothedPosition.z)),n&&(Z.smoothedQuaternion.slerp(Vd,i),Z.smoothedQuaternion.normalize())}var Ud=[];function Wd(e,t){if(Z.confidence<Ad){Ud=[],Z.worldOriginSamples=0;return}Ud.push({pos:e.clone(),quat:t.clone()}),Ud.length>Pd&&Ud.shift(),Z.worldOriginSamples=Ud.length;let n=new w,r=new C;if(Ud.forEach((e,t)=>{let i=1/(t+1);n.lerp(e.pos,i),r.slerp(e.quat,i)}),Z.worldOriginPosition.copy(n),Z.worldOriginQuaternion.copy(r),Ud.length===Pd){let e=0;Ud.forEach(t=>{e+=t.pos.distanceToSquared(n)}),e/Pd<.001&&(Z.worldOriginLocked=!0,k.sessionAnchor.restoredAt=Date.now(),j(`world-origin-locked`,{position:Z.worldOriginPosition.toArray(),quaternion:Z.worldOriginQuaternion.toArray()}),D(`status-tracking`,`${k.trackingMode} origin locked`))}}function Gd(){Z.isLost=!0,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,Ud=[],Z.relocalizationAttempts=0,document.body.dataset.jarvisTrackingState=`lost`,E(`Tracking lost — move camera slowly to reacquire environment.`,`Tracking`),D(`status-tracking`,`lost`),j(`tracking-lost`,{lastGoodPose:{position:Z.lastGoodPose.position.toArray(),age:performance.now()-Z.lastGoodPose.timestamp}}),Z.anchorRegistry.forEach(e=>{e.object&&(e.object.userData.trackingFrozen=!0)})}function Kd(e){Z.isLost=!1,Z.lostFrames=0,Z.relocalizationAttempts++,document.body.dataset.jarvisTrackingState=`recovered`,D(`status-tracking`,k.trackingMode),j(`tracking-recovered`,{attempt:Z.relocalizationAttempts,confidence:Z.confidence}),Z.anchorRegistry.forEach(e=>{e.object&&(e.object.userData.trackingFrozen=!1)}),E(`Tracking recovered.`,`Tracking`)}function qd(e,t,n){let r={id:e,object:t,targetPosition:n.clone(),history:[],confidence:Z.confidence,createdAt:performance.now()};return Z.anchorRegistry.set(e,r),j(`anchor-registered`,{id:e,position:n.toArray()}),r}function Jd(e){Z.anchorRegistry.delete(e),j(`anchor-removed`,{id:e})}function Yd(){Z.anchorRegistry.forEach(e=>{if(!e.object||e.object.userData.trackingFrozen)return;let t=e.object,n=e.targetPosition,r=new w;t.getWorldPosition(r),r.set(Math.fround(r.x),Math.fround(r.y),Math.fround(r.z)),n.set(Math.fround(n.x),Math.fround(n.y),Math.fround(n.z));let i=r.distanceTo(n);if(e.history.push({drift:i,t:performance.now()}),e.history.length>Fd&&e.history.shift(),i>.001){let r=Math.max(.015,Math.min(.35,i*1.5));t.position.lerp(n,r),e.confidence=Z.confidence}})}function Xd(e){if(!e||e.length<20)return;let t=e.map(e=>{let t=e.position||e;return new w(t.x,t.y,t.z)}).filter(e=>Number.isFinite(e.x+e.y+e.z));if(t.length<20)return;let n=Math.min(...t.map(e=>e.y)),r=Math.max(...t.map(e=>e.y))-n;if(r<.1)return;let i=Array.from({length:10},()=>[]);t.forEach(e=>{i[Math.min(9,Math.floor((e.y-n)/r*10))].push(e)});let a=[];return i.forEach((e,t)=>{if(e.length<8)return;let i=n+t/10*r+r/10/2,o=e.reduce((e,t)=>e.add(t),new w).divideScalar(e.length),s=i<n+r*.25,c=i>n+r*.75,l=s?`floor`:c?`ceiling`:`surface`;a.push({yCenter:i,centroid:o,pointCount:e.length,type:l,confidence:Math.min(1,e.length/30)})}),a.forEach((e,t)=>{let n=`plane-${t}-${e.type}`;Z.planeRegistry.set(n,e)}),k.detectedPlanes=a,a.length>0&&j(`planes-updated`,{planes:a,count:a.length}),a}function Zd(e,t){if(Z.confidence<kd)return null;let{renderer:n}=z()||{};if(n?.xr?.enabled&&k.xrHitTestSource){let e=n.xr.getFrame();if(e){let t=n.xr.getReferenceSpace(),r=e.getHitTestResults(k.xrHitTestSource);if(r.length>0){let e=r[0].getPose(t);if(e){let t=new Ke().fromArray(e.transform.matrix);return{point:new w().setFromMatrixPosition(t),normal:new w(0,1,0).applyMatrix4(t).normalize(),confidence:Z.confidence,type:`webxr-hit-test`}}}}}if(globalThis.XR8?.XrController){let t=globalThis.XR8.XrController.hitTest(e.x,e.y,[`FEATURE_POINT`,`ESTIMATED_SURFACE`,`DETECTED_SURFACE`]);if(t&&t.length>0){let e=t[0];return{point:new w(e.position.x,e.position.y,e.position.z),normal:new w(0,1,0),confidence:Z.confidence*(e.type===`DETECTED_SURFACE`?.9:.5),type:e.type}}}let r=new Re;if(r.setFromCamera(new Ne(e.x*2-1,-(e.y*2-1)),t),Number.isFinite(k.floorY)){let e=new w(0,1,0),t=new p(e,-k.floorY),n=new w;if(r.ray.intersectPlane(t,n)){let t=n.distanceTo(r.ray.origin);if(t>.2&&t<10)return{point:n,normal:e,confidence:Z.confidence,type:`floor`,distance:t}}}let i=k.detectedPlanes||[];for(let e of i){if(e.type===`floor`)continue;let t=new w(0,1,0),n=new p(t,-e.yCenter),i=new w;if(r.ray.intersectPlane(n,i)){let n=i.distanceTo(r.ray.origin);if(n>.2&&n<10)return{point:i,normal:t,confidence:Z.confidence*e.confidence,type:e.type,distance:n}}}return null}function Qd(){return{confidence:Z.confidence,tier:Z.qualityTier,isLost:Z.isLost,worldOriginLocked:Z.worldOriginLocked,anchorCount:Z.anchorRegistry.size,planeCount:Z.planeRegistry.size,relocalizationAttempts:Z.relocalizationAttempts,totalFrames:Z.totalFrames}}function $d(){Z.worldOriginLocked=!1,Z.worldOriginSamples=0,Ud=[],Z.isLost=!1,Z.lostFrames=0,Z.goodFrames=0,E(`Relocalization requested — scanning environment.`,`Tracking`),j(`relocalization-requested`,{attempt:++Z.relocalizationAttempts})}function ef(){Z.confidence=0,Z.qualityTier=`initializing`,Z.lostFrames=0,Z.goodFrames=0,Z.isLost=!1,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,Ud=[],Z.anchorRegistry.clear(),Z.planeRegistry.clear(),Z.relocalizationAttempts=0,Z.totalFrames=0,k.detectedPlanes=[],document.body.dataset.jarvisTrackingQuality=`initializing`,document.body.dataset.jarvisTrackingState=`init`}A(`world-anchor-sample`,({floorY:e,pointCount:t})=>{k.worldPointBuffer?.length>20&&Xd(k.worldPointBuffer)}),A(`runtime-phase`,({phase:e})=>{(e===`created`||e===`booting`)&&ef()});var tf=null,nf=0;function rf(){return tf||(tf=yn(af(`eternum`),`Eternum AR`,880,560),of(tf,[[`NEXT`,`Enter`],[`AUTO`,`a`],[`SAVE`,`s`],[`MENU`,`Escape`]]),E(`Eternum opened as a floating AR panel. Normal game launch is unchanged outside AR.`,`Eternum AR`),tf)}function af(e){let t=new URLSearchParams(location.search);return String(t.get(`${e}Url`)||t.get(`game${e[0].toUpperCase()}${e.slice(1)}Url`)||``).trim()||String(globalThis.FridayARConfig?.gameUrls?.[e]||``).trim()||`/api/ar_task?mode=game_launch&task=${encodeURIComponent(`open ${e} web mirror`)}`}function of(e,t){let n=document.createElement(`div`);n.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;pointer-events:auto`,t.forEach(([t,r])=>{let i=document.createElement(`button`);i.textContent=t,i.style.cssText=`min-height:44px;min-width:70px;border:1px solid rgba(255,255,255,.25);border-radius:999px;background:rgba(0,0,0,.48);color:white;font-weight:700`,i.onclick=()=>sf(e.iframe,r),n.appendChild(i)}),e.container.style.position=`relative`,e.container.appendChild(n)}async function sf(e,t,n=!1,r=!1){let i=e?.contentWindow;if(!i)return T(`The game iframe is not ready yet.`,`Game Input Failed`),!1;try{let e={key:t,bubbles:!0,cancelable:!0,ctrlKey:n};return i.document.dispatchEvent(new KeyboardEvent(`keydown`,e)),r||window.setTimeout(()=>i.document.dispatchEvent(new KeyboardEvent(`keyup`,e)),50),!0}catch(e){let a=`key-${Date.now().toString(36)}-${++nf}`;return await new Promise(o=>{let s=window.setTimeout(()=>{window.removeEventListener(`message`,c),T(`The game iframe did not acknowledge the key relay before the timeout elapsed.`,`Game Input Timeout`),o(!1)},250),c=e=>{e.source===i&&(e.data?.type!==`keydown-ack`||e.data?.id!==a||(window.clearTimeout(s),window.removeEventListener(`message`,c),o(!0)))};window.addEventListener(`message`,c);try{i.postMessage({type:`keydown`,id:a,key:t,ctrl:n,hold:r},`*`)}catch(t){window.clearTimeout(s),window.removeEventListener(`message`,c),T(t.message||e.message,`Game Input Failed`),o(!1)}})}}var cf=null;function lf(){if(cf)return cf;let e=new URLSearchParams(location.search);cf=yn(String(e.get(`ripplesUrl`)||globalThis.FridayARConfig?.gameUrls?.ripples||``).trim()||`/api/ar_task?mode=game_launch&task=open%20ripples%20web%20mirror`,`Ripples AR`,880,560);let t=document.createElement(`div`);return t.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;pointer-events:auto`,[[`NEXT`,`Enter`],[`AUTO`,`a`],[`SAVE`,`s`],[`MENU`,`Escape`]].forEach(([e,n])=>{let r=document.createElement(`button`);r.textContent=e,r.style.cssText=`min-height:44px;min-width:70px;border:1px solid rgba(255,255,255,.25);border-radius:999px;background:rgba(0,0,0,.48);color:white;font-weight:700`,r.onclick=()=>sf(cf.iframe,n),t.appendChild(r)}),cf.container.style.position=`relative`,cf.container.appendChild(t),E(`Ripples opened as a floating AR panel.`,`Ripples AR`),cf}async function uf(e,t){let n=await df(e,t),r=yn(pf(n.url||e),`${n.title||e} AR`,880,560);return _f(n.controls,r),r}async function df(e,t){if(t?.query)try{let n=await t.query(`Game "${e}" genre + controls as JSON only: {"title":"","url":"","genre":"","controls":[{"action":"","key":"","label":""}]}`),r=String(n).replace(/```json|```/g,``).trim(),i=JSON.parse(hf(r));if(ff(i))return i}catch(e){T(e.message,`Game Schema AI Failed`)}return{title:e,url:pf(e),genre:`generic`,controls:[{action:`accept`,key:`Enter`,label:`NEXT`},{action:`back`,key:`Escape`,label:`BACK`},{action:`left`,key:`ArrowLeft`,label:`LEFT`},{action:`right`,key:`ArrowRight`,label:`RIGHT`}]}}function ff(e){return!e||typeof e!=`object`||typeof e.title!=`string`||typeof e.url!=`string`||typeof e.genre!=`string`||!Array.isArray(e.controls)?!1:e.controls.every(e=>e&&typeof e==`object`&&typeof e.key==`string`&&typeof e.label==`string`&&e.key.trim()&&e.label.trim())}function pf(e){let t=String(e||``).trim();if(!t)return mf(`AR Game`);if(/^(https?:|blob:|data:|about:)/i.test(t)||t.startsWith(`/`))return t;let n=t.toLowerCase();if(n.includes(`eternum`)){let e=new URLSearchParams(location.search).get(`eternumUrl`);return String(e||globalThis.FridayARConfig?.gameUrls?.eternum||``).trim()||`/api/ar_task?mode=game_launch&task=open%20eternum%20web%20mirror`}if(n.includes(`ripples`)){let e=new URLSearchParams(location.search).get(`ripplesUrl`);return String(e||globalThis.FridayARConfig?.gameUrls?.ripples||``).trim()||`/api/ar_task?mode=game_launch&task=open%20ripples%20web%20mirror`}return mf(t)}function mf(e){let t=`<!doctype html>
<html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body style="margin:0;background:#05070a;color:white;font:16px system-ui;display:grid;place-items:center;height:100vh;text-align:center">
  <main>
    <h1 style="font-size:22px;margin:0 0 10px">${gf(e)}</h1>
    <p style="opacity:.72;max-width:32rem">No direct web URL was configured for this game yet. Pass a URL in the launch query string or runtime config, or open a supported mirror command, then convert again.</p>
  </main>
</body>
</html>`;return`data:text/html;charset=utf-8,${encodeURIComponent(t)}`}function hf(e){let t=e.indexOf(`{`),n=e.lastIndexOf(`}`);return t>=0&&n>t?e.slice(t,n+1):e}function gf(e){return String(e).replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e])}function _f(e,t){let n=document.createElement(`div`);return n.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap;pointer-events:auto`,e.forEach(e=>{let r=document.createElement(`button`);r.textContent=e.label||e.action,r.style.cssText=`min-height:44px;min-width:64px;border:1px solid var(--separator);border-radius:999px;background:var(--bg-dark);color:var(--text-primary);font-weight:700`,r.onclick=()=>sf(t.iframe,e.key||`Enter`),n.appendChild(r)}),t.container.style.position=`relative`,t.container.appendChild(n),n}var vf=`jarvis_ar_game_builder_graphs_v1`,yf=[`OnCollide`,`OnTap`,`OnGesture`,`OnTimerEnd`,`IsTag`,`IsHealth`,`IsDistance`,`Destroy`,`Spawn`,`MoveToward`,`SetScore`,`PlaySound`,`ShowMessage`,`EndGame`],bf=null,xf=null;function Sf(){if(bf)return bf.restore(),bf;let e=document.createElement(`div`);e.append(Cf()),bf=new hn({title:`AR Game Builder`,body:e,icon:`B`,width:400,height:600});let t=bf.destroy.bind(bf);return bf.destroy=()=>{xf?.dispose?.(),xf=null,t(),bf=null},bf.focus(),bf}function Cf(){let e=document.createElement(`div`),t=document.createElement(`div`),n=document.createElement(`div`);return t.className=`panel-row`,Object.entries({Entities:wf,Logic:Tf,Settings:Ef,Play:Df}).forEach(([e,r],i)=>{let a=document.createElement(`button`);a.className=`panel-action`,a.textContent=e,a.onclick=()=>{t.querySelectorAll(`button`).forEach(e=>e.classList.toggle(`selected`,e===a)),n.replaceChildren(r())},t.appendChild(a),i===0&&window.setTimeout(()=>a.click(),0)}),e.append(t,n),e}function wf(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`input`),r=document.createElement(`button`);return t.placeholder=`Entity name`,n.placeholder=`Tag, e.g. target`,r.className=`panel-action`,r.textContent=`Add Entity`,r.onclick=()=>{let e=ur(vf,[]).at(-1)||Nf();e.entities.push({id:gr(`entity`),name:t.value||`Entity`,tag:n.value||`default`}),Pf(e),E(`Entity saved to AR game graph.`)},e.append(t,n,r,Ff()),e}function Tf(){let e=document.createElement(`div`),t=document.createElement(`select`),n=document.createElement(`input`),r=document.createElement(`button`);return _r(t,yf),n.placeholder=`Node value`,r.className=`panel-action`,r.textContent=`Add Logic Node`,r.onclick=()=>{let e=ur(vf,[]).at(-1)||Nf();e.nodes.push({id:gr(`node`),type:t.value,value:n.value}),Pf(e),E(`${t.value} node added.`)},e.append(t,n,r,Ff()),e}function Ef(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`input`),r=document.createElement(`button`);return t.placeholder=`Game title`,n.type=`number`,n.placeholder=`Timer seconds`,r.className=`panel-action`,r.textContent=`Save Settings`,r.onclick=()=>{let e=ur(vf,[]).at(-1)||Nf();e.title=t.value||e.title,e.duration=Number(n.value||e.duration||60),Pf(e),E(`Game settings saved.`)},e.append(t,n,r,Ff()),e}function Df(){let e=document.createElement(`div`),t=document.createElement(`button`);return t.className=`btn-primary`,t.textContent=`Spawn Saved Game`,t.onclick=()=>{let e=ur(vf,[]).at(-1);if(!e){E(`Create a game graph first.`);return}xf?.dispose?.(),xf=Of(e),E(`Game "${e.title}" spawned ${xf.entities.length} AR entity object(s).`,`Game Builder`)},e.append(t,Ff()),e}function Of(e){let{scene:t,camera:n}=z(),r=new we;r.name=`jarvis-game-${e.id}`,r.userData.isARGame=!0,r.position.set(0,k.floorY+.08,-1.6),t.add(r);let i=(e.entities.length?e.entities:[{id:gr(`entity`),name:`Target`,tag:`target`}]).map((t,n)=>kf(t,n,e.entities.length||1));i.forEach(e=>r.add(e.mesh));let a=0,o=!1,s=performance.now(),c=[],l=[],u=new Re,d=t=>{if(o)return;let n=String(t.type||``).toLowerCase(),s=String(t.value||``).trim();if(n===`spawn`){let e=kf({id:gr(`entity`),name:s||`Spawned`,tag:`spawned`},i.length,i.length+1);i.push(e),r.add(e.mesh)}else if(n===`destroy`){let e=Af(s,i);e&&(e.mesh.parent?.remove(e.mesh),e.destroyed=!0)}else if(n===`setscore`)a=Number(s||a+1),r.userData.score=a;else if(n===`showmessage`)E(s||e.title||`AR game event`,`Game Builder`);else if(n===`playsound`)Mf();else if(n===`endgame`)o=!0,E(`${e.title||`AR Game`} ended. Score: ${a}`,`Game Builder`);else if(n===`movetoward`){let e=Af(s,i)||i[0];e&&e.mesh.position.lerp(new w(0,.12,-.35),.35)}},f=t=>{if(o||t.target.closest?.(`.ar-panel, .hud-toolbar, button, input, select, textarea, iframe`))return;u.setFromCamera(new Ne(t.clientX/innerWidth*2-1,-(t.clientY/innerHeight)*2+1),n);let s=u.intersectObjects(i.filter(e=>!e.destroyed).map(e=>e.mesh),!0)[0];if(!s)return;let c=jf(s.object,i);a+=1,r.userData.score=a,c.mesh.scale.multiplyScalar(.92),e.nodes.filter(e=>e.type===`OnTap`||e.type===`SetScore`||e.type===`ShowMessage`).forEach(d)};document.addEventListener(`pointerup`,f,!0),l.push(()=>document.removeEventListener(`pointerup`,f,!0));let p=A(`gesture-pinch`,()=>{e.nodes.filter(e=>e.type===`OnGesture`||e.type===`SetScore`).forEach(d)});l.push(p),Number(e.duration)>0&&c.push(window.setTimeout(()=>{e.nodes.filter(e=>e.type===`OnTimerEnd`||e.type===`EndGame`).forEach(d),o||(o=!0,E(`${e.title||`AR Game`} timer finished. Score: ${a}`,`Game Builder`))},Number(e.duration)*1e3));let m=()=>{if(!r.parent||o)return;let e=(performance.now()-s)/1e3;i.forEach((t,n)=>{t.destroyed||(t.mesh.rotation.y+=.01+n*.001,t.mesh.position.y=.08+Math.sin(e*1.6+n)*.035)}),r.userData.frame=I(m)};return m(),{root:r,entities:i,dispose(){o=!0,ht(r.userData.frame),c.forEach(e=>window.clearTimeout(e)),l.forEach(e=>e()),r.traverse(e=>{e.geometry?.dispose?.(),e.material?.dispose?.()}),r.parent?.remove(r)}}}function kf(e,t,n){let r=new _(.12,1),i=t/Math.max(n,1)*.78+.05,o=new a(r,new d({color:new re().setHSL(i,.72,.55),emissive:new re().setHSL(i,.72,.12),roughness:.25,metalness:.18})),s=t/Math.max(n,1)*Math.PI*2;return o.position.set(Math.sin(s)*.55,.08,-Math.cos(s)*.35),o.userData.entityId=e.id,o.userData.entityName=e.name,o.userData.tag=e.tag,o.castShadow=!0,o.receiveShadow=!0,{...e,mesh:o,destroyed:!1}}function Af(e,t){let n=String(e||``).toLowerCase();return t.find(e=>String(e.name||``).toLowerCase().includes(n)||String(e.tag||``).toLowerCase().includes(n)||String(e.id||``).toLowerCase()===n)}function jf(e,t){let n=e;for(;n;){let e=n.userData?.entityId;if(e)return t.find(t=>t.id===e);n=n.parent}return null}function Mf(){try{let e=new AudioContext,t=e.createOscillator(),n=e.createGain();t.frequency.value=660,n.gain.value=.035,t.connect(n),n.connect(e.destination),t.start(),window.setTimeout(()=>{t.stop(),e.close()},140)}catch{}}function Nf(){return{id:gr(`game`),title:`Untitled AR Game`,duration:60,entities:[],nodes:[],createdAt:Date.now()}}function Pf(e){let t=ur(vf,[]).filter(t=>t.id!==e.id);t.push(e),dr(vf,t.slice(-20))}function Ff(){let e=document.createElement(`pre`),t=ur(vf,[]).at(-1)||Nf();return e.style.cssText=`white-space:pre-wrap;font:12px/1.4 monospace;color:rgba(255,255,255,.72);background:rgba(0,0,0,.25);padding:10px;border-radius:12px;max-height:160px;overflow:auto`,e.textContent=JSON.stringify(t,null,2),e}async function If(e,t={},n=0,r=1e4){let i=null;for(let a=0;a<=n;a+=1){let o=new AbortController,s=window.setTimeout(()=>o.abort(new DOMException(`Request timed out`,`AbortError`)),r);try{let n=await fetch(e,{...t,signal:o.signal});return window.clearTimeout(s),n}catch(e){if(window.clearTimeout(s),i=e,a>=n)throw e}}throw i||Error(`Request failed.`)}async function Lf(e,t={},n=0,r=1e4){let i=await If(e,t,n,r);if(!(i.headers.get(`content-type`)||``).includes(`application/json`)){let t=await i.text();throw Error(t||`Expected JSON response from ${e}`)}return i.json()}function Rf(e,t){if(!Array.isArray(e))return!1;let n=JSON.stringify(t);return e.some(e=>JSON.stringify(e)===n)?!1:(e.push(t),!0)}var zf=class{constructor(e){this.config=e,this.ws=null,this.connected=!1,this.reconnectTimer=0,this.pendingPatches=[],this.reconnectDelay=2e3,this.maxReconnectDelay=3e4,this.heartbeatTimer=0}connect(){return this.connectWebSocket(),this.loadConfig(),k.jarvis=this,this}async loadConfig(){try{let e=await Lf(`${this.apiBase()}/api/ar_config`,{headers:this.headers()},1,9e3);if(e.ok===!1)throw Error(e.error||`AR config failed.`);return j(`jarvis-config`,e),D(`status-omega`,`linked`),e}catch{return D(`status-omega`,`offline`),null}}connectWebSocket(){let e=this.config.wsBase||(location.protocol===`https:`?`wss://${location.host}/scene-ws`:`ws://${location.hostname}:5050`),t=rr(`omega_session`);t&&!/[?&]token=/.test(e)&&(e+=`${e.includes(`?`)?`&`:`?`}token=${encodeURIComponent(t)}`);try{this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=0),this._clearHeartbeat(),this.ws=new WebSocket(e),this.ws.onopen=()=>{this.connected=!0,clearTimeout(this.reconnectTimer),this.reconnectDelay=2e3,D(`status-omega`,`linked`),this.ws.send(JSON.stringify({type:`hello`,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`})),this.flushPendingPatches(),this._startHeartbeat()},this.ws.onmessage=e=>this.onMessage(e),this.ws.onerror=()=>{this.connected&&D(`status-omega`,`ws error`)},this.ws.onclose=()=>{this.connected=!1,this._clearHeartbeat(),D(`status-omega`,`offline`),this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=this.reconnectDelay;this.reconnectDelay=Math.min(this.reconnectDelay*2,this.maxReconnectDelay),this.reconnectTimer=setTimeout(()=>this.connectWebSocket(),e)}}catch(e){T(e.message,`OMEGA WebSocket Failed`)}}_startHeartbeat(){this._clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){this._clearHeartbeat();return}try{this.ws.send(JSON.stringify({type:`ping`,ts:Date.now()}))}catch{this.ws.close()}},15e3)}_clearHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=0)}onMessage(e){try{let t=JSON.parse(e.data);j(`omega-message`,t),t.state&&j(`omega-scene-state`,t.state)}catch{}}async query(e){let t=await If(`${this.apiBase()}/api/ar_task`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify({task:e,mode:`jarvis`,device_name:this.config.deviceName})},0,9e3),n=await t.json();if(!t.ok||n.ok===!1)throw Error(n.error||`JARVIS query failed.`);return n.response||n.message||n.result||JSON.stringify(n)}async runTask(e,t=`task`){let n=await If(`${this.apiBase()}/api/ar_task`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify({task:e,mode:t,device_name:this.config.deviceName})},0,9e3),r=await n.json();if(!n.ok||r.ok===!1)throw Error(r.error||`Task endpoint failed.`);return j(`jarvis-task-result`,r),r}patchScene(e){let t={...e,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`};return this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify({type:`patch`,patch:t,ts:Date.now()})),Promise.resolve(!0)):(Rf(this.pendingPatches,t),If(`${this.apiBase()}/api/ar_scene_patch`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify(t)},1,9e3).catch(()=>null))}headers(){let e={"X-FRIDAY-Device":this.config.deviceName},t=rr(`omega_session`);return t&&(e.Authorization=`Bearer ${t}`),e}apiBase(){return String(this.config.omegaBase||``).replace(/\/+$/,``)||``}flushPendingPatches(){!this.ws||this.ws.readyState!==WebSocket.OPEN||!this.pendingPatches.length||this.pendingPatches.splice(0).forEach(e=>{try{this.ws.send(JSON.stringify({type:`patch`,patch:{...e,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`},ts:Date.now()}))}catch{}})}},Bf={IDLE:`idle`,LISTENING:`listening`,THINKING:`thinking`,SPEAKING:`speaking`},Vf={listening:`👂`,thinking:`🧠`,speaking:`🔊`},Hf={listening:`LISTENING`,thinking:`THINKING`,speaking:`SPEAKING`},Uf=Bf.IDLE,Wf=new Set;function Gf(){return Uf}function Kf(e){return Wf.add(e),()=>Wf.delete(e)}function qf(e){let t=String(e||``).toLowerCase();Object.values(Bf).includes(t)&&t!==Uf&&(Uf=t,Yf(),Wf.forEach(e=>{try{e(Uf)}catch{}}))}function Jf(){let e=document.getElementById(`jarvis-assistant-state`);return e||(e=document.createElement(`div`),e.id=`jarvis-assistant-state`,e.setAttribute(`aria-live`,`polite`),Object.assign(e.style,{position:`fixed`,top:`calc(env(safe-area-inset-top, 0px) + 12px)`,left:`50%`,transform:`translateX(-50%) translateY(-8px)`,display:`flex`,alignItems:`center`,gap:`8px`,padding:`7px 14px`,borderRadius:`999px`,background:`linear-gradient(180deg, rgba(10,10,15,.82), rgba(10,10,15,.62))`,border:`1px solid rgba(0,212,255,.35)`,boxShadow:`0 6px 24px rgba(0,0,0,.45), 0 0 18px rgba(0,212,255,.22)`,backdropFilter:`blur(14px) saturate(140%)`,color:`#eaf2ff`,font:`600 11px/1 'JetBrains Mono', ui-monospace, monospace`,letterSpacing:`2px`,zIndex:`99998`,pointerEvents:`none`,opacity:`0`,transition:`opacity .28s cubic-bezier(.2,.8,.2,1), transform .28s cubic-bezier(.2,.8,.2,1)`}),e.innerHTML=`<span data-glyph style="font-size:14px;letter-spacing:0"></span><span data-label></span>`,document.body.appendChild(e),e)}function Yf(){let e;try{e=Jf()}catch{return}if(!e)return;let t=e.querySelector(`[data-glyph]`),n=e.querySelector(`[data-label]`);if(Uf===Bf.IDLE){e.style.opacity=`0`,e.style.transform=`translateX(-50%) translateY(-8px)`;return}t&&(t.textContent=Vf[Uf]||``),n&&(n.textContent=Hf[Uf]||``),e.style.opacity=`1`,e.style.transform=`translateX(-50%) translateY(0)`}var Xf=0,Zf={idle:`JARVIS`,listening:`Listening`,thinking:`Working on it`,speaking:`JARVIS`,failed:`Couldn’t answer`};function Qf(e){let t=document.getElementById(`jarvis-bubble`),n=document.getElementById(`jarvis-bubble-label`);if(!t)return;let r=String(e||`idle`).toLowerCase();t.setAttribute(`data-state`,r),n&&(n.textContent=Zf[r]||`JARVIS`)}var $f=!1;function ep(){if($f)return;$f=!0,Kf(Qf),Qf(Gf());let e=document.getElementById(`jarvis-bubble-close`),t=document.getElementById(`jarvis-bubble`);e&&t&&e.addEventListener(`click`,()=>{clearTimeout(Xf),t.classList.add(`hidden`)})}function tp(e,{speak:t=!0}={}){let n=document.getElementById(`jarvis-bubble`),r=document.getElementById(`jarvis-bubble-text`);!n||!r||(ep(),n.classList.remove(`hidden`),clearTimeout(Xf),rp(r,String(e||`Ready.`),()=>{clearTimeout(Xf),Xf=window.setTimeout(()=>n.classList.add(`hidden`),6e3)}),t&&np(e))}function np(e){try{if(!(`speechSynthesis`in window))return;window.speechSynthesis.cancel();let t=new SpeechSynthesisUtterance(String(e||``));t.rate=.92,t.pitch=.82,t.volume=.88;let n=window.speechSynthesis.getVoices();t.voice=n.find(e=>String(e.lang||``).toLowerCase()===`en-gb`)||n.find(e=>/Daniel|George|Arthur|Google UK English Male|English.*United Kingdom|UK/i.test(`${e.name} ${e.lang}`))||n.find(e=>String(e.lang||``).toLowerCase().startsWith(`en-gb`))||n.find(e=>/en/i.test(e.lang))||null;let r=()=>{Gf()===Bf.SPEAKING&&qf(Bf.IDLE)};t.onstart=()=>qf(Bf.SPEAKING),t.onend=r,t.onerror=r,window.speechSynthesis.speak(t)}catch{Gf()===Bf.SPEAKING&&qf(Bf.IDLE)}}function rp(e,t,n){e.textContent=``;let r=0,i=()=>{e.textContent=t.slice(0,r),r+=1,r<=t.length?window.setTimeout(i,14):n?.()};i()}var ip=null,ap=0,op=0,sp=!1,cp=!1,lp=!1,up=null,dp=`unknown`,fp=0,pp=``;function mp(){let e=window.SpeechRecognition||window.webkitSpeechRecognition;return e?(ip=new e,ip.continuous=!0,ip.interimResults=!1,ip.lang=navigator.language||`en-US`,ip.onresult=gp,ip.onerror=e=>{if(e.error===`not-allowed`||e.error===`service-not-allowed`||e.error===`audio-capture`){sp=!1,dp=`blocked`,clearTimeout(op),T(e.error||`Speech recognition blocked.`,`JARVIS Voice`),vp(`blocked`,{error:e.error||`blocked`});return}e.error!==`no-speech`&&T(e.error||`Speech recognition failed.`,`JARVIS Voice`),vp(`error`,{error:e.error||`unknown`})},ip.onend=()=>{sp&&(clearTimeout(op),op=setTimeout(()=>void hp(),850),vp(`ended`))},!0):(E(`SpeechRecognition is not available here. Use the JARVIS text command panel.`),!1)}async function hp(){if(!ip&&!mp())return!1;if(lp)return!0;sp=!0,lp=!0,await _p();try{return ip.start(),window.setTimeout(()=>{lp=!1},350),cp||(E(`JARVIS wake word listening is active.`),cp=!0),!0}catch(e){return lp=!1,clearTimeout(op),op=setTimeout(()=>{sp&&hp()},1200),/InvalidStateError/i.test(e?.name||e?.message||``)||E(`JARVIS voice restart pending: ${e?.message||`recognizer busy`}`),vp(`start-failed`,{error:e?.message||`busy`}),!1}}function gp(e){if(!e.results?.[e.resultIndex]?.isFinal)return;let t=Array.from(e.results).slice(e.resultIndex).filter(e=>e?.isFinal).map(e=>e[0]?.transcript||``).join(` `).trim();if(!t)return;let n=t.toLowerCase().replace(/\s+/g,` `).trim(),r=Date.now(),i=n.match(/(?:^|\b)(?:hey\s+)?jarvis\b[:,]?\s*(.*)$/i)||n.match(/(?:^|\b)(?:hey\s+)?friday\b[:,]?\s*(.*)$/i),a=i?.[1]?.trim()||``;if(i){if(ap=r+4200,vp(`wake`,{wakeWindowUntil:ap}),!a){tp(`Listening.`,{speak:!1});return}}else if(r>ap)return;if(r-fp<650)return;fp=r;let o=a||n;!o||o===pp||(pp=o,j(`jarvis-command`,{text:o,source:`voice`}),vp(`command`,{wakeWindowUntil:ap}))}async function _p(){if(up||dp===`blocked`||!navigator.mediaDevices?.getUserMedia)return up;try{return up=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1},video:!1}),dp=`granted`,vp(`mic-ready`),up}catch(e){return dp=[`NotAllowedError`,`SecurityError`].includes(e?.name)?`blocked`:`error`,vp(`mic-error`,{error:e?.name||e?.message||`unknown`}),null}}function vp(e,t={}){try{j(`VOICE_STATE`,{reason:e,enabled:sp,starting:lp,wakeWindowUntil:ap,micPermission:dp,hasStream:!!up,lastCommandAt:fp,...t})}catch{}}var yp=5,bp=.55,xp=.3,Sp=null,Cp=null;function wp(){return Sp||(Sp=document.getElementById(`world-label-layer`)),Sp}function Tp(e,t){let n=t?.width||0,r=t?.height||0;if(!n||!r)return null;let i=t.source?.getBoundingClientRect?.(),a=i?.width||window.innerWidth,o=i?.height||window.innerHeight;if(!a||!o)return null;let s=i?.width?i.left:0,c=i?.height?i.top:0,l=`cover`;try{l=getComputedStyle(t.source).objectFit||`cover`}catch{}let u=l===`contain`||l===`scale-down`?Math.min(a/n,o/r):Math.max(a/n,o/r),d=s+(a-n*u)/2,f=c+(o-r*u)/2;return{cx:(e.originX+e.width/2)*u+d,top:e.originY*u+f}}function Ep(e){let t=wp();if(!t)return;let n=ft();if(!n)return;let r=new Set,i=[];for(let t of e||[]){let e=t?.categories?.[0],a=e?.categoryName,o=e?.score??0;if(!a||o<xp||r.has(a))continue;let s=Tp(t.boundingBox||{},n);if(s&&!(s.cx<0||s.cx>window.innerWidth||s.top<0||s.top>window.innerHeight)&&(r.add(a),i.push({name:a,score:o,pos:s}),i.length>=yp))break}t.replaceChildren();for(let e of i){let n=document.createElement(`span`);n.className=e.score<bp?`world-label low`:`world-label`,n.style.left=`${e.pos.cx}px`,n.style.top=`${e.pos.top}px`;let r=document.createElement(`b`);r.textContent=e.name.charAt(0).toUpperCase()+e.name.slice(1);let i=document.createElement(`span`);i.className=`world-label-conf`;let a=document.createElement(`i`);a.style.width=`${Math.round(Math.max(0,Math.min(1,e.score))*100)}%`,i.appendChild(a),n.append(r,i),t.appendChild(n)}}function Dp(){return Cp?!0:wp()?(Cp=F(window,`ar-object-detections`,e=>{try{Ep(e.detail)}catch(e){console.warn(`[world-labels] render skipped`,e)}}),!0):!1}var Op=null,kp=null,Ap=!1;async function jp(){Ap=!0;try{Op=new globalThis.FaceMesh({locateFile:e=>`https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${e}`}),Op.setOptions({maxNumFaces:1,refineLandmarks:!0,minDetectionConfidence:.5,minTrackingConfidence:.5}),Op.onResults(e=>{window.dispatchEvent(new CustomEvent(`ar-face-mesh-results`,{detail:e}))}),console.log(`[AR Vision] Face mesh initialized.`)}catch(e){Op=null,console.warn(`[AR Vision] Face mesh unavailable, continuing without it:`,e),D(`status-tracking`,`no face mesh`)}try{let t=await e.forVisionTasks(`https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm`);Dp(),kp=await n.createFromOptions(t,{baseOptions:{modelAssetPath:`https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float16/1/efficientdet_lite0.tflite`,delegate:`GPU`},scoreThreshold:.5,maxResults:5,runningMode:`VIDEO`}),console.log(`[AR Vision] Object detector initialized.`)}catch(e){kp=null,console.warn(`[AR Vision] Object detector unavailable, continuing without it:`,e),D(`status-tracking`,`no object detect`)}I(Mp)}async function Mp(){if(!Ap)return;let e=ft();if(e){let t=e.source;try{if(Op&&await Op.send({image:t}),kp){let e=kp.detectForVideo(t,performance.now());e.detections.length>0&&window.dispatchEvent(new CustomEvent(`ar-object-detections`,{detail:e.detections}))}}catch(e){console.warn(`Vision frame skipped:`,e)}}I(Mp)}var Np=.6,Pp=new Map([[`wrist`,0],[`thumb-metacarpal`,1],[`thumb-phalanx-proximal`,2],[`thumb-phalanx-distal`,3],[`thumb-tip`,4],[`index-finger-phalanx-proximal`,5],[`index-finger-phalanx-intermediate`,6],[`index-finger-phalanx-distal`,7],[`index-finger-tip`,8],[`middle-finger-phalanx-proximal`,9],[`middle-finger-phalanx-intermediate`,10],[`middle-finger-phalanx-distal`,11],[`middle-finger-tip`,12],[`ring-finger-phalanx-proximal`,13],[`ring-finger-phalanx-intermediate`,14],[`ring-finger-phalanx-distal`,15],[`ring-finger-tip`,16],[`pinky-finger-phalanx-proximal`,17],[`pinky-finger-phalanx-intermediate`,18],[`pinky-finger-phalanx-distal`,19],[`pinky-finger-tip`,20]]),Fp=!1,Ip=0,Lp=16;function Rp(e,t){let n=e?.session;if(!n)return;let r=t?.xr?.getReferenceSpace?.();if(!r)return;let i=performance.now();if(i-Ip<Lp)return;Ip=i;let a=[];for(let t of n.inputSources){if(!t.hand)continue;let n=zp(e,t.hand,r);n&&a.push(n)}if(!a.length){k.handState.hands.length&&(k.handState.hands=[],k.handState.gestures=new Map);return}Fp||(Fp=!0,L(`webXRHandTracking`,!0),j(`xr-hands-detected`,{count:a.length})),k.handState.hands=a;let o=Ac(a);k.handState.gestures=o;for(let[e,t]of o)j(`gesture-${e}`,{...t,source:`webxr-hands`})}function zp(e,t,n){let r=Array(21),i=0;for(let[a,o]of Pp){let s=t.get(a);if(!s)continue;let c=e.getJointPose?.(s,n);if(!c)continue;let l=c.transform.position;r[o]={x:.5+l.x/Np,y:.5-l.y/Np,z:l.z/Np},i+=1}return i<15||!r[0]||!r[4]||!r[8]?null:r}function Bp(){Fp=!1,Ip=0,k.handState.hands=[],k.handState.gestures=new Map}var Q={active:!1,binding:null,depthTexture:null,uniforms:null,patched:new WeakSet,renderer:null},Vp=`
  uniform sampler2D uDepthTexture;
  uniform mat4 uUvTransform;
  uniform float uRawValueToMeters;
  uniform float uDepthActive;
  varying vec4 vOcclClip;
  varying float vOcclEyeDepth;
`,Hp=`
  if (uDepthActive > 0.5) {
    vec2 ndc = (vOcclClip.xy / vOcclClip.w) * 0.5 + 0.5;
    vec2 depthUv = (uUvTransform * vec4(ndc, 0.0, 1.0)).xy;
    if (depthUv.x >= 0.0 && depthUv.x <= 1.0 && depthUv.y >= 0.0 && depthUv.y <= 1.0) {
      float realDepth = dot(texture2D(uDepthTexture, depthUv).ra, vec2(255.0, 65280.0)) * uRawValueToMeters;
      // Real surface closer than this fragment (with a small bias) → occluded.
      if (realDepth > 0.0 && realDepth < vOcclEyeDepth - 0.02) discard;
    }
  }
`;function Up(e,t,n={}){if(n.occlusion===!1||!e||!t)return!1;if(t.depthUsage!==`gpu-optimized`||typeof globalThis.XRWebGLBinding!=`function`)return L(`depthOcclusion`,!1),!1;try{let n=e.getContext();Q.binding=new globalThis.XRWebGLBinding(t,n),Q.renderer=e;let r=new he;r.minFilter=ie,r.magFilter=ie,r.generateMipmaps=!1,r.flipY=!1,Q.depthTexture=r,Q.uniforms={uDepthTexture:{value:r},uUvTransform:{value:new Ke},uRawValueToMeters:{value:.001},uDepthActive:{value:0}},Q.active=!0,k.occlusion={active:!0,disable:Gp},L(`depthOcclusion`,!0);for(let e of k.placedObjects||[])Kp(e);return A(`object-placed`,e=>Kp(e?.object)),t.addEventListener(`end`,Gp,{once:!0}),E(`Depth occlusion active — virtual objects hide behind real surfaces (Quest depth sensing).`,`Occlusion`),!0}catch(e){return console.warn(`Depth occlusion init failed; continuing without it:`,e?.message||e),Gp(),!1}}function Wp(e,t){if(!(!Q.active||!e||!t))try{let e=Q.binding.getDepthInformation(t);if(!e||!e.texture){Q.uniforms.uDepthActive.value=0;return}let n=Q.renderer.properties.get(Q.depthTexture);n.__webglTexture=e.texture,n.__webglInit=!0,Q.uniforms.uUvTransform.value.fromArray(e.normDepthBufferFromNormView.matrix),Q.uniforms.uRawValueToMeters.value=e.rawValueToMeters,Q.uniforms.uDepthActive.value=1}catch{Q.uniforms.uDepthActive.value=0}}function Gp(){Q.active=!1,Q.uniforms&&(Q.uniforms.uDepthActive.value=0),k.occlusion&&(k.occlusion.active=!1),L(`depthOcclusion`,!1)}function Kp(e){!Q.active||!e?.traverse||e.traverse(e=>{if(!e.isMesh)return;let t=Array.isArray(e.material)?e.material:[e.material];for(let e of t)qp(e)})}function qp(e){if(!e||Q.patched.has(e)||!e.isMeshStandardMaterial&&!e.isMeshPhysicalMaterial&&!e.isMeshLambertMaterial&&!e.isMeshPhongMaterial)return;Q.patched.add(e);let t=e.onBeforeCompile;e.onBeforeCompile=(e,n)=>{typeof t==`function`&&t(e,n),Object.assign(e.uniforms,Q.uniforms),e.vertexShader=e.vertexShader.replace(`#include <common>`,`#include <common>
  varying vec4 vOcclClip;
  varying float vOcclEyeDepth;`).replace(`#include <project_vertex>`,`#include <project_vertex>
  vOcclClip = gl_Position;
  vOcclEyeDepth = -mvPosition.z;`),e.fragmentShader=e.fragmentShader.replace(`#include <common>`,Vp+`
#include <common>`).replace(`#include <dithering_fragment>`,Hp+`
#include <dithering_fragment>`)},e.needsUpdate=!0}window.THREE=He,window.addEventListener(`deviceorientation`,e=>{if(globalThis.JARVIS_AR&&globalThis.JARVIS_AR.runtime&&globalThis.JARVIS_AR.runtime.camera){let{alpha:t,beta:n,gamma:r}=e;if(t!=null&&n!=null&&r!=null){let e=new window.THREE.Euler(y.degToRad(n),y.degToRad(t),y.degToRad(-r),`YXZ`);globalThis.JARVIS_AR.runtime.camera.quaternion.setFromEuler(e)}}});var $=Vt();k.config=$;try{globalThis.JARVIS_AR=k,globalThis.JarvisWebAR={state:k,start:um,resume:bm,pause:xm,destroy:Sm,setNativeOptions:wm,applyNativeState:Tm,command:Nm,spawn:e=>j(`spawn-model`,{query:e})}}catch{}var Jp=0,Yp=!1,Xp=null,Zp=!1,Qp=!1,$p=!1,em=!1,tm=null,nm=new Promise(e=>{tm=e}),rm=!1;function im(){Yp=!0,tm?.(!0),mt(Jp),O(`8th Wall engine loaded.`,30),$.autoStart||tt(`Engine ready`),$.autoStart&&um()}am();function am(){if(em)return;if(em=!0,document.visibilityState===`visible`){om();return}O(`Waiting for this tab to become visible...`,8);let e=()=>{document.visibilityState===`visible`&&(document.removeEventListener(`visibilitychange`,e),om())};document.addEventListener(`visibilitychange`,e)}async function om(){if($p)return;if(document.visibilityState!==`visible`){am();return}if($p=!0,ut(`ar-core`,{entrypoint:`ar-core/ar-init.js`,force:!0}),ct(`booting`),M(`booting`),document.body.dataset.jarvisBoot=`booting`,k.telemetry.startedAt=performance.now(),O(`Running AR preflight audit...`,10),!Bt()){ct(`blocked`,{reason:`https-required`}),M(`blocked`,{reason:`https-required`});return}await sm($),Em(),P(`capability-matrix`,`ready`,k.capabilities),gn(),P(`panels`,`ready`),kl(),P(`vr`,`ready`),Iu(),cd(),P(`media-viewer`,`ready`),ji(),P(`spatial-audio`,`ready`),Cd(),P(`reconstruction`,`ready`),P(`physics`,`initializing`);let e=()=>{ea().then(()=>P(`physics`,`ready`)).catch(e=>{console.error(`[AR Physics] initialization failed — physics disabled:`,e),P(`physics`,`failed`,{error:String(e?.message||e)})})};typeof requestIdleCallback==`function`?requestIdleCallback(e,{timeout:5e3}):setTimeout(e,2e3),jp(),P(`vision`,`ready`),km(),lm(),Dm(),await Yt($);try{t(async()=>{let{initVrStereoSplitScreen:e}=await import(`./ar-compositor-B1P8XIyr.js`);return{initVrStereoSplitScreen:e}},[],import.meta.url).then(({initVrStereoSplitScreen:e})=>{let{renderer:t,scene:n,camera:r}=z();e(t,n,r),console.log(`V15 AR: Stereo split-screen mounted.`)})}catch(e){console.error(`V15 AR Stereo Mount failed:`,e)}N(`scene`,!0),P(`scene`,`ready`,{renderer:k.runtime.rendererOwner}),tn(),P(`adaptive-quality`,`ready`),Pt(z(),{mode:`boot-proxy`,tier:k.telemetry.qualityTier||`medium`}),bo(),P(`models`,`ready`),Om(),P(`jarvis`,`ready`),O(`Waiting for 8th Wall engine binary...`,22),rm||(rm=!0,window.addEventListener(`xrloaded`,im,{once:!0})),globalThis.XR8&&(Yp=!0,tm?.(!0),mt(Jp),O(`8th Wall engine loaded.`,30),$.autoStart||tt(`Engine ready`),$.autoStart&&um()),Jp=pt(()=>{Yp||E(`8th Wall is still loading. Holding real AR start instead of silently dropping into basic camera mode.`,`8th Wall Loading`)},4500),$.command&&(k._commandBootTimer=pt(()=>Nm($.command),1200)),document.body.dataset.jarvisBoot=`ready`,N(`boot`,!0),N(`ui`,!0),ct(`ready`),M(`ready`)}function sm(e={}){if(globalThis.XR8)return Promise.resolve(!0);let t=document.getElementById(`jarvis-xr-static`);return t?t.dataset.loadFailed===`true`?cm(e):new Promise(n=>{t.addEventListener(`load`,()=>{n(!0)},{once:!0}),t.addEventListener(`error`,()=>{t.dataset.loadFailed=`true`,cm(e).then(n)},{once:!0})}):cm(e)}function cm(e={}){if(globalThis.XR8)return Promise.resolve(!0);let t=String(e.xrScriptUrl||``).trim();return t?document.querySelector(`script[data-jarvis-xr-script]`)?Promise.resolve(!0):new Promise(e=>{let n=document.createElement(`script`);n.src=t,n.async=!0,n.defer=!0,n.crossOrigin=`anonymous`,n.dataset.jarvisXrScript=`true`,n.setAttribute(`data-preload-chunks`,`slam`),n.addEventListener(`load`,()=>e(!0),{once:!0}),n.addEventListener(`error`,()=>{E(`Configured 8th Wall binary failed to load. The runtime will fall back instead of hanging on a dead CDN pin.`,`8th Wall Loading`),e(!1)},{once:!0}),document.head.appendChild(n)}):Promise.resolve(!1)}function lm(){document.getElementById(`start-ar`)?.addEventListener(`click`,e=>{let t=e.currentTarget;t.disabled=!0,t.textContent=`STARTING...`,um()}),document.getElementById(`camerafeed`)?.addEventListener(`click`,()=>{k.started||um()})}async function um(){return Zp||Xp?Xp:k.runtime.lifecycleState===`running`?!0:(Zp=!0,ut(`ar-core`,{entrypoint:`ar-core/ar-init.js`}),ct(`starting`),M(`starting`),O(`Starting real AR camera...`,34),k._cameraAcquired=!1,Xp=(async()=>{try{let e=await dm(3e4);return k._commandBootTimer&&(mt(k._commandBootTimer),k._commandBootTimer=null),e&&fm()?await pm():e?(T(`This device or browser is not supported by the 8th Wall SLAM engine (it needs a mobile browser with motion sensors). Running the fallback tracking path instead.`,`Using fallback tracking`,{timeout:0}),await gm()):(T(`8th Wall engine binary did not load within 30 seconds. Running fallback with reduced tracking.`,`8th Wall Timeout`,{timeout:0}),await gm()),_n(),Tc().catch(e=>T(e.message,`Gesture Startup Failed`)),hp(),sn(),k.started=!0,N(`camera`,!!(k.cameraVideo||k.xrStarted||k.xrSession)),N(`tracking`,!!(k.trackingMode&&k.trackingMode!==`standby`)),ct(`running`,{trackingMode:k.trackingMode}),M(`running`,{trackingMode:k.trackingMode}),wt(`AR runtime started: ${k.trackingMode}`),!0}catch(e){k.runtime.lastError=e?.message||String(e),k.runtime.degradationReason=k.runtime.lastError,ct(`degraded`,{error:k.runtime.lastError}),M(`degraded`,{error:k.runtime.lastError}),T(e.message,`AR Startup Failed`,{timeout:0}),k._commandBootTimer&&(mt(k._commandBootTimer),k._commandBootTimer=null);let t=await ym();return _n(),t?(k.started=!0,N(`camera`,!0),N(`tracking`,!0),M(`degraded-running`,{trackingMode:k.trackingMode,reason:k.runtime.degradationReason}),!0):(k.started=!1,Xp=null,M(`failed`,{error:k.runtime.lastError}),!1)}finally{Zp=!1}})(),Xp)}async function dm(e){if(globalThis.XR8&&Yp)return!0;O(`Waiting for 8th Wall SLAM engine...`,36);let t=new Promise(t=>pt(()=>t(!1),e));return!!(await Promise.race([nm,t])&&globalThis.XR8)}function fm(){try{let e=globalThis.XR8?.XrDevice;if(!e?.isDeviceBrowserCompatible||e.isDeviceBrowserCompatible())return!0;let t=``;try{let n=e.incompatibleReasons?e.incompatibleReasons():null,r=e.deviceEstimate?e.deviceEstimate():null;t=` (reasons: ${JSON.stringify(n)}, os: ${r?.os||`unknown`})`}catch{}return console.warn(`[AR] 8th Wall reports this device/browser is unsupported${t}. Using the fallback tracking path.`),k.runtime.degradationReason=`8thwall-device-unsupported`,!1}catch{return!0}}async function pm(){let e=globalThis.XR8;if(!e?.GlTextureRenderer?.pipelineModule)throw Error(`XR8.GlTextureRenderer.pipelineModule() is missing.`);if(!e?.Threejs?.pipelineModule)throw Error(`XR8.Threejs.pipelineModule() is missing.`);let t=document.getElementById(`camerafeed`);if(!t)throw Error(`Camera feed canvas was not found.`);e.addCameraPipelineModule({name:`app-camera-status`,onCameraStatusChange:({status:e})=>{e===`requesting`?(O(`Allow camera access to start AR...`,40),D(`status-camera`,`requesting`)):e===`hasStream`?(O(`Camera stream acquired. Initializing SLAM...`,52),D(`status-camera`,`stream`),k.runtime.permissionState=`granted`,k._cameraAcquired=!0,N(`camera`,!0)):e===`hasVideo`?(k._cameraAcquired=!0,O(`Camera live. Tracking world points...`,76),D(`status-camera`,`live`),k.runtime.permissionState=`granted`,N(`camera`,!0),nt()):e===`failed`&&(D(`status-camera`,`failed`),k.runtime.permissionState=`denied-or-failed`,k.runtime.degradationReason=`camera failed`,M(`permission-blocked`,{source:`xr8-camera`}),T(`Camera access failed. Check browser settings and allow camera for this browser.`,`Camera Failed`,{timeout:0,linkHref:`intent://settings#Intent;scheme=android-app;end`,linkLabel:`Open Chrome Android settings`}))}});let n=[e.GlTextureRenderer.pipelineModule(),Rt.FullWindowCanvas.pipelineModule(),e.Threejs.pipelineModule(),e.XrController.pipelineModule({enableWorldPoints:!0,disableWorldTracking:!1,imageTargets:Array.isArray($.imageTargets)?$.imageTargets:[]}),...e.CameraPixelArray?.pipelineModule?[e.CameraPixelArray.pipelineModule({maxDimension:480}),Kc()]:[],Rt.AlmostThere.pipelineModule(),Rt.Loading.pipelineModule(),Rt.RuntimeError.pipelineModule(),gd(),Id()];k.pipelineOrder=[`app-camera-status`,`XR8.GlTextureRenderer`,...n.slice(1).map(e=>e.name)],k.trackingAPI={getTrackingQuality:Qd,registerAnchor:qd,unregisterAnchor:Jd,performHitTest:Zd,requestRelocalization:$d},e.addCameraPipelineModules(n),e.run({canvas:t,webgl2:!0,ownRunLoop:!0,glContextConfig:{alpha:!0,preserveDrawingBuffer:!0,powerPreference:`high-performance`},cameraConfig:{direction:e.XrConfig.camera().BACK}}),k.xrStarted=!0,k.xrAvailable=!0,L(`eightWallSLAM`,!0),k.trackingMode=`8thwall-slam`,await mm(12e3),await hm();let r=kt()||z();dt(`xr8-threejs`,r,{takeover:!0,engine:`8thwall-slam`}),Pt(r,{mode:`xr8-session`,session:k.xrSession,tier:k.telemetry.qualityTier||`high`,stereo:!1,depthComposition:!0,frameBudgetMs:13.5,guardianProxy:!!$.guardianProxy}),P(`xr8`,`running`,{pipelineOrder:k.pipelineOrder}),$t(r.renderer,$),on(r.scene),At(r),N(`tracking`,!0),document.body.dataset.jarvisTracking=`8thwall-slam`,D(`status-tracking`,`8th wall`),Zt(),nt(),E(`8th Wall SLAM path started. Camera texture renderer is first in the render pipeline.`)}async function mm(e){if(k._cameraAcquired)return!0;let t=performance.now();for(;performance.now()-t<e;){if(k._cameraAcquired)return!0;if(k.runtime.permissionState===`denied-or-failed`)throw Error(`Camera access was denied or failed.`);await new Promise(e=>pt(e,250))}throw Error(`The camera did not start within ${Math.round(e/1e3)}s. The AR engine could not obtain a rear-facing camera stream.`)}async function hm(e=2200){let t=0,n=performance.now();for(;performance.now()-n<e&&t<132;){try{let e=globalThis.XR8?.Threejs?.xrScene?.();if(e?.scene&&e?.camera&&e?.renderer)return e}catch{}t++,await new Promise(e=>requestAnimationFrame(e))}return t>=132&&console.warn(`Timed out without a valid XR scene — returning null.`,132),null}async function gm(){if(k.trackingMode=`webxr-fallback`,document.body.dataset.jarvisTracking=`webxr-fallback`,D(`status-tracking`,`webxr/basic`),!(`xr`in navigator&&navigator.xr))return ym();try{if(!await navigator.xr.isSessionSupported(`immersive-ar`))return ym();let{renderer:e}=z(),t=await Promise.race([navigator.xr.requestSession(`immersive-ar`,{requiredFeatures:[`hit-test`],optionalFeatures:[`dom-overlay`,`light-estimation`,`depth-sensing`,`local-floor`,`anchors`,`bounded-floor`,`hand-tracking`,`unbounded`],depthSensing:{usagePreference:[`gpu-optimized`],dataFormatPreference:[`luminance-alpha`]},domOverlay:{root:document.getElementById(`ui-layer`)}}),new Promise((e,t)=>pt(()=>t(Error(`WebXR session request timed out`)),5e3))]);e.xr.enabled=!0,e.xr.setSession(t),_m(e,t),vm(e,t),Up(e,t,$);let n=await t.requestReferenceSpace(`viewer`);return k.xrHitTestSource=await t.requestHitTestSource({space:n}),k.xrSession=t,t.addEventListener(`end`,()=>{if(k.xrSession===t){k.xrSession=null,k.xrStarted=!1;try{e.setAnimationLoop(null)}catch{}Bp(),Dt(),k.started&&M(`degraded`,{reason:`webxr-session-ended`})}},{once:!0}),dt(`webxr-threejs`,{scene:k.scene,camera:k.camera,renderer:e},{takeover:!0,engine:`webxr-fallback`}),Pt({scene:k.scene,camera:k.camera,renderer:e},{mode:`webxr-session`,session:t,stereo:!1,depthComposition:!0,source:k.cameraVideo||document.getElementById(`camerafeed`)}),P(`webxr`,`running`),L(`webXRHitTest`,!0),Ot(),e.setAnimationLoop((t,n)=>{if(n&&(k.xrFrame=n,Rp(n,e),k.occlusion?.active)){let t=e.xr.getReferenceSpace?.(),r=t?n.getViewerPose?.(t):null;r?.views?.length&&Wp(n,r.views[0])}let r=k.scene||k.fallbackScene,i=k.camera||k.fallbackCamera;r&&i&&e.render(r,i)}),At(z()),N(`camera`,!0),N(`tracking`,!0),nt(),E(`Running WebXR fallback. 8th Wall SLAM is not active in this session.`),!0}catch(e){return T(e.message,`WebXR Fallback Failed`),ym()}}function _m(e,t){try{let n=k.scene||z()?.scene;if(!n||!e)return;let r=new Se(e);k.xrEstimatedLight=r;let i=n.environment;r.addEventListener(`estimationstart`,()=>{n.add(r),i=n.environment,r.environment&&(n.environment=r.environment),k.telemetry.iblEnvironment=`xr-light-estimation`,L(`lightEstimation`,!0)}),r.addEventListener(`estimationend`,()=>{try{n.remove(r)}catch{}n.environment=i,k.telemetry.iblEnvironment=n.userData?.jarvisEnvironmentSource||`room-default`}),t.addEventListener(`end`,()=>{try{n.remove(r)}catch{}n.environment=i,k.xrEstimatedLight=null},{once:!0})}catch(e){console.warn(`XR light estimation setup failed:`,e?.message||e)}}function vm(e,t){let n=t=>{try{let n=k.xrFrame,r=e?.xr?.getReferenceSpace?.(),i=t.inputSource,a=i?.targetRaySpace;if(!n||!r||!a)return;let o=n.getPose?.(a,r);if(!o)return;let s=o.transform.matrix,c={x:s[12],y:s[13],z:s[14]},l={x:-s[8],y:-s[9],z:-s[10]};try{i.gamepad?.hapticActuators?.[0]?.pulse?.(.4,40)}catch{}let u=ws({origin:c,direction:l});u&&(k.telemetry.lastXRSelect=u.type)}catch(e){console.warn(`XR select handling failed:`,e?.message||e)}};t.addEventListener(`select`,n),t.addEventListener(`end`,()=>{try{t.removeEventListener(`select`,n)}catch{}},{once:!0})}async function ym(){k.trackingMode=`manual-camera`,L(`manualCamera`,!0),document.body.dataset.jarvisTracking=`manual-camera`,D(`status-tracking`,`basic camera`),O(`Starting basic camera mode...`,48);try{Cm();let e=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:`environment`},width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},audio:!1}),t=document.createElement(`video`);t.srcObject=e,t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.setAttribute(`playsinline`,``),t.style.cssText=`position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;z-index:0;background:#000`,document.body.insertBefore(t,document.body.firstChild),await t.play(),k.cameraVideo=t,k.runtime.permissionState=`granted`;try{return dt(`fallback-three`,z(),{takeover:k.runtime.rendererOwner!==`xr8-threejs`,engine:`manual-camera`}),P(`manual-camera`,`running`),Pt(z(),{mode:`manual-camera`,stereo:!1,source:k.cameraVideo||document.getElementById(`camerafeed`),frameBudgetMs:20}),Dt(),At(z()),D(`status-camera`,`live`),N(`camera`,!0),N(`tracking`,!0),nt(),E(`Basic camera mode is active. Surface placement uses estimated floor fallback.`),!0}catch(e){return k.runtime.permissionState=`failed`,k.runtime.degradationReason=e?.message||String(e),T(`Manual camera fallback setup failed: ${e?.message||String(e)}`,`Manual Camera Setup Failed`,{timeout:0}),Cm(),!1}}catch(e){return k.runtime.permissionState=e.name===`NotAllowedError`?`denied`:`failed`,k.runtime.degradationReason=e?.message||String(e),M(e.name===`NotAllowedError`?`permission-blocked`:`failed`,{error:k.runtime.degradationReason}),e.name===`NotAllowedError`?T(`Camera permission denied. Please allow camera access.`,`Camera Denied`,{timeout:0}):e.name===`NotFoundError`?T(`No camera found on this device.`,`Camera Missing`,{timeout:0}):T(`Camera error: ${e.message}`,`Camera Error`,{timeout:0}),!1}}function bm(){if(k.runtime.lifecycleState===`stopped`)return!1;if(k.paused=!1,k.xrStarted)try{globalThis.XR8?.resume?.()}catch{E(`8th Wall resume was not available in this browser session.`,`Lifecycle`)}try{k.cameraVideo?.play?.()}catch{}return!k.xrStarted&&k.fallbackRenderer&&Dt(),document.body.dataset.jarvisPaused=`false`,sn(),M(k.started?`running`:`ready`,{reason:`resume`}),wt(`AR runtime resumed`),!0}function xm(e=`manual`){if(k.paused=!0,k.xrStarted)try{globalThis.XR8?.pause?.()}catch{E(`8th Wall pause was not available in this browser session.`,`Lifecycle`)}try{k.cameraVideo?.pause?.()}catch{}return Ot(),document.body.dataset.jarvisPaused=`true`,M(`paused`,{reason:e}),wt(`AR runtime paused`),!0}async function Sm(){xm(`shutdown`),k._commandBootTimer&&(mt(k._commandBootTimer),k._commandBootTimer=null),Dc(),ql(),On(),ef(),Ot();try{await k.xrSession?.end?.()}catch{}try{let e=z()?.renderer;e?.xr&&await e.xr.setSession(null)}catch{}try{typeof globalThis.XR8?.clearCameraPipelineModules==`function`&&globalThis.XR8.clearCameraPipelineModules(),globalThis.XR8?.stop?.()}catch{}return Cm(),document.querySelectorAll(`#ui-layer .ar-panel, #ui-layer .panel-orb, #error-host > *, #banner-host > *`).forEach(e=>e.remove()),It(),lt(),Xp=null,wt(`AR runtime shut down`),!0}function Cm(){try{(k.cameraVideo?.srcObject)?.getTracks?.().forEach(e=>e.stop()),k.cameraVideo?.remove?.()}catch{}k.cameraVideo=null}function wm(e={}){k.nativeOptions={...k.nativeOptions,...e&&typeof e==`object`?e:{}},document.body.dataset.jarvisNativeOptions=`applied`,k.nativeOptions.handTrackingEnabled===!1&&E(`Native options disabled hand tracking for this AR session.`,`APK Options`),(k.nativeOptions.thermalPause===!0||k.nativeOptions.thermalState===`critical`)&&(xm(`thermal`),k.runtime.degradationReason=`thermal`,M(`thermal-paused`,{thermalState:k.nativeOptions.thermalState||`critical`}));for(let e of[`eyeTracking`,`nativeCompositor`,`truePersistentWorldAnchors`,`nativeOpenXRBridge`])Object.prototype.hasOwnProperty.call(k.nativeOptions,e)&&L(e,k.nativeOptions[e]);return Object.prototype.hasOwnProperty.call(k.nativeOptions,`truePersistentWorldAnchors`)&&L(`persistentAnchorSupport`,k.nativeOptions.truePersistentWorldAnchors),R(`setCompositorState`,JSON.stringify({mode:k.compositor.mode,native:k.compositor.native,passthroughBlend:k.compositor.passthroughBlend,frameBudgetMs:k.compositor.frameBudgetMs,browserManaged:!0})),j(`native-options`,k.nativeOptions),wt(`APK AR options applied`),k.nativeOptions}function Tm(e={}){let t=e;try{t=typeof e==`string`?JSON.parse(e):e}catch(e){return T(e.message,`APK State Sync Failed`),!1}let n=Array.isArray(t)?t:Array.isArray(t?.objects)?t.objects:t?.ar_objects;return Array.isArray(n)&&(j(`native-ar-state`,{objects:n}),R(`status`,`Applied ${n.length} native AR object(s)`)),t?.ui&&typeof t.ui==`object`&&j(`native-ui-state`,t.ui),!0}function Em(){let e=qt();bt(e),k.runtime.browserProfile=e,L(`mediaPipeHands`,!!globalThis.Hands),L(`spatialAudio`,!!(globalThis.AudioContext||globalThis.webkitAudioContext)),L(`microphone`,!!navigator.mediaDevices?.getUserMedia),L(`speechSynthesis`,!!window.speechSynthesis),L(`voiceRecognition`,!!(globalThis.SpeechRecognition||globalThis.webkitSpeechRecognition)),L(`webXRAvailable`,!!navigator.xr),L(`webXRHitTest`,!1),L(`browserLatencyCeiling`,!0),L(`limitedSensorAccess`,!0),L(`limitedOSIntegration`,!0),L(`limitedCompositorControl`,!0),L(`persistentAnchorSupport`,!!$.truePersistentWorldAnchors),L(`backgroundExecutionLimited`,!0),L(`passthroughControlLimited`,!0),L(`spatialMemoryLimited`,!0),L(`headsetOptimizationAccessLimited`,!0),L(`webXRFragmented`,e.webXRFragmented),L(`safariWebXRLimitations`,e.limits.safariWebXRLimitations),L(`visionOSBrowserRestrictions`,e.limits.visionOSBrowserRestrictions),L(`androidBrowserInconsistency`,e.limits.androidBrowserInconsistency),L(`webViewInconsistency`,e.limits.webViewInconsistency),L(`questBrowserQuirks`,e.limits.questBrowserQuirks),L(`fullscreenEdgeCases`,e.limits.fullscreenEdgeCases),L(`orientationLockEdgeCases`,e.limits.orientationLockEdgeCases),L(`webglContextLossRisk`,e.limits.webglContextLossRisk),L(`renderLoopDuplicationRisk`,e.limits.renderLoopDuplicationRisk),L(`eyeTracking`,!!$.eyeTracking),L(`nativeCompositor`,!!$.nativeCompositor),L(`truePersistentWorldAnchors`,!!$.truePersistentWorldAnchors),L(`nativeOpenXRBridge`,!!$.nativeOpenXRBridge),L(`eyeTrackingProxy`,!0),L(`persistentSpatialMemory`,!0),L(`ultraStableAnchoring`,!0),L(`naturalWindowPlacement`,!0),L(`depthAwareImmersion`,!0),L(`environmentAwareUI`,!0),L(`headsetComfortSystems`,!0),L(`lowLatencyCompositing`,!0),document.body.dataset.jarvisCapabilityModel=`browser-web-ar-with-explicit-native-limits`,document.body.dataset.jarvisBrowserProfile=e.browser,document.body.dataset.jarvisBrowserPlatform=e.platform,document.body.dataset.jarvisBrowserLatency=String(e.latencyCeilingMs);let t=Jt(e).filter(e=>/safari|visionos|android|webview|webxr-fragmented|quest/.test(e));xt({architecture:`browser-web-ar-runtime`,experienceClass:`web-ar-experiment`,spatialRuntimeClass:e.isVisionOS?`browser-managed-visionos-shell`:e.isQuest?`quest-browser-ar-shell`:e.isSafari?`safari-webxr-shell`:e.isWebView?`embedded-webview-ar-shell`:`browser-web-ar-shell`,platformRole:e.isVisionOS?`visionos-browser`:e.isQuest?`quest-browser`:e.isAndroid?`android-browser`:e.isIOS?`ios-browser`:`desktop-browser`,spatialGapStatement:e.isVisionOS||e.isSafari||e.isWebView||e.isAndroid?`This runtime is browser-managed spatial AR, not a native headset OS, compositor, or persistent spatial shell.`:`This runtime is browser-managed spatial AR, not a unified native spatial computing runtime.`}),St([`No single authoritative native spatial runtime exists in this codebase.`,`Browser-layer AR, XR8/WebXR, fallback cameras, and compatibility shells coexist behind one shared authority instead of a native OS compositor stack.`,`Persistent world understanding, headset compositor control, and headset-grade platform integration remain unavailable because the runtime is bounded by browser APIs and vendor binaries.`,`Lifecycle and rendering governance must therefore be centralized in the web runtime, not spread across competing engines.`].join(` `)),Ct(`Vision Pro-style browser shell implemented as far as the web stack allows: gaze proxy, hand-eye fusion, persistent spatial memory, stabilized anchoring, low-latency compositor hints, natural window placement, depth-aware immersion, environment-aware UI, and comfort systems are active; true native eye tracking, headset OS integration, and native compositor control remain outside the browser runtime.`,[`gaze proxy`,`hand-eye fusion`,`persistent spatial memory`,`ultra-stable anchoring`,`low-latency compositing proxy`,`natural window placement`,`depth-aware immersion`,`environment-aware UI`,`headset comfort systems`]),R(`setNativeCapabilities`,JSON.stringify({browserProfile:e,capabilities:k.capabilities,runtime:{architecture:k.runtime.architecture,spatialRuntimeClass:k.runtime.spatialRuntimeClass,platformRole:k.runtime.platformRole}})),R(`setGuardianState`,JSON.stringify({requested:!0,boundary:k.capabilities.guardianBoundary,platformRole:k.runtime.platformRole,source:`ar-init`})),R(`setOpenXRState`,JSON.stringify({supported:e.isQuest||e.isVisionOS,browserManaged:!0,platformRole:k.runtime.platformRole,compositor:k.compositor})),t.length&&(k.runtime.degradationReason=t.join(`, `),wt(`Browser limits: ${t.join(`, `)}`),e.limits.visionOSBrowserRestrictions?E(`visionOS browser support is browser-managed only. Native compositor, passthrough control, and persistent anchors stay unavailable here.`,`visionOS Browser Limits`):e.limits.safariWebXRLimitations?E(`Safari WebXR support is fragmented. Chrome Android remains the primary AR path for this runtime.`,`Safari WebXR Limits`):e.limits.webViewInconsistency?E(`Embedded WebViews can be stricter than Chrome Custom Tabs for XR, sensors, and camera permissions.`,`WebView Limits`):e.limits.questBrowserQuirks&&E(`Quest Browser fullscreen, orientation, and session behavior can be quirky; the runtime is applying extra guard rails.`,`Quest Browser Limits`))}function Dm(){Qp||(Qp=!0,document.addEventListener(`visibilitychange`,()=>{document.hidden?k.started&&xm(`background-tab`):k.started&&k.runtime.lifecycleState===`paused`&&bm()}),window.addEventListener(`pagehide`,()=>{k.started&&xm(`pagehide`)}),window.addEventListener(`pageshow`,()=>{k.started&&k.runtime.lifecycleState===`paused`&&bm()}))}function Om(){let e=new zf($).connect();mp();try{globalThis.Jarvis={query:t=>e.query(t),runTask:(t,n)=>e.runTask(t,n),command:e=>Nm(e)}}catch{k.jarvisGlobalBlocked=!0}A(`jarvis-command`,({text:e})=>Nm(e))}function km(){A(`VOICE_STATE`,e=>{k.spatialAudio.micPermission=e?.micPermission||k.spatialAudio.micPermission,k.spatialAudio.micReady=!!(e?.micReady||e?.enabled||e?.listening),k.spatialAudio.wakeWindowUntil=e?.wakeWindowUntil||0,k.spatialAudio.lastVoiceCommandAt=e?.lastCommandAt||k.spatialAudio.lastVoiceCommandAt,(e?.reason===`mic-error`||e?.reason===`blocked`)&&wt(`Voice mic ${e.error||e.micPermission||`blocked`}`)}),A(`open-jarvis`,Am),A(`open-games`,jm),A(`open-builder`,Sf),A(`scan-room`,()=>tp(`Scanning the room.`,{speak:!1}))}function Am(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`button`);t.placeholder=`Command JARVIS`,n.className=`btn-primary`,n.textContent=`Run`,n.onclick=()=>Nm(t.value),t.addEventListener(`keydown`,e=>{e.key===`Enter`&&n.click()}),e.append(t,n),new hn({title:`JARVIS`,body:e,icon:`J`,width:360,height:260}).focus()}function jm(){let e=document.createElement(`div`),t=Mm(`Eternum AR`,rf),n=Mm(`Ripples AR`,lf),r=document.createElement(`input`),i=Mm(`Convert Game URL`,()=>uf(r.value||`about:blank`,globalThis.Jarvis||k.jarvis));r.placeholder=`Game URL or name`,e.append(t,n,r,i),kn(`AR Games`,e,`G`)}function Mm(e,t){let n=document.createElement(`button`);return n.className=`panel-action`,n.textContent=e,n.onclick=t,n}async function Nm(e){let t=String(e||``).trim();if(!t)return;let n=t.toLowerCase();qf(Bf.THINKING);try{let e=n.match(/\b(open|close|toggle|rotate|spin|turn|reconfigure|rebuild|transform|rearrange|shatter|break|explode|reveal|show|hide|grab|move|drag)\b/);if(e&&/(model|door|window|screen|panel|roof|drawer|wheel|part|house|room|car|vehicle|device|custom)/.test(n)){let r=n.replace(/\b(hey\s+jarvis|jarvis)\b/gi,``).replace(/\b(open|close|toggle|rotate|spin|turn|reconfigure|rebuild|transform|rearrange|shatter|break|explode|reveal|show|hide|grab|move|drag|the|a|an|model|part|on|of|in|for|to)\b/gi,` `).replace(/\s+/g,` `).trim();j(`jarvis-model-action`,{action:e[1],target:r,command:t,source:`voice`}),tp(`Model action queued: ${e[1]}${r?` on ${r}`:``}.`,{speak:!0});return}if(/spawn|place|load|model/.test(n)){let e=n.replace(/\b(spawn|place|load|model|a|an|the|in ar)\b/g,` `).trim()||`Duck`;j(`spawn-model`,{query:e}),tp(`Model armed: ${e}. Tap a surface to place it.`,{speak:!0});return}if(/scan room|room scan|scan/.test(n)){j(`scan-room`);return}if(/reconstruct/.test(n)){let e=n.replace(`reconstruct`,``).replace(`this scene`,``).trim()||`room`;await wd(e),tp(`Scene reconstruction complete: ${e}.`,{speak:!0});return}if(/vr mode|vr screen|headset/.test(n)){await Al();return}if(/eternum/.test(n)){rf(),tp(`Eternum AR panel is open.`,{speak:!0});return}if(/ripples/.test(n)){lf(),tp(`Ripples AR panel is open.`,{speak:!0});return}if(/convert .* ar|game to ar/.test(n)){await uf(t.replace(/convert|to ar|game to ar/gi,``).trim(),globalThis.Jarvis||k.jarvis);return}if(/open models|model picker/.test(n)){Co();return}if(/forge model|interactive model|3d forge|custom interactive model|build custom model|custom 3d builder/.test(n)){j(`open-model-forge`),tp(`Interactive model forge opened.`,{speak:!0});return}if(/camera kit|lens studio|snap/.test(n)){let e=document.createElement(`div`);e.style.cssText=`display:flex;flex-direction:column;gap:10px;padding:8px 0`;let t=document.createElement(`p`);t.style.cssText=`margin:0;font-size:13px;opacity:0.75;line-height:1.4`,t.textContent=`Lens Studio Camera Kit requires a Snap developer token. Enter yours below to activate the Camera Kit AR layer.`;let n=document.createElement(`label`);n.textContent=`Snap Developer Token`,n.style.cssText=`font-size:12px;font-weight:600;opacity:0.9`;let r=document.createElement(`input`);r.type=`text`,r.placeholder=`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`,r.style.cssText=`width:100%;box-sizing:border-box;padding:8px 10px;border-radius:6px;border:1px solid rgba(255,255,255,0.2);background:rgba(255,255,255,0.08);color:var(--text-primary);font-size:13px`,k.config.snapToken&&(r.value=k.config.snapToken);let i=document.createElement(`button`);i.className=`btn-primary`,i.textContent=`Activate Camera Kit`,i.onclick=()=>{let e=r.value.trim();if(!e){E(`Please enter a valid Snap developer token.`,`Camera Kit`);return}k.config.snapToken=e,j(`camera-kit-token-set`,{token:e}),E(`Camera Kit token saved. Reload the AR session to activate the Lens Studio layer.`,`Camera Kit`),o.close?.()};let a=document.createElement(`a`);a.href=`https://docs.snap.com/snap-kit/camera-kit/guides/tutorials/integration-guides/web#set-up-your-api-token`,a.target=`_blank`,a.rel=`noopener noreferrer`,a.textContent=`How to get a Snap developer token ↗`,a.style.cssText=`font-size:12px;color:rgba(255,255,255,0.55);text-decoration:underline`,e.append(t,n,r,i,a);let o=new hn({title:`Camera Kit`,body:e,icon:`CK`,width:360,height:300});o.focus();return}tp(await(globalThis.Jarvis||k.jarvis).query(t),{speak:!0})}catch(e){T(e.message,`JARVIS Command Failed`)}finally{Gf()===Bf.THINKING&&qf(Bf.IDLE)}}export{Tm as applyNativeState,Ft as i,Lt as n,xm as pauseRuntime,It as r,bm as resumeRuntime,wm as setNativeOptions,Sm as shutdownRuntime,ym as startManualCameraFallback,Pt as t};