Spaces:
Running
Running
File size: 289,756 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 & 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.XRWebGLBinding==`function`&&typeof globalThis.XRWebGLBinding.prototype?.createEquirectLayer==`function`,a={maxTextureSize:n,webCodecs:r,webxrLayers:i,requestVideoFrameCallback:typeof HTMLVideoElement<`u`&&typeof HTMLVideoElement.prototype?.requestVideoFrameCallback==`function`,webAudio:typeof globalThis.AudioContext==`function`||typeof globalThis.webkitAudioContext==`function`,xr:!!navigator.xr};return J.deviceLimits=a,L(`mediaViewerMaxTextureSize`,n),L(`mediaViewerWebCodecs`,r),L(`mediaViewerWebXRLayers`,i),a}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`);Au({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){Cu();try{await i.play()}catch{E(`Tap play to start — this browser needs a gesture before it will play audio.`,`Media`)}Ou()}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(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 bu(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 xu(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 Su(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 Cu(){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 wu(){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 Tu(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 Eu(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 Du(){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 Ou(e=!1){if(!J.isVideo||!J.element)return null;let t=globalThis.AudioContext||globalThis.webkitAudioContext;if(!t)return{enabled:!1,reason:`No Web Audio API on this platform.`};let n=await Du();if(!(e||n.detected))return J.audio={enabled:!1,headphones:n,reason:`Defaulting to normal stereo output.`},J.audio;let r=J.audio?.ctx||new t,i=eu[J.environment],a=J.audio?.source||r.createMediaElementSource(J.element),o=new PannerNode(r,{panningModel:`HRTF`,distanceModel:`inverse`,positionX:0,positionY:J.screen.elevation||0,positionZ:-(J.screen.distance||3)}),s=r.createConvolver();s.buffer=Eu(r,i.reverb.seconds,i.reverb.decay);let c=r.createGain();c.gain.value=i.reverb.wet;let l=r.createGain();return l.gain.value=1-i.reverb.wet*.5,a.connect(o),o.connect(l).connect(r.destination),o.connect(s).connect(c).connect(r.destination),J.audio={enabled:!0,mechanism:`HRTF binaural rendering (Web Audio PannerNode + ConvolverNode)`,isDolbyAtmos:!1,sourceIsAmbisonic:!1,honestLabel:`Virtual/enhanced surround — reshapes existing channels, not true object-based 3D audio.`,ctx:r,source:a,panner:o,convolver:s,headphones:n,room:i.label},J.audio}function ku(e){let t=J.audio;if(!t?.enabled||!t.ctx||!e)return!1;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,mechanism:J.audio.mechanism||null,isDolbyAtmos:!1,headphones:J.audio.headphones,room:J.audio.room||null}:null,deviceLimits:J.deviceLimits,findings:J.findings.slice(),quality:wu()}}function Au({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 ju(){let e=gu(),t=()=>{let n=gu();n!==e&&(e=n,J.active&&J.packing!==`mono`&&J.element&&_u()),Zl=I(t)};Zl=I(t)}function Mu(){return ru(),ju(),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,Au()}),globalThis.JarvisMedia={open:mu,setProjection:yu,setPacking:bu,setEnvironment:xu,adjustScreen:Su,setAmbientResponse:Tu,setupSpatialAudio:Ou,updateAudioOrientation:ku,detectHeadphones:Du,getState:Y,getQualityReport:wu,probeDecodeCapability:ru,close:Au,PROJECTIONS:Ql,PACKINGS:$l,ENVIRONMENTS:eu,_math:{detectProjection:iu,detectPacking:ou,eyeUvRect:su,unpackedEyeSize:cu,computeScreenDimensions:pu,buildScreenGeometry:lu}},!0}var Nu={flat:`Flat`,180:`180`,360:`360`,fisheye:`Fisheye`},Pu={mono:`Mono`,"sbs-full":`SBS full`,"sbs-half":`SBS half`,"tb-full":`Top-bottom`,"tb-half":`TB half`},Fu={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,Iu=null,Lu=0,Ru=!1,zu=!1;function Bu(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 Vu(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 Hu(){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">
${Bu(`<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">
${Bu(`<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 Layers</dt><dd>${e.webxrLayers?`available`:`absent`}</dd>
</dl>
</div>
</div>
`,Iu=document.createElement(`input`),Iu.type=`file`,Iu.accept=`video/*,image/*`,Iu.style.cssText=`position:absolute;width:1px;height:1px;opacity:0;pointer-events:none`,X.appendChild(Iu),(document.getElementById(`ui-layer`)||document.body).appendChild(X),Wu(),ed(),X}function Uu(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=`${Bu(`<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 Wu(){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 Ku(t.dataset.format);if(t.dataset.packing)return void qu(t.dataset.packing);if(t.dataset.mode)return void Ju(t.dataset.mode);switch(t.dataset.mv){case`close`:return rd();case`browse`:case`drop`:return Iu.click();case`sw-audio`:Yu(t);return;case`sw-ambient`:Xu(t);return;case`sw-depth`:Zu(t);return;case`sw-surround`:Qu(t);return;default:return}}}),F(Iu,`change`,()=>{let e=Iu.files?.[0];e&&Gu(e)}),F(X,`dragover`,e=>{e.preventDefault()}),F(X,`drop`,e=>{e.preventDefault();let t=e.dataTransfer?.files?.[0];t&&Gu(t)}),$u(),gt(()=>rd())}async function Gu(e){try{await mu(e,{environment:Y().environment||`theater`}),ed(),nd(),E(`${e.name} is open.`,`Media`)}catch(e){T(e?.message||String(e),`Media`)}}function Ku(e){if(Ql.includes(e)){try{yu(e)}catch(e){T(e.message,`Media`)}ed()}}function qu(e){if($l.includes(e)){try{bu(e)}catch(e){T(e.message,`Media`)}ed()}}function Ju(e){if(eu[e]){try{xu(e)}catch(e){T(e.message,`Media`)}ed()}}async function Yu(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=await Ou(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 Xu(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=Tu(t);e.setAttribute(`aria-checked`,String(!!n)),t&&!n&&E(`Open a video first — ambient response reads the playing frame.`,`Media`)}function Zu(e){zu=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),zu&&(E(`AI 3D depth needs the depth model installed on the Space. The control is here; the engine is not ready yet.`,`Not available`),zu=!1)}function Qu(e){Ru=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),Uu(!1),Ru&&(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`),Ru=!1)}function $u(){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`)Su(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`)Su(e===`h-dist`?{distance:r.distance+n}:{width:r.width+n});else return;t.preventDefault(),td()}))}),F(e,`pointermove`,e=>{if(!(!t||!n)){if(t===`h-dist`){let t=(e.clientY-n.y)/26;Su({distance:Math.max(1,n.distance+t)})}else{let r=(t===`h-right`?1:-1)*(e.clientX-n.x)/26;Su({width:Math.max(.5,n.width+r*2)})}td()}});let i=()=>{t=null,n=null};F(e,`pointerup`,i),F(e,`pointercancel`,i),F(window,`pointerup`,i)}function ed(){if(!X)return;let e=Y();X.querySelector(`[data-mv="formats"]`).innerHTML=Vu(`format`,Ql,Nu,e.projection,e.projectionAuto),X.querySelector(`[data-mv="packings"]`).innerHTML=Vu(`packing`,$l,Pu,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}">${Bu(Fu[t])}${eu[t].label}</button>`).join(``);let t=X.querySelector(`[data-mv="mode-note"]`);t.textContent=e.roomSuppressed?`${Nu[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=`${Bu(`<path d="M20 6 9 17l-5-5"/>`,`mv-ok-icon`)}
<p><b>${e.fileName}</b> — ${e.sourceWidth}×${e.sourceHeight}.
Detected as <b>${Nu[e.projection]}</b> (${e.projectionWhy}) packed
<b>${Pu[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,td()}function td(){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 nd(){Lu&&clearInterval(Lu),Lu=setInterval(()=>{let e=X?.querySelector(`[data-mv="quality"]`);if(!e)return;let t=Y(),n=wu();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 rd(){return Lu&&(clearInterval(Lu),Lu=0),Uu(!1),Au(),X?.remove(),X=null,Iu=null,!0}function id(){return A(`open-media`,()=>Hu()),globalThis.JarvisMediaUI={open:Hu,close:rd,isOpen:()=>!!X,click:e=>{let t=X?.querySelector(e);return t?(t.click(),!0):!1}},!0}var ad=null,od=null,sd=null,cd=null,ld=new Float32Array(1e3*3),ud=new Ge;ud.setAttribute(`position`,new Ve(ld,3)),ud.setDrawRange(0,0);var dd=1e3;function fd(){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,pd(t))}}}function pd(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&&(md(k.worldPointBuffer),hd(k.worldPointBuffer))}}function md(e){if(!e.length)return;let{scene:t}=z(),n=Math.min(e.length,dd);for(let t=0;t<n;t+=1){let r=e[e.length-n+t];ld[t*3]=r.x,ld[t*3+1]=r.y,ld[t*3+2]=r.z}ud.attributes.position.needsUpdate=!0,ud.setDrawRange(0,n),ad||(cd=new te({color:51455,size:.018,transparent:!0,opacity:.55,depthWrite:!1}),ad=new oe(ud,cd),ad.name=`jarvis-room-point-cloud`,ad.scale.setScalar(1),t.add(ad))}function hd(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(!od){let e=new ae(10,10,20,20);od=new a(e,new x({color:51455,transparent:!0,opacity:.06,side:2,depthWrite:!1})),sd=new a(e,new x({color:51455,transparent:!0,opacity:.2,wireframe:!0,depthWrite:!1})),od.name=`jarvis-detected-floor`,sd.name=`jarvis-detected-floor-wire`,od.rotation.x=-Math.PI/2,sd.rotation.x=-Math.PI/2,l.add(od,sd)}od.position.y=c,sd.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 gd(){k.worldPointBuffer.length<10&&_d(),md(k.worldPointBuffer),hd(k.worldPointBuffer)}function _d(){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 vd={forest:[`Fox`,`Lantern`,`BarramundiFish`],lab:[`DamagedHelmet`,`AntiqueCamera`,`ReciprocatingSaw`],room:[`GlamVelvetSofa`,`WaterBottle`,`IridescenceLamp`],street:[`CesiumMilkTruck`,`ToyCar`,`Lantern`],default:[`Duck`,`Avocado`,`WaterBottle`]};function yd(){A(`scan-room`,()=>{gd(),E(`Room mesh scan updated from 8th Wall world points or basic fallback points.`,`Room Scan`)}),Sd()}async function bd(e=`room`){let t=String(e||`room`).toLowerCase(),n=vd[t]||vd.default;gd();let r=Math.min(3,Math.max(1,n.length));E(`Reconstructing ${t} scene with ${r} parallel model loads.`,`Scene Reconstruction`);try{await xd(t)}catch(e){T(e.message,`HDR Environment Failed`)}let i=(await Cd(n.map((e,t)=>async()=>{let r=t/n.length*Math.PI*2;return wd(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 xd(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 Sd(){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 Cd(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 wd(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 Td=.35,Ed=.65,Dd=.18,Od=8,kd=4,Ad=12,jd=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 Md(){return{name:`jarvis-tracking-quality`,onUpdate:({processCpuResult:e,processGpuResult:t})=>{Z.totalFrames++;let n=e?.reality||t?.reality||e||t,r=Nd(n),i=Pd(n);i&&(Z.confidence=Z.confidence*.85+r*.15,Z.qualityTier=Fd(Z.confidence),k.trackingQuality=Z.qualityTier,document.body.dataset.jarvisTrackingQuality=Z.qualityTier,Z.confidence<Td?(Z.lostFrames++,Z.goodFrames=0,!Z.isLost&&Z.lostFrames>=Od&&Vd()):(Z.goodFrames++,Z.lostFrames=0,Z.isLost&&Z.goodFrames>=kd&&Hd(i)),!Z.isLost&&(Rd(i),Z.worldOriginLocked||Bd(Z.smoothedPosition,Z.smoothedQuaternion),Gd(),Z.confidence>=Ed&&(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 Nd(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 Pd(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 Fd(e){return e>=.8?`excellent`:e>=.6?`good`:e>=.38?`fair`:e>=.15?`poor`:`initializing`}var Id=new w,Ld=new C;function Rd(e){let{position:t,orientation:n}=e;Id.set(Math.fround(t.x??0),Math.fround(t.y??0),Math.fround(t.z??0)),n&&Ld.set(n.x??0,n.y??0,n.z??0,n.w??1);let r=Dd*(1+(1-Z.confidence)*1.5),i=Math.min(r,.45);Z.smoothedPosition.lerp(Id,i),Z.smoothedPosition.set(Math.fround(Z.smoothedPosition.x),Math.fround(Z.smoothedPosition.y),Math.fround(Z.smoothedPosition.z)),n&&(Z.smoothedQuaternion.slerp(Ld,i),Z.smoothedQuaternion.normalize())}var zd=[];function Bd(e,t){if(Z.confidence<Ed){zd=[],Z.worldOriginSamples=0;return}zd.push({pos:e.clone(),quat:t.clone()}),zd.length>Ad&&zd.shift(),Z.worldOriginSamples=zd.length;let n=new w,r=new C;if(zd.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),zd.length===Ad){let e=0;zd.forEach(t=>{e+=t.pos.distanceToSquared(n)}),e/Ad<.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 Vd(){Z.isLost=!0,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,zd=[],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 Hd(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 Ud(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 Wd(e){Z.anchorRegistry.delete(e),j(`anchor-removed`,{id:e})}function Gd(){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>jd&&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 Kd(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 qd(e,t){if(Z.confidence<Td)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 Jd(){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 Yd(){Z.worldOriginLocked=!1,Z.worldOriginSamples=0,zd=[],Z.isLost=!1,Z.lostFrames=0,Z.goodFrames=0,E(`Relocalization requested — scanning environment.`,`Tracking`),j(`relocalization-requested`,{attempt:++Z.relocalizationAttempts})}function Xd(){Z.confidence=0,Z.qualityTier=`initializing`,Z.lostFrames=0,Z.goodFrames=0,Z.isLost=!1,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,zd=[],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&&Kd(k.worldPointBuffer)}),A(`runtime-phase`,({phase:e})=>{(e===`created`||e===`booting`)&&Xd()});var Zd=null,Qd=0;function $d(){return Zd||(Zd=yn(ef(`eternum`),`Eternum AR`,880,560),tf(Zd,[[`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`),Zd)}function ef(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 tf(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=()=>nf(e.iframe,r),n.appendChild(i)}),e.container.style.position=`relative`,e.container.appendChild(n)}async function nf(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)}-${++Qd}`;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 rf=null;function af(){if(rf)return rf;let e=new URLSearchParams(location.search);rf=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=()=>nf(rf.iframe,n),t.appendChild(r)}),rf.container.style.position=`relative`,rf.container.appendChild(t),E(`Ripples opened as a floating AR panel.`,`Ripples AR`),rf}async function of(e,t){let n=await sf(e,t),r=yn(lf(n.url||e),`${n.title||e} AR`,880,560);return pf(n.controls,r),r}async function sf(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(df(r));if(cf(i))return i}catch(e){T(e.message,`Game Schema AI Failed`)}return{title:e,url:lf(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 cf(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 lf(e){let t=String(e||``).trim();if(!t)return uf(`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 uf(t)}function uf(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">${ff(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 df(e){let t=e.indexOf(`{`),n=e.lastIndexOf(`}`);return t>=0&&n>t?e.slice(t,n+1):e}function ff(e){return String(e).replace(/[&<>"']/g,e=>({"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`})[e])}function pf(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=()=>nf(t.iframe,e.key||`Enter`),n.appendChild(r)}),t.container.style.position=`relative`,t.container.appendChild(n),n}var mf=`jarvis_ar_game_builder_graphs_v1`,hf=[`OnCollide`,`OnTap`,`OnGesture`,`OnTimerEnd`,`IsTag`,`IsHealth`,`IsDistance`,`Destroy`,`Spawn`,`MoveToward`,`SetScore`,`PlaySound`,`ShowMessage`,`EndGame`],gf=null,_f=null;function vf(){if(gf)return gf.restore(),gf;let e=document.createElement(`div`);e.append(yf()),gf=new hn({title:`AR Game Builder`,body:e,icon:`B`,width:400,height:600});let t=gf.destroy.bind(gf);return gf.destroy=()=>{_f?.dispose?.(),_f=null,t(),gf=null},gf.focus(),gf}function yf(){let e=document.createElement(`div`),t=document.createElement(`div`),n=document.createElement(`div`);return t.className=`panel-row`,Object.entries({Entities:bf,Logic:xf,Settings:Sf,Play:Cf}).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 bf(){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(mf,[]).at(-1)||kf();e.entities.push({id:gr(`entity`),name:t.value||`Entity`,tag:n.value||`default`}),Af(e),E(`Entity saved to AR game graph.`)},e.append(t,n,r,jf()),e}function xf(){let e=document.createElement(`div`),t=document.createElement(`select`),n=document.createElement(`input`),r=document.createElement(`button`);return _r(t,hf),n.placeholder=`Node value`,r.className=`panel-action`,r.textContent=`Add Logic Node`,r.onclick=()=>{let e=ur(mf,[]).at(-1)||kf();e.nodes.push({id:gr(`node`),type:t.value,value:n.value}),Af(e),E(`${t.value} node added.`)},e.append(t,n,r,jf()),e}function Sf(){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(mf,[]).at(-1)||kf();e.title=t.value||e.title,e.duration=Number(n.value||e.duration||60),Af(e),E(`Game settings saved.`)},e.append(t,n,r,jf()),e}function Cf(){let e=document.createElement(`div`),t=document.createElement(`button`);return t.className=`btn-primary`,t.textContent=`Spawn Saved Game`,t.onclick=()=>{let e=ur(mf,[]).at(-1);if(!e){E(`Create a game graph first.`);return}_f?.dispose?.(),_f=wf(e),E(`Game "${e.title}" spawned ${_f.entities.length} AR entity object(s).`,`Game Builder`)},e.append(t,jf()),e}function wf(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)=>Tf(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=Tf({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=Ef(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`)Of();else if(n===`endgame`)o=!0,E(`${e.title||`AR Game`} ended. Score: ${a}`,`Game Builder`);else if(n===`movetoward`){let e=Ef(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=Df(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 Tf(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 Ef(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 Df(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 Of(){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 kf(){return{id:gr(`game`),title:`Untitled AR Game`,duration:60,entities:[],nodes:[],createdAt:Date.now()}}function Af(e){let t=ur(mf,[]).filter(t=>t.id!==e.id);t.push(e),dr(mf,t.slice(-20))}function jf(){let e=document.createElement(`pre`),t=ur(mf,[]).at(-1)||kf();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 Mf(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 Nf(e,t={},n=0,r=1e4){let i=await Mf(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 Pf(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 Ff=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 Nf(`${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 Mf(`${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 Mf(`${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)):(Pf(this.pendingPatches,t),Mf(`${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{}})}},If={IDLE:`idle`,LISTENING:`listening`,THINKING:`thinking`,SPEAKING:`speaking`},Lf={listening:`👂`,thinking:`🧠`,speaking:`🔊`},Rf={listening:`LISTENING`,thinking:`THINKING`,speaking:`SPEAKING`},zf=If.IDLE,Bf=new Set;function Vf(){return zf}function Hf(e){return Bf.add(e),()=>Bf.delete(e)}function Uf(e){let t=String(e||``).toLowerCase();Object.values(If).includes(t)&&t!==zf&&(zf=t,Gf(),Bf.forEach(e=>{try{e(zf)}catch{}}))}function Wf(){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 Gf(){let e;try{e=Wf()}catch{return}if(!e)return;let t=e.querySelector(`[data-glyph]`),n=e.querySelector(`[data-label]`);if(zf===If.IDLE){e.style.opacity=`0`,e.style.transform=`translateX(-50%) translateY(-8px)`;return}t&&(t.textContent=Lf[zf]||``),n&&(n.textContent=Rf[zf]||``),e.style.opacity=`1`,e.style.transform=`translateX(-50%) translateY(0)`}var Kf=0,qf={idle:`JARVIS`,listening:`Listening`,thinking:`Working on it`,speaking:`JARVIS`,failed:`Couldn’t answer`};function Jf(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=qf[r]||`JARVIS`)}var Yf=!1;function Xf(){if(Yf)return;Yf=!0,Hf(Jf),Jf(Vf());let e=document.getElementById(`jarvis-bubble-close`),t=document.getElementById(`jarvis-bubble`);e&&t&&e.addEventListener(`click`,()=>{clearTimeout(Kf),t.classList.add(`hidden`)})}function Zf(e,{speak:t=!0}={}){let n=document.getElementById(`jarvis-bubble`),r=document.getElementById(`jarvis-bubble-text`);!n||!r||(Xf(),n.classList.remove(`hidden`),clearTimeout(Kf),$f(r,String(e||`Ready.`),()=>{clearTimeout(Kf),Kf=window.setTimeout(()=>n.classList.add(`hidden`),6e3)}),t&&Qf(e))}function Qf(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=()=>{Vf()===If.SPEAKING&&Uf(If.IDLE)};t.onstart=()=>Uf(If.SPEAKING),t.onend=r,t.onerror=r,window.speechSynthesis.speak(t)}catch{Vf()===If.SPEAKING&&Uf(If.IDLE)}}function $f(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 ep=null,tp=0,np=0,rp=!1,ip=!1,ap=!1,op=null,sp=`unknown`,cp=0,lp=``;function up(){let e=window.SpeechRecognition||window.webkitSpeechRecognition;return e?(ep=new e,ep.continuous=!0,ep.interimResults=!1,ep.lang=navigator.language||`en-US`,ep.onresult=fp,ep.onerror=e=>{if(e.error===`not-allowed`||e.error===`service-not-allowed`||e.error===`audio-capture`){rp=!1,sp=`blocked`,clearTimeout(np),T(e.error||`Speech recognition blocked.`,`JARVIS Voice`),mp(`blocked`,{error:e.error||`blocked`});return}e.error!==`no-speech`&&T(e.error||`Speech recognition failed.`,`JARVIS Voice`),mp(`error`,{error:e.error||`unknown`})},ep.onend=()=>{rp&&(clearTimeout(np),np=setTimeout(()=>void dp(),850),mp(`ended`))},!0):(E(`SpeechRecognition is not available here. Use the JARVIS text command panel.`),!1)}async function dp(){if(!ep&&!up())return!1;if(ap)return!0;rp=!0,ap=!0,await pp();try{return ep.start(),window.setTimeout(()=>{ap=!1},350),ip||(E(`JARVIS wake word listening is active.`),ip=!0),!0}catch(e){return ap=!1,clearTimeout(np),np=setTimeout(()=>{rp&&dp()},1200),/InvalidStateError/i.test(e?.name||e?.message||``)||E(`JARVIS voice restart pending: ${e?.message||`recognizer busy`}`),mp(`start-failed`,{error:e?.message||`busy`}),!1}}function fp(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(tp=r+4200,mp(`wake`,{wakeWindowUntil:tp}),!a){Zf(`Listening.`,{speak:!1});return}}else if(r>tp)return;if(r-cp<650)return;cp=r;let o=a||n;!o||o===lp||(lp=o,j(`jarvis-command`,{text:o,source:`voice`}),mp(`command`,{wakeWindowUntil:tp}))}async function pp(){if(op||sp===`blocked`||!navigator.mediaDevices?.getUserMedia)return op;try{return op=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1},video:!1}),sp=`granted`,mp(`mic-ready`),op}catch(e){return sp=[`NotAllowedError`,`SecurityError`].includes(e?.name)?`blocked`:`error`,mp(`mic-error`,{error:e?.name||e?.message||`unknown`}),null}}function mp(e,t={}){try{j(`VOICE_STATE`,{reason:e,enabled:rp,starting:ap,wakeWindowUntil:tp,micPermission:sp,hasStream:!!op,lastCommandAt:cp,...t})}catch{}}var hp=5,gp=.55,_p=.3,vp=null,yp=null;function bp(){return vp||(vp=document.getElementById(`world-label-layer`)),vp}function xp(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 Sp(e){let t=bp();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<_p||r.has(a))continue;let s=xp(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>=hp))break}t.replaceChildren();for(let e of i){let n=document.createElement(`span`);n.className=e.score<gp?`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 Cp(){return yp?!0:bp()?(yp=F(window,`ar-object-detections`,e=>{try{Sp(e.detail)}catch(e){console.warn(`[world-labels] render skipped`,e)}}),!0):!1}var wp=null,Tp=null,Ep=!1;async function Dp(){Ep=!0;try{wp=new globalThis.FaceMesh({locateFile:e=>`https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${e}`}),wp.setOptions({maxNumFaces:1,refineLandmarks:!0,minDetectionConfidence:.5,minTrackingConfidence:.5}),wp.onResults(e=>{window.dispatchEvent(new CustomEvent(`ar-face-mesh-results`,{detail:e}))}),console.log(`[AR Vision] Face mesh initialized.`)}catch(e){wp=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`);Cp(),Tp=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){Tp=null,console.warn(`[AR Vision] Object detector unavailable, continuing without it:`,e),D(`status-tracking`,`no object detect`)}I(Op)}async function Op(){if(!Ep)return;let e=ft();if(e){let t=e.source;try{if(wp&&await wp.send({image:t}),Tp){let e=Tp.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(Op)}var kp=.6,Ap=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]]),jp=!1,Mp=0,Np=16;function Pp(e,t){let n=e?.session;if(!n)return;let r=t?.xr?.getReferenceSpace?.();if(!r)return;let i=performance.now();if(i-Mp<Np)return;Mp=i;let a=[];for(let t of n.inputSources){if(!t.hand)continue;let n=Fp(e,t.hand,r);n&&a.push(n)}if(!a.length){k.handState.hands.length&&(k.handState.hands=[],k.handState.gestures=new Map);return}jp||(jp=!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 Fp(e,t,n){let r=Array(21),i=0;for(let[a,o]of Ap){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/kp,y:.5-l.y/kp,z:l.z/kp},i+=1}return i<15||!r[0]||!r[4]||!r[8]?null:r}function Ip(){jp=!1,Mp=0,k.handState.hands=[],k.handState.gestures=new Map}var Q={active:!1,binding:null,depthTexture:null,uniforms:null,patched:new WeakSet,renderer:null},Lp=`
uniform sampler2D uDepthTexture;
uniform mat4 uUvTransform;
uniform float uRawValueToMeters;
uniform float uDepthActive;
varying vec4 vOcclClip;
varying float vOcclEyeDepth;
`,Rp=`
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 zp(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:Vp},L(`depthOcclusion`,!0);for(let e of k.placedObjects||[])Hp(e);return A(`object-placed`,e=>Hp(e?.object)),t.addEventListener(`end`,Vp,{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),Vp(),!1}}function Bp(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 Vp(){Q.active=!1,Q.uniforms&&(Q.uniforms.uDepthActive.value=0),k.occlusion&&(k.occlusion.active=!1),L(`depthOcclusion`,!1)}function Hp(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)Up(e)})}function Up(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>`,Lp+`
#include <common>`).replace(`#include <dithering_fragment>`,Rp+`
#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:om,resume:gm,pause:_m,destroy:vm,setNativeOptions:bm,applyNativeState:xm,command:km,spawn:e=>j(`spawn-model`,{query:e})}}catch{}var Wp=0,Gp=!1,Kp=null,qp=!1,Jp=!1,Yp=!1,Xp=!1,Zp=null,Qp=new Promise(e=>{Zp=e}),$p=!1;function em(){Gp=!0,Zp?.(!0),mt(Wp),O(`8th Wall engine loaded.`,30),$.autoStart||tt(`Engine ready`),$.autoStart&&om()}tm();function tm(){if(Xp)return;if(Xp=!0,document.visibilityState===`visible`){nm();return}O(`Waiting for this tab to become visible...`,8);let e=()=>{document.visibilityState===`visible`&&(document.removeEventListener(`visibilitychange`,e),nm())};document.addEventListener(`visibilitychange`,e)}async function nm(){if(Yp)return;if(document.visibilityState!==`visible`){tm();return}if(Yp=!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 rm($),Sm(),P(`capability-matrix`,`ready`,k.capabilities),gn(),P(`panels`,`ready`),kl(),P(`vr`,`ready`),Mu(),id(),P(`media-viewer`,`ready`),ji(),P(`spatial-audio`,`ready`),yd(),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),Dp(),P(`vision`,`ready`),Tm(),am(),Cm(),await Yt($);try{t(async()=>{let{initVrStereoSplitScreen:e}=await import(`./ar-compositor-CkBVbEla.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`),wm(),P(`jarvis`,`ready`),O(`Waiting for 8th Wall engine binary...`,22),$p||($p=!0,window.addEventListener(`xrloaded`,em,{once:!0})),globalThis.XR8&&(Gp=!0,Zp?.(!0),mt(Wp),O(`8th Wall engine loaded.`,30),$.autoStart||tt(`Engine ready`),$.autoStart&&om()),Wp=pt(()=>{Gp||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(()=>km($.command),1200)),document.body.dataset.jarvisBoot=`ready`,N(`boot`,!0),N(`ui`,!0),ct(`ready`),M(`ready`)}function rm(e={}){if(globalThis.XR8)return Promise.resolve(!0);let t=document.getElementById(`jarvis-xr-static`);return t?t.dataset.loadFailed===`true`?im(e):new Promise(n=>{t.addEventListener(`load`,()=>{n(!0)},{once:!0}),t.addEventListener(`error`,()=>{t.dataset.loadFailed=`true`,im(e).then(n)},{once:!0})}):im(e)}function im(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 am(){document.getElementById(`start-ar`)?.addEventListener(`click`,e=>{let t=e.currentTarget;t.disabled=!0,t.textContent=`STARTING...`,om()}),document.getElementById(`camerafeed`)?.addEventListener(`click`,()=>{k.started||om()})}async function om(){return qp||Kp?Kp:k.runtime.lifecycleState===`running`?!0:(qp=!0,ut(`ar-core`,{entrypoint:`ar-core/ar-init.js`}),ct(`starting`),M(`starting`),O(`Starting real AR camera...`,34),k._cameraAcquired=!1,Kp=(async()=>{try{let e=await sm(3e4);return k._commandBootTimer&&(mt(k._commandBootTimer),k._commandBootTimer=null),e&&cm()?await lm():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 fm()):(T(`8th Wall engine binary did not load within 30 seconds. Running fallback with reduced tracking.`,`8th Wall Timeout`,{timeout:0}),await fm()),_n(),Tc().catch(e=>T(e.message,`Gesture Startup Failed`)),dp(),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 hm();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,Kp=null,M(`failed`,{error:k.runtime.lastError}),!1)}finally{qp=!1}})(),Kp)}async function sm(e){if(globalThis.XR8&&Gp)return!0;O(`Waiting for 8th Wall SLAM engine...`,36);let t=new Promise(t=>pt(()=>t(!1),e));return!!(await Promise.race([Qp,t])&&globalThis.XR8)}function cm(){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 lm(){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(),fd(),Md()];k.pipelineOrder=[`app-camera-status`,`XR8.GlTextureRenderer`,...n.slice(1).map(e=>e.name)],k.trackingAPI={getTrackingQuality:Jd,registerAnchor:Ud,unregisterAnchor:Wd,performHitTest:qd,requestRelocalization:Yd},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 um(12e3),await dm();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 um(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 dm(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 fm(){if(k.trackingMode=`webxr-fallback`,document.body.dataset.jarvisTracking=`webxr-fallback`,D(`status-tracking`,`webxr/basic`),!(`xr`in navigator&&navigator.xr))return hm();try{if(!await navigator.xr.isSessionSupported(`immersive-ar`))return hm();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),pm(e,t),mm(e,t),zp(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{}Ip(),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,Pp(n,e),k.occlusion?.active)){let t=e.xr.getReferenceSpace?.(),r=t?n.getViewerPose?.(t):null;r?.views?.length&&Bp(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`),hm()}}function pm(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 mm(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 hm(){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{ym();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}),ym(),!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 gm(){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 _m(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 vm(){_m(`shutdown`),k._commandBootTimer&&(mt(k._commandBootTimer),k._commandBootTimer=null),Dc(),ql(),On(),Xd(),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 ym(),document.querySelectorAll(`#ui-layer .ar-panel, #ui-layer .panel-orb, #error-host > *, #banner-host > *`).forEach(e=>e.remove()),It(),lt(),Kp=null,wt(`AR runtime shut down`),!0}function ym(){try{(k.cameraVideo?.srcObject)?.getTracks?.().forEach(e=>e.stop()),k.cameraVideo?.remove?.()}catch{}k.cameraVideo=null}function bm(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`)&&(_m(`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 xm(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 Sm(){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 Cm(){Jp||(Jp=!0,document.addEventListener(`visibilitychange`,()=>{document.hidden?k.started&&_m(`background-tab`):k.started&&k.runtime.lifecycleState===`paused`&&gm()}),window.addEventListener(`pagehide`,()=>{k.started&&_m(`pagehide`)}),window.addEventListener(`pageshow`,()=>{k.started&&k.runtime.lifecycleState===`paused`&&gm()}))}function wm(){let e=new Ff($).connect();up();try{globalThis.Jarvis={query:t=>e.query(t),runTask:(t,n)=>e.runTask(t,n),command:e=>km(e)}}catch{k.jarvisGlobalBlocked=!0}A(`jarvis-command`,({text:e})=>km(e))}function Tm(){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`,Em),A(`open-games`,Dm),A(`open-builder`,vf),A(`scan-room`,()=>Zf(`Scanning the room.`,{speak:!1}))}function Em(){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=()=>km(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 Dm(){let e=document.createElement(`div`),t=Om(`Eternum AR`,$d),n=Om(`Ripples AR`,af),r=document.createElement(`input`),i=Om(`Convert Game URL`,()=>of(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 Om(e,t){let n=document.createElement(`button`);return n.className=`panel-action`,n.textContent=e,n.onclick=t,n}async function km(e){let t=String(e||``).trim();if(!t)return;let n=t.toLowerCase();Uf(If.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`}),Zf(`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}),Zf(`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 bd(e),Zf(`Scene reconstruction complete: ${e}.`,{speak:!0});return}if(/vr mode|vr screen|headset/.test(n)){await Al();return}if(/eternum/.test(n)){$d(),Zf(`Eternum AR panel is open.`,{speak:!0});return}if(/ripples/.test(n)){af(),Zf(`Ripples AR panel is open.`,{speak:!0});return}if(/convert .* ar|game to ar/.test(n)){await of(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`),Zf(`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}Zf(await(globalThis.Jarvis||k.jarvis).query(t),{speak:!0})}catch(e){T(e.message,`JARVIS Command Failed`)}finally{Vf()===If.THINKING&&Uf(If.IDLE)}}export{xm as applyNativeState,Ft as i,Lt as n,_m as pauseRuntime,It as r,gm as resumeRuntime,bm as setNativeOptions,vm as shutdownRuntime,hm as startManualCameraFallback,Pt as t}; |