@displayxr/inline3d 1.28.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/call.js ADDED
@@ -0,0 +1,86 @@
1
+ /* @displayxr/inline3d 1.30.0 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
2
+ var ue=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),Mn=["high","normal","low","paused"],kn=.02,En=1e3/20,Tn=3e3,Cn=1e3/28;function pe(n){return typeof n=="function"?n:n===!1||n==="off"?"off":"auto"}function tt(n=import.meta.url){return fe?typeof fe=="function"?fe():fe:new URL("../lift/index.js",n).href}var fe=null;function ii(n){fe=n||null}function Rn(){return import(tt())}async function it(n,{importer:e=Rn,nav:t=globalThis.navigator,log:i=null,capsOpts:r={webFallback:!0}}={}){let s=(h,d)=>i&&i(h,d),o=(h,d={})=>(s("lift-unavailable",{reason:h,...d}),{lift:null,capabilities:null,caps:null,source:"none",reason:h}),a=pe(n);if(a==="off")return{lift:null,capabilities:null,caps:null,source:"none",reason:"off"};if(typeof a=="function"){let h=typeof a.liftCapabilities=="function"?a.liftCapabilities:null;return{lift:a,capabilities:h,caps:null,source:"injected",reason:null}}let l;try{l=await e()}catch(h){return o("import-failed",{message:String(h&&h.message||h).slice(0,200)})}let c=l&&typeof l.lift=="function"?l.lift:null;if(!c)return o("no-lift-export");let p=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,f=null;if(p){try{f=await p(r)}catch{f=null}let h=!!(f&&f.webFallback&&f.webFallback.webgpu);if(f&&!f.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(f&&f.native),provider:f&&f.provider||null}),{lift:c,capabilities:p,caps:f,source:"module",reason:null}}function me(n){let e=Number.isFinite(+n)&&n!==null?Math.max(-1,Math.min(1,+n)):0;return Math.abs(e)<kn?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Ce({id:n,speakerId:e,visible:t=!0}){return t?n!=null&&n===e?ue.speaker:ue.other:ue.hidden}function nt(n,e){if(!n||!Mn.includes(e)||typeof n.setPriority!="function")return!1;try{return n.setPriority(e)!==!1}catch{return!1}}function rt({degradedMs:n=En,recoveredMs:e=Cn,holdMs:t=Tn,alpha:i=.1}={}){let r=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(r=r===null?a:r+i*(a-r),o){if(r<e)return o=!1,s=0,"recovered"}else if(s=r>n?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){r=null,s=0,o=!1},get frameMs(){return r},get degraded(){return o}}}function st({lift:n,max:e=4,log:t=null,options:i=null}={}){let r=i&&typeof i=="object"?i:{},s=new Map,o=null,a=0,l=0,c=(h,d)=>t&&t(h,d),p=(h,d)=>{if(!d.handle)return;let m=Ce({id:h,speakerId:o,visible:d.visible});if(m===d.priority)return;d.priority=m;let u=nt(d.handle,m);c("lift-priority",{peer:h,priority:m,applied:u})},f={get size(){return s.size},get max(){return e},set max(h){e=Math.max(0,h|0)},has:h=>s.has(h),handle:h=>s.get(h)&&s.get(h).handle||null,priority:h=>s.get(h)&&s.get(h).priority||null,canAcquire:h=>s.has(h)||s.size<e,acquire(h,d,{wall:m,visible:u=!0,onError:v}={}){let y=s.get(h);if(y)return y.pending||Promise.resolve(y.handle);if(s.size>=e)return Promise.resolve(null);let x=++l,M=Ce({id:h,speakerId:o,visible:u}),b={gen:x,handle:null,visible:u,priority:M,pending:null};s.set(h,b);let A={quality:"auto",...r,mode:"live",wall:m,ui:"none",convergence:me(a),priority:M};return c("lift-acquire",{peer:h,priority:M,convergence:A.convergence}),b.pending=Promise.resolve().then(()=>n(d,A)).then(E=>{if(s.get(h)!==b||b.gen!==x){try{E&&E.remove&&E.remove()}catch{}return null}return b.pending=null,b.handle=E||null,b.priority=null,p(h,b),E&&typeof E.setConvergence=="function"&&E.setConvergence(me(a)),b.handle},E=>(s.get(h)===b&&s.delete(h),c("lift-failed",{peer:h,message:String(E&&E.message||E).slice(0,200)}),v&&v(E),null)),b.pending},release(h){let d=s.get(h);if(d){if(s.delete(h),d.handle)try{d.handle.remove()}catch{}c("lift-release",{peer:h})}},releaseAll(){for(let h of[...s.keys()])f.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,m]of s)p(d,m)},setVisible(h,d){let m=s.get(h);!m||m.visible===!!d||(m.visible=!!d,p(h,m))},setDepth(h){a=h;let d=me(h);for(let m of s.values())m.handle&&typeof m.handle.setConvergence=="function"&&m.handle.setConvergence(d);return d},get anyWeb(){for(let h of s.values())if(h.handle&&!h.handle.native)return!0;return!1},list(){return[...s].map(([h,d])=>({id:h,priority:d.priority,pending:!!d.pending,native:!!(d.handle&&d.handle.native)}))}};return f}var Ln=null;function ni(n){Ln=typeof n=="function"?n:null}var ri=new WeakMap,U;function si(n){let e=null;for(let[t,i]of n)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function On(n){if(!n||typeof n.getParameter!="function")return null;let e=ri.get(n);if(e)return e;let t,i,r;try{t=n.getParameter(n.MAX_TEXTURE_SIZE??3379),i=n.getParameter(n.MAX_RENDERBUFFER_SIZE??34024),r=n.getParameter(n.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=r&&r.length>=2?r[0]:0,o=r&&r.length>=2?r[1]:0,a=si([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=si([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",o]]);if(!a||!l)return null;let c={maxW:a[1],maxH:l[1],nameW:a[0],nameH:l[0],valueW:a[1],valueH:l[1]};return ri.set(n,c),c}function oi(){if(U!==void 0)return U;U=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return U;let n=document.createElement("canvas"),e=n.getContext("webgl2")||n.getContext("webgl");if(!e)return U;U=On(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{U=null}return U}function ai(n,e,t,{cols:i=2,rows:r=1}={}){let s=n*i,o=e*r,a={eyeW:n,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(n>0)||!(e>0))return a;let l=t.maxW/s,c=t.maxH/o,p=Math.min(l,c);if(!(p<1))return a;let f=l<=c,h=Math.max(1,Math.min(Math.floor(n*p+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*p+1e-9),Math.floor(t.maxH/r)));return{eyeW:h,eyeH:d,cols:i,scale:p,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*r,limitName:f?t.nameW:t.nameH,limitValue:f?t.valueW:t.valueH}}function ot(n){return Math.round(n*1e3)/1e3}function li(n,e,t){let i=typeof t=="number"?` (renderScale ${ot(t)} \u2192 ${ot(t*e.scale)})`:` (scale ${ot(e.scale)})`;return`${n} ${e.cols===1?"buffer":"SBS buffer"} ${e.reqW}\xD7${e.reqH} exceeds ${e.limitName} ${e.limitValue} on this device; rendering at ${e.bufW}\xD7${e.bufH}${i}.`}function ci(n,e){let t=n?.width||0,i=n?.height||0,r=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?r/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:r,h:s,mismatch:o!==1||a!==1}}function di(n,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${n} the browser clamped this canvas's drawing buffer to ${t.w}\xD7${t.h} (canvas.width/height say ${e.width}\xD7${e.height}); ${i}`}var Z="smoothstep",lt=["linear","smoothstep","easeoutcubic"];function ct(n){if(typeof n!="string")return null;let e=n.toLowerCase().replace(/[-_\s]/g,"");return lt.includes(e)?e:null}function An(n,e){if(e<=0)return 0;if(e>=1)return 1;if(n==="linear")return e;if(n==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var Y="idle",hi="rampDownThenFire",at="fireThenRampUp",Re=class{constructor(e,t){this._phase=Y,this._targetMode=null,this._firePending=!1,this._fireAtEnd=!1,this._from=0,this._to=0,this._cur=0,this._t=1,this._dur=180/1e3,this._easing=Z,(e!==void 0||t!==void 0)&&this.configure(e,t)}configure(e,t){if(e!==void 0){let i=Number(e);this._dur=Number.isFinite(i)&&i>0?i:0}return t!==void 0&&(this._easing=ct(t)||Z),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:r,current:s,steady:o=1}={}){let a=!(t>1),l=!(r>1),c=Number.isFinite(o)?o:1,p=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=p,a&&!l?(this._phase=hi,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=at,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=at,this._to=a?p:c,this._firePending=!(e!==null&&e===i),this._fireAtEnd=!1),this._t=this._dur>0?0:1,this._cur=this._from,this}update(e){let t=!1;if(this._phase!==Y){let i=Number.isFinite(e)&&e>0?e:0;this._t<1&&this._dur>0?(this._t+=i/this._dur,this._t>1&&(this._t=1)):this._t=1,this._cur=this._from+(this._to-this._from)*An(this._easing,this._t),this._phase===at?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=Y)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=Y)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==Y}value(){return this._cur}firePending(){return this._phase===hi?this._fireAtEnd:this._firePending}cancel(){return this._phase=Y,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var z=null;ni(n=>{let e=z;if(!e||!e._running||!n)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===n&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof n.contains=="function"&&n.contains(i.canvas))return t(i);for(let i of e._windows.values()){let r=i.canvas.parentElement;if(i.layer&&r&&typeof r.contains=="function"&&r.contains(n))return t(i)}return null});var Pn=()=>typeof navigator<"u"&&!!navigator.xr,J=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",De=()=>J()&&"excludeElement"in window.XRDisplayLayer.prototype,dt=()=>{if(!J())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},In=["getDisplayInfo","getRenderingModes","requestRenderingMode"],bi=["renderingmodechange","hardwaredisplaystatechange"],pt="trackingstatechange",xi=["unknown","tracking","searching"],ui=[...bi,pt];function Le(n){try{let e=n?n.trackingState:void 0;return xi.includes(e)?e:null}catch{return null}}var ht=()=>{if(!J())return!1;try{let n=window.XRDisplayLayer.prototype;return In.every(e=>typeof n[e]=="function")}catch{return!1}},ft=()=>{if(!J())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},ee=null;function Q(){if(ee!==null)return ee;if(!J())return!1;try{let n=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof n=="boolean")return ee=n}catch{}return!1}function Fn(n){if(ee!==null)return ee;if(!n||!J()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return ee=!!n.occlusionByDrawOrder}catch{return null}}var mi=!1;function ut(){mi||(mi=!0,console.info("[inline3d] This browser composites 2D over woven 3D automatically, per-pixel by draw order \u2014 overlay exclusion is obsolete here, so exclude()/addGlobalOverlay()/data-inline3d-overlay/autoChrome are accepted and ignored. Your 2D chrome already occludes the tiles correctly. The calls are harmless (keep them if you also ship to older DisplayXR Browsers); gate on inline3dOcclusionByDrawOrder() to drop them."))}function Si(){return Pn()&&J()}function mt(n){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:n.virtualDisplayHeight>0?n.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function jn(n,e){let t=Number.isFinite(n.ipdFactor)?n.ipdFactor:1,i=Number.isFinite(n.parallaxFactor)?n.parallaxFactor:1;return{...n,ipdFactor:t*e,parallaxFactor:i*e}}var Wn=16;function N(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Nn=1200,pi=!1;function zn(n){if(n==null)return Z;let e=ct(n);return e||(pi||(pi=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(n)} } }) is not a curve this SDK knows (${lt.join(" / ")}); using '${Z}'.`)),Z)}var gi=!1;function Hn(){gi||(gi=!0,console.info("[inline3d] The active rendering mode is 1-view, so this SDK has zeroed every window rig (ipdFactor/parallaxFactor -> 0) \u2014 both eyes now render from one place. The runtime keeps weaving the same two-view atlas whatever the page submits, so leaving stereo in it would put two slightly different images on a flat panel, i.e. a blurry double image instead of 2D. Your rendering is unchanged; the flattening is a copy applied on the way to the layer and it is undone the moment a 2-view mode goes active again."))}function gt(n){return n&&n.detail!==void 0&&n.detail!==null?n.detail:void 0}function Mi(n){let e=gt(n);return e!==void 0?[e,n]:[n]}function Vn(n){for(let e of Mi(n)){if(typeof e=="number"&&Number.isFinite(e))return e;if(e&&typeof e=="object"){let t=e.modeIndex!==void 0?e.modeIndex:e.mode;if(typeof t=="number"&&Number.isFinite(t))return t}}return-1}function $n(n){for(let e of Mi(n)){if(e==="2d"||e==="3d")return e;if(e&&typeof e=="object"){let t=e.state!==void 0?e.state:e.hardwareDisplayState;if(t==="2d"||t==="3d")return t}}return null}var _i=!1;function Bn(){_i||(_i=!0,console.warn("[inline3d] This browser has no XRDisplayLayer.setViewRig, so the view rig was ignored (the window still weaves \u2014 the runtime keeps the default display rig, scaled by virtualDisplayHeight). Gate on inline3dViewRigSupported() if your page's framing depends on the rig; further calls are silent."))}var vi=!1;function Un(){vi||(vi=!0,console.warn("[inline3d] addScene got BOTH viewRig and virtualDisplayHeight; on a browser with rig support the rig wins and the height is dropped. They describe the same slot \u2014 virtualDisplayHeight is shorthand for exactly one rig (display, identity pose, all factors 1) \u2014 so there is no merge. This is only worth passing as a PAIR deliberately: the height is what a browser without setViewRig will use, so a camera-rig scene can name its own fallback framing. Otherwise say it once, inside the rig."))}async function ki(n={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:r=!0,modeSwitch:s=null,untrackedFallback:o="none"}=n;if(!Si())return{supported:!1,trackingState:"unknown"};let a;try{a=await navigator.xr.requestSession("inline-3d")}catch(c){return{supported:!1,trackingState:"unknown",error:c}}let l=null;try{l=await a.requestReferenceSpace(e)}catch{}return new _t(a,l,{lazy:t,rootMargin:i,autoChrome:r,modeSwitch:s,untrackedFallback:o})}var ge=null;function Ae(n={}){return z&&z._running?Promise.resolve(z):ge||(ge=ki(n).finally(()=>{ge=null}),ge)}var yi=.7,qn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Xn(n){let e=[],t=document.createTreeWalker(n,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(qn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let r of i.childNodes)if(r.nodeType===Node.TEXT_NODE&&r.nodeValue.trim()){e.push(i);break}}return e}var Gn=4;function wi(n){let e=typeof window<"u"&&window.devicePixelRatio||1;return`${n.clientWidth}x${n.clientHeight}@${e}`}var _t=class{constructor(e,t,{lazy:i,rootMargin:r,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._globalOverlays=new Set,this._isolatedBy=new WeakMap,this._autoChrome=s,this._autoChromeEls=new Set,this._lastChromeScan=0,this._fullTileWarned=new WeakSet,this._stoodDown=!1,this._activeModeIndex=-1,this._activeViewCount=0,this._hardwareDisplayState=null,this._modes=null,this._stereoCollapsed=!1,this._displayListeners=new Map,this._primedDisplayState=!1;let l=o&&typeof o=="object"?o:{};this._msEnabled=l.enabled!==!1,this._modeSwitch=new Re((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,zn(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=Le(e)!==null,this._trackingState=this._trackingSupported?Le(e):"unknown",this._untrackedFallback=a==="mono"?"mono":"none",this._bakedStereo=1,this._bakedTarget=1,this._bakedAt=null,this._bakedEaseS=(Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,this._applyUntrackedTarget(),this.undock=ft()?{model:!1,splat:!1}:null,this._undockRead=!1,this._running=!0,this._lazy=i,this._observer=i&&typeof IntersectionObserver=="function"?new IntersectionObserver(c=>this._onIntersect(c),{rootMargin:r}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,z&&z._running&&z!==this&&console.warn("[inline3d] A second inline-3D session is live in this document. The browser's element-rect channel is a whole-widget setter, so both managers clobber each other's rect list every frame \u2014 tiles may flicker, ghost, or weave at a stale rect. Use ONE createInline3D() per document and add every window to it; if you are switching views, close() the previous manager first."),z=this,e.addEventListener("end",()=>this._teardown()),this._bindDisplayEvents(),this._bindTrackingEvents(),this._scanChrome(),this._bindLifecycle(),this._armDprWatch(),this._requestFrame()}get liveCount(){let e=0;for(let t of this._windows.values())t.layer&&e++;return e}addGlobalOverlay(e){if(!(!e||this._globalOverlays.has(e))){Q()&&ut(),this._globalOverlays.add(e);for(let t of this._windows.values())t.layer&&this._applyExclusion(t,e)}}removeGlobalOverlay(e){if(!(!e||!this._globalOverlays.delete(e)))for(let t of this._windows.values())t.layer&&this._dropExclusion(t,e)}_scanChrome(){if(Q()||!this._autoChrome||!De()||typeof document>"u")return;let e=Date.now();if(e-this._lastChromeScan<1e3)return;this._lastChromeScan=e;let t=document.body;if(!t)return;let i=new Set,r=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of r){if(s.closest("[data-inline3d-no-overlay]"))continue;let o=getComputedStyle(s).position;if(o!=="fixed"&&o!=="sticky")continue;let a=!1;for(let l of this._windows.keys())if(s===l||s.contains(l)){a=!0;break}if(!a){i.add(s);for(let l of Xn(s))i.add(l)}}for(let s of this._autoChromeEls){let o=!1;if(s.isConnected){for(let a of this._windows.keys())if(s===a||s.contains(a)){o=!0;break}}(!s.isConnected||o)&&(this._autoChromeEls.delete(s),this.removeGlobalOverlay(s))}for(let s of i)this._globalOverlays.has(s)||(this._autoChromeEls.add(s),this.addGlobalOverlay(s))}addImage(e,t,i={}){let r=this._register(e,"image",i);return r.ready=Kn(t).then(s=>{r.img=s,r.repaint()}),this._handle(e,r)}addVideo(e,t,i={}){let r=this._register(e,"video",i);return r.video=t,this._handle(e,r)}addScene(e,t,i={}){i.viewRig&&i.virtualDisplayHeight!==void 0&&Un();let r=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return r.onFrame=t,r.ownsBuffer=!1,this._handle(e,r)}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:r=>{r&&(Q()&&ut(),t.excluded.add(r),this._applyExclusion(t,r))},unexclude:r=>{!r||!t.excluded.delete(r)||this._dropExclusion(t,r)},get trackingState(){return i._trackingState},setViewRig:r=>(t.viewRig=r||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:r=>this._requestRenderingModeEased(r,t),setStereoEnabled:r=>this._setStereoEnabled(r,t),on:(r,s)=>this.on(r,s),off:(r,s)=>this.off(r,s),onDisplayModeChange:r=>this._onDisplayModeChange(r),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get firstWoven(){return t.fwPromise},onFirstWoven:r=>{if(typeof r!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{r(o)}catch(a){console.error("[inline3d] onFirstWoven callback threw",a)}}),()=>{s=!1}},rewoven:()=>this._rewoven(t)}}getDisplayInfo(){return this._layerCall(this._liveWindow(null),"getDisplayInfo","getDisplayInfo()")}getRenderingModes(){return this._getRenderingModes(null)}requestRenderingMode(e){return this._requestRenderingModeEased(e,null)}setStereoEnabled(e){return this._setStereoEnabled(e,null)}get trackingState(){return this._trackingState}get hardwareDisplayState(){return this._hardwareDisplayState}get activeMode(){return{modeIndex:this._activeModeIndex,viewCount:this._activeViewCount}}get stereoCollapsed(){return this._stereoCollapsed}get modeSwitch(){return{active:this._msTransitionActive(),factor:this._stereoFactor}}close(){try{this.session.end()}catch{}this._teardown()}_effectiveViewRig(e){return this._stereoFactor>=1?e.viewRig||(e.stereoSynthRig?mt(e):null):(e.viewRig||(e.stereoSynthRig=!0),jn(e.viewRig||mt(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&Hn(),!t&&this._msArmedUp?(this._msArmedUp=!1,this._startUpRamp()):this._modeSwitch.active()||(this._stereoFactor=t?0:1);for(let i of this._windows.values()){if(t){let r=i.viewRig||mt(i);i.stereoSaved={ipdFactor:r.ipdFactor,parallaxFactor:r.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!dt())return Bn(),!1;if(!e.layer)return!1;let t=this._effectiveViewRig(e);try{return e.layer.setViewRig(t),!0}catch{return!1}}_layerCall(e,t,i,r=[]){if(!ht())return Promise.reject(new Error(`[inline3d] ${i} needs a DisplayXR Browser with the display-mode API (XRDisplayLayer.getDisplayInfo/getRenderingModes/requestRenderingMode). Gate on inline3dDisplayModesSupported().`));if(!e||!e.layer)return Promise.reject(new Error(`[inline3d] ${i} needs a live weave layer, and this window has none right now (lazy mode closes the layer while the tile is off screen). Call it once the tile is visible, or create the manager with { lazy: false }.`));try{return Promise.resolve(e.layer[t](...r))}catch(s){return Promise.reject(s)}}_liveWindow(e){if(e&&e.layer)return e;for(let t of this._windows.values())if(t.layer)return t;return e||null}async _getRenderingModes(e){let t=await this._layerCall(this._liveWindow(e),"getRenderingModes","getRenderingModes()"),i=Array.isArray(t)?t:[];this._modes=i;let r=i.find(s=>s.isActive);return r&&(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount,(r.viewCount===1||r.viewCount===2)&&this._setStereoCollapsed(r.viewCount===1)),this._primedDisplayState=!0,t}_requestRenderingMode(e,t){return this._layerCall(this._liveWindow(t),"requestRenderingMode","requestRenderingMode()",[e])}_msTransitionActive(){return this._modeSwitch.active()||this._msArmedUp||this._msFire!==null}async _requestRenderingModeEased(e,t){if(!this._msEnabled||!dt())return this._requestRenderingMode(e,t);let i=this._modes;if(!Array.isArray(i)||i.length===0)try{i=await this._getRenderingModes(t)}catch{i=null}let r=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=r&&Number.isFinite(r.viewCount)?r.viewCount:0,o=this._activeViewCount;return s<1||s>2||o<1?this._requestRenderingMode(e,t):s===1?o===1?this._requestRenderingMode(e,t):this._rampDownThenRequest(e,t):this._requestThenRampUp(e,t)}_rampDownThenRequest(e,t){if(this._msFire&&this._msFire.modeIndex===e)return this._msFire.promise;this._settlePendingDown("superseded",`a request for mode ${e} replaced it`);let i={modeIndex:e,win:t,resolve:null,reject:null,promise:null};return i.promise=new Promise((r,s)=>{i.resolve=r,i.reject=s}),this._msFire=i,this._modeSwitch.request({targetMode:e,targetViewCount:1,currentMode:this._activeModeIndex,currentViewCount:this._activeViewCount,current:this._stereoFactor,steady:1}),this._msLastMs=N(),this._armModeSwitchTick(),i.promise}_requestThenRampUp(e,t){let r=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=r?Promise.resolve(void 0):this._requestRenderingMode(e,t);return this._stereoFactor<1&&(this._stereoCollapsed?(this._msArmedUp=!0,this._modeSwitch.cancel(),this._stereoFactor=0):this._startUpRamp()),s.catch(o=>{throw this._msArmedUp&&(this._msArmedUp=!1,this._modeSwitch.active()||(this._stereoFactor=this._stereoCollapsed?0:1)),o})}_startUpRamp(){this._settlePendingDown("superseded","the display returned to 3D"),this._modeSwitch.request({targetMode:this._activeModeIndex,targetViewCount:2,currentMode:this._activeModeIndex,currentViewCount:2,current:this._stereoFactor,steady:1}),this._msLastMs=N(),this._armModeSwitchTick()}_settlePendingDown(e,t){let i=this._msFire;if(!i)return;this._msFire=null;let r=new Error(`[inline3d] the request for rendering mode ${i.modeIndex} was never forwarded: ${t}. A ->2D switch is held until the disparity has ramped out, so a request that is reversed or replaced in that window is dropped rather than fired late.`);r.name=e,i.reject(r)}_advanceModeSwitch(){if(!this._modeSwitch.active()){this._msLastMs=null,this._disarmModeSwitchTick();return}let e=N(),t=typeof this._msLastMs=="number"?Math.max(0,(e-this._msLastMs)/1e3):0;this._msLastMs=e;let i=this._modeSwitch.update(t);if(i.factor!==this._stereoFactor){this._stereoFactor=i.factor;for(let r of this._windows.values())this._pushViewRig(r)}if(i.fire&&this._msFire){let r=this._msFire;this._msFire=null,this._requestRenderingMode(r.modeIndex,r.win).then(s=>r.resolve(s),s=>{this._startUpRamp(),r.reject(s)})}this._modeSwitch.active()||(this._msLastMs=null,this._disarmModeSwitchTick())}_armModeSwitchTick(){this._msTick!==null||typeof setTimeout!="function"||(this._msTick=setTimeout(()=>{this._msTick=null,this._running&&(this._advanceModeSwitch(),this._modeSwitch.active()&&this._armModeSwitchTick())},Wn))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,r=await this._getRenderingModes(t),s=Array.isArray(r)?r:[],o=s.find(a=>a.viewCount===i&&a.isRequestable);if(!o)throw new Error(`[inline3d] setStereoEnabled(${!!e}) found no requestable ${i}-view mode on this display (${s.length} mode(s) listed). It is sugar over requestRenderingMode() and cannot invent one \u2014 read getRenderingModes() and drive the list yourself.`);return o.isActive&&!this._msTransitionActive()||await this._requestRenderingModeEased(o.modeIndex,t),!!e}_bindDisplayEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||ht()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=$n(e),i=gt(e),r=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&r(t);let s=this._activeModeIndex,o=this._activeViewCount;return this._getRenderingModes(null).then(a=>{let l=(Array.isArray(a)?a:[]).find(c=>c.isActive)||null;if(l&&(l.modeIndex!==s||l.viewCount!==o)&&this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:l,detail:null}),!t){let c=l&&typeof l.hardwareDisplay3D=="boolean"?l.hardwareDisplay3D?"3d":"2d":null;r(c)}}).catch(()=>{t||r(null)})}async _onRenderingModeChange(e){let t=gt(e),i=Vn(e),r=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];r=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}r?(this._activeModeIndex=r.modeIndex,this._activeViewCount=r.viewCount):i>=0&&(this._activeModeIndex=i),(this._activeViewCount===1||this._activeViewCount===2)&&this._setStereoCollapsed(this._activeViewCount===1),this._emitDisplay({type:"renderingmodechange",modeIndex:this._activeModeIndex,viewCount:this._activeViewCount||null,mode:r,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let r=t||[e];for(let s of[...i])try{s(...r)}catch(o){console.error(`[inline3d] ${e.type} listener threw`,o)}}on(e,t){if(typeof t!="function")throw new TypeError("[inline3d] on() takes (type, function).");if(!ui.includes(e))throw new TypeError(`[inline3d] on() knows ${ui.join(" / ")}, got ${JSON.stringify(e)}.`);let i=this._displayListeners.get(e);return i||this._displayListeners.set(e,i=new Set),i.add(t),()=>this.off(e,t)}off(e,t){let i=this._displayListeners.get(e);i&&i.delete(t)}_onDisplayModeChange(e){if(typeof e!="function")throw new TypeError("[inline3d] onDisplayModeChange() takes a function.");let t=bi.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!ft())return this.undock=null;let e=this._liveWindow(null);if(!e||!e.layer||typeof e.layer.getUndockCapabilities!="function")return this.undock;try{let t=await e.layer.getUndockCapabilities();this.undock={model:!!(t&&t.model),splat:!!(t&&t.splat)}}catch{}return this.undock}_register(e,t,i){this._windows.has(e)&&this._remove(e),e.style.willChange="transform",e.style.transform="translateZ(0)";let r={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,ready:null,ownsBuffer:t!=="scene",cornerRadius:i.cornerRadius||0,feather:i.feather||0,reqW:i.width||0,reqH:i.height||0,virtualDisplayHeight:i.virtualDisplayHeight||0,viewRig:i.viewRig||null,stereoSaved:null,stereoSynthRig:!1,observeEl:i.observe||e,ctx:t==="scene"?null:e.getContext("2d"),repaint:()=>this._paint(r,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:Jn(i.firstWovenHoldMs),fwRegAt:N(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null};return r.fwPromise=new Promise(s=>{r.fwResolve=s}),this._windows.set(e,r),this._lazy&&this._observer?this._observer.observe(r.observeEl):this._activate(r),r}_remove(e){let t=this._windows.get(e);t&&(this._observer&&this._observer.unobserve(t.observeEl),this._deactivate(t),this._windows.delete(e),this._settleFirstWoven(t,!1,"removed"))}_onIntersect(e){for(let t of e){let i=null;for(let r of this._windows.values())if(r.observeEl===t.target){i=r;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=dt()?this._effectiveViewRig(e):null,i=t?{viewRig:t}:e.virtualDisplayHeight>0?{virtualDisplayHeight:e.virtualDisplayHeight}:{};e.layer=new XRDisplayLayer(this.session,e.canvas,i)}catch(t){e.layer=null,e.layerFailWarned||(e.layerFailWarned=!0,console.warn("[inline3d] new XRDisplayLayer() failed for this window \u2014 it will show FLAT 2D instead of woven 3D, and the SDK will not retry. The canvas has been repainted mono so it cannot be left holding a raw side-by-side pair.",t)),this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"layer-failed");return}e.fwResult||(e.fwLayerAt=N(),e.fwStereo=!1),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&ht()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),ft()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),Fn(e.layer)===!0&&this._standDownLegacyOcclusion();for(let t of e.excluded)this._applyExclusion(e,t);for(let t of this._globalOverlays)this._applyExclusion(e,t);this._startOverlayScan(e),e.ownsBuffer&&(this._sizeBuffer(e,!0),this._paint(e,null)),this._startSizeWatch(e)}}_deactivate(e){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e)}_paintMono(e){!e.ownsBuffer||e.kind==="scene"||(this._sizeBuffer(e,!1),this._paint(e,null))}_notifyLayerLost(e){if(!(e.kind!=="scene"||typeof e.onLayerLost!="function"||e.layerLostSent)){e.layerLostSent=!0;try{e.onLayerLost()}catch(t){console.warn("[inline3d] a scene window's onLayerLost callback threw",t)}}}_isFullTileOverlay(e,t){if(!t||typeof t.getBoundingClientRect!="function")return!1;let i=t.getBoundingClientRect(),r=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=r.width*r.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,r.right)-Math.max(i.left,r.left),l=Math.min(i.bottom,r.bottom)-Math.max(i.top,r.top);if(a<=0||l<=0)return!1;let c=a*l;return c/s<yi||c/o<yi?!1:(this._fullTileWarned.has(t)||(this._fullTileWarned.add(t),console.warn("[inline3d] Refusing a full-tile overlay: this element covers its own woven canvas, and the browser's geometric matcher cannot tell the two apart \u2014 it would stage the CANVAS as the overlay and the tile would show its raw side-by-side buffer instead of 3D. Make the overlay a PARTIAL region of the tile (a caption band, a badge, a corner plate), or move it outside the tile and register it with addGlobalOverlay().",t)),!0)}_applyExclusion(e,t){if(Q()||!e.layer||!De()||this._isFullTileOverlay(e,t))return;let i=this._isolatedBy.get(t);if(i||(i=new Set,this._isolatedBy.set(t,i)),i.add(e),!t.dataset.inline3dIsolated){t.dataset.inline3dPriorWillChange=t.style.willChange||"";let r=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=r,t.dataset.inline3dIsolated="1"}try{e.layer.excludeElement(t)}catch{}}_dropExclusion(e,t){if(Q())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!De()))try{e.layer.unexcludeElement(t)}catch{}}_unpromote(e){return!e||!e.dataset||!e.dataset.inline3dIsolated?!1:(e.style.willChange=e.dataset.inline3dPriorWillChange||"",delete e.dataset.inline3dPriorWillChange,delete e.dataset.inline3dIsolated,!0)}_standDownLegacyOcclusion(){if(this._stoodDown)return;this._stoodDown=!0;let e=!1;for(let t of this._windows.values()){t.overlayObserver&&(this._stopOverlayScan(t),e=!0);for(let i of t.excluded)this._unpromote(i)&&(e=!0)}for(let t of this._autoChromeEls)this._globalOverlays.delete(t),this._unpromote(t),e=!0;this._autoChromeEls.clear();for(let t of this._globalOverlays)this._unpromote(t)&&(e=!0);this._isolatedBy=new WeakMap,e&&ut()}_startOverlayScan(e){if(Q()||!De()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let r=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)r.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of r)e.autoExcluded.has(s)||(e.autoExcluded.add(s),this._applyExclusion(e,s))};i(),e.overlayObserver=new MutationObserver(i),e.overlayObserver.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-inline3d-overlay"]})}_stopOverlayScan(e){e.overlayObserver&&(e.overlayObserver.disconnect(),e.overlayObserver=null),e.autoExcluded.clear()}_eyeSize(e,t=!0){let i=Math.min(window.devicePixelRatio||1,2),r=e.reqW||Math.round((e.canvas.clientWidth||256)*i),s=e.reqH||Math.round((e.canvas.clientHeight||256)*i),o=1,a=!e.reqW&&!e.reqH&&this._sourceEyeSize(e);if(a){let c=Math.max(a.w/r,a.h/s);c<1&&(o=c,r=Math.max(1,Math.round(r*c)),s=Math.max(1,Math.round(s*c)))}let l=ai(r,s,oi(),{cols:t?2:1});return l.clamped&&(o*=l.scale,r=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(li("[inline3d]",l)))),e.bufScale=o,{w:r,h:s}}_sourceEyeSize(e){if(e.kind!=="video"&&e.kind!=="image")return null;let t=e.kind==="video"?e.video:e.img;if(!t)return null;let i=t.videoWidth||t.naturalWidth||t.width,r=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(r>0)?null:{w:i/2,h:r}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let r=null;try{r=t.getContext("webgl2")||t.getContext("webgl")}catch{r=null}e.sceneGl=r&&typeof r.drawingBufferWidth=="number"?r:null}if(!e.sceneGl)return;let i=ci(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(di("[inline3d]",t,i,"getViewport() splits canvas.width, so the eyes are off-centre in the woven buffer. This scene canvas is sized by the page: keep 2 \xD7 eye width and the height within MAX_TEXTURE_SIZE / MAX_RENDERBUFFER_SIZE / MAX_VIEWPORT_DIMS, or map getViewport() onto gl.drawingBufferWidth/Height.")))}_sizeBuffer(e,t){let{w:i,h:r}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=r,e.canvas.width=t?i*2:i,e.canvas.height=r,e.sbs=t}_startSizeWatch(e){typeof ResizeObserver=="function"&&(e.sizeObserver||!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas)))}_stopSizeWatch(e){e.sizeObserver&&(e.sizeObserver.disconnect(),e.sizeObserver=null),e.resizePending=!1}_onBoxChange(e){if(!e.layer||!e.ownsBuffer||e.resizePending)return;e.resizePending=!0;let t=()=>{if(!e.resizePending||(e.resizePending=!1,!e.layer||!e.ownsBuffer))return;this._noteRewovenBox(e);let{w:i,h:r}=this._eyeSize(e);i===e.eyeW&&r===e.eyeH||(this._sizeBuffer(e,!0),this._paint(e,null))};typeof requestAnimationFrame=="function"?requestAnimationFrame(t):t()}_armDprWatch(){if(typeof window>"u"||typeof window.matchMedia!="function")return;this._disarmDprWatch();let e;try{e=window.matchMedia(`(resolution: ${window.devicePixelRatio||1}dppx)`)}catch{return}let t=()=>{if(this._running){this._armDprWatch();for(let i of this._windows.values())i.layer&&this._onBoxChange(i)}};try{e.addEventListener("change",t)}catch{return}this._dprWatch={q:e,onChange:t}}_disarmDprWatch(){if(this._dprWatch){try{this._dprWatch.q.removeEventListener("change",this._dprWatch.onChange)}catch{}this._dprWatch=null}}_paint(e,t){if(e.kind==="scene"||!e.ctx)return;let i=this._running&&!!e.layer;!i&&e.sbs&&this._sizeBuffer(e,!1);let r=e.kind==="video"?e.video:e.img;if(!r)return;if(e.kind==="video"&&(r.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=r.videoWidth||r.naturalWidth||r.width,l=r.videoHeight||r.naturalHeight||r.height;if(!a||!l)return;let c=a+"x"+l;if(e.srcKey!==c&&(e.srcKey=c,e.ownsBuffer&&!(e.reqW&&e.reqH))){let{w:u,h:v}=this._eyeSize(e,e.sbs);(u!==e.eyeW||v!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let p=e.bufScale||1,f=e.cornerRadius*p,h=e.feather*p;if(o.clearRect(0,0,s.width,s.height),!e.sbs){Oe(o,r,0,0,a/2,l,0,0,s.width,s.height,f,h);return}let d=s.width/2,m=Math.min(this._stereoFactor,this._bakedStereo);if(m<1){Oe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),Yn(o,r,a/2,l,d,s.height,m,f,h);return}f>0||h>0?(Oe(o,r,0,0,a/2,l,0,0,d,s.height,f,h),Oe(o,r,a/2,0,a/2,l,d,0,d,s.height,f,h)):o.drawImage(r,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(pt,()=>{this._setTrackingState(Le(e)||"unknown")})}_setTrackingState(e){let t=xi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:pt,state:t};this._emitDisplay(i,[t,i])}_applyUntrackedTarget(){if(this._untrackedFallback!=="mono"){this._bakedTarget=1;return}this._trackingState==="searching"?this._bakedTarget=0:this._trackingState==="tracking"&&(this._bakedTarget=1)}_trackBakedStereo(e){this._trackingSupported&&this._setTrackingState(Le(this.session)||"unknown");let t=this._bakedAt===null||!Number.isFinite(e)?0:Math.max(0,(e-this._bakedAt)/1e3);this._bakedAt=Number.isFinite(e)?e:this._bakedAt;let i=this._bakedStereo,r=this._bakedTarget;if(i===r)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=r>i?Math.min(r,i+s):Math.max(r,i-s)}_recommitLastFrame(e){let t=e.canvas;if(!t.width||!t.height)return;let i=e.ctx;try{i.save(),i.globalCompositeOperation="copy",i.drawImage(t,0,0),i.restore()}catch{}}_requestFrame(e){if(!this._running||this._framePending&&!e)return;let t=e?++this._loopId:this._loopId;this._framePending=!0;try{this.session.requestAnimationFrame((i,r)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,r))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,r=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.kind==="scene"){if(r&&s.onFrame){if(s.frames++,r.length<2&&(s.monoFrames++,s.monoFrames%300===1&&typeof console<"u"&&console.debug)){let o=(100*s.monoFrames/Math.max(1,s.frames)).toFixed(1);console.debug(`[inline3d] scene window: ${s.monoFrames} non-stereo view lists in ${s.frames} frames (${o}%). The viewer replays its last good stereo frame for these; a rising rate means the session is falling back under load.`)}try{s.onFrame(r,s.layer,t),r.length>=2&&(s.fwStereo=!0,s.warnedBufMismatch||this._checkSceneBuffer(s),s.rw&&(s.rw.stereo=!0))}catch(o){s.frameThrewWarned||(s.frameThrewWarned=!0,console.warn("[inline3d] a scene window's onFrame threw; this window will keep whatever it last drew, and the other windows carry on. Further throws from it are silent.",o))}}}else this._paint(s,r),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.rw&&(s.rw.stereo=!0));this._tickFirstWoven(s)}}_tickFirstWoven(e){if(e.rw){this._noteRewovenBox(e);let t=e.rw,i=N();t.stereo&&i-t.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):t.at>t.calledAt&&i-t.calledAt>=Gn*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||N()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_settleFirstWoven(e,t,i){t||(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(N()-e.fwRegAt)}),e.fwResolve(e.fwResult),e.fwResolve=null)}_rewoven(e){if(!e.fwResult)return e.fwPromise;if(!e.fwResult.woven)return Promise.resolve(e.fwResult);if(e.rwGone)return Promise.resolve(Object.freeze({woven:!1,confirmed:!1,reason:e.rwGone,ms:0}));if(e.rw)return this._restartRewoven(e),e.rw.promise;let t,i=new Promise(s=>{t=s}),r=N();return e.rw={promise:i,resolve:t,calledAt:r,at:r,stereo:!1,box:wi(e.canvas)},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=wi(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=N(),e.rw.stereo=!1)}_settleRewoven(e,t,i){let r=e.rw;r&&(e.rw=null,r.resolve(Object.freeze({woven:t,confirmed:!1,reason:i,ms:Math.round(N()-r.calledAt)})))}_bindLifecycle(){typeof window>"u"||(this._onPageHide=()=>this._suspend(),this._onPageShow=e=>this._resume(!!(e&&e.persisted)),window.addEventListener("pagehide",this._onPageHide),window.addEventListener("pageshow",this._onPageShow),typeof document<"u"&&"onfreeze"in document&&(this._onFreeze=()=>this._suspend(),this._onResume=()=>this._resume(!0),document.addEventListener("freeze",this._onFreeze),document.addEventListener("resume",this._onResume)))}_unbindLifecycle(){typeof window>"u"||(this._onPageHide&&window.removeEventListener("pagehide",this._onPageHide),this._onPageShow&&window.removeEventListener("pageshow",this._onPageShow),this._onFreeze&&typeof document<"u"&&(document.removeEventListener("freeze",this._onFreeze),document.removeEventListener("resume",this._onResume)),this._onPageHide=this._onPageShow=this._onFreeze=this._onResume=null,this._frameWatchdog&&(clearTimeout(this._frameWatchdog),this._frameWatchdog=null))}_suspend(){if(!this._running||this._suspended)return;let e=[];for(let t of this._windows.values())t.layer&&(e.push(t),this._deactivate(t));this._suspended=e}_resume(e){if(!this._running)return;let t=this._suspended;if(this._suspended=null,t)for(let i of t)this._windows.has(i.canvas)&&(this._lazy&&this._observer?(this._observer.unobserve(i.observeEl),this._observer.observe(i.observeEl)):this._activate(i));this._lastChromeScan=0,this._scanChrome(),this._armDprWatch(),e&&this._watchForStalledFrames()}_watchForStalledFrames(){if(this._frameWatchdog||typeof setTimeout!="function")return;let e=this._frameCount;this._frameWatchdog=setTimeout(()=>{this._frameWatchdog=null,!(!this._running||this._frameCount!==e)&&this._requestFrame(!0)},1e3)}_teardown(){if(this._running){this._running=!1,z===this&&(z=null),this._unbindLifecycle(),this._disarmDprWatch(),this._disarmModeSwitchTick(),this._modeSwitch.cancel(),this._msArmedUp=!1,this._settlePendingDown("closed","the inline-3D session closed first"),this._observer&&this._observer.disconnect();for(let e of this._windows.values()){if(this._stopOverlayScan(e),this._stopSizeWatch(e),e.layer){try{e.layer.close()}catch{}e.layer=null}this._paintMono(e),this._notifyLayerLost(e),this._settleFirstWoven(e,!1,"session-ended")}this._windows.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function Jn(n){return typeof n=="number"&&Number.isFinite(n)&&n>=0?n:Nn}function Kn(n){return typeof n!="string"?Promise.resolve(n):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=n})}function Oe(n,e,t,i,r,s,o,a,l,c,p,f){p>0&&n.roundRect?(n.save(),n.beginPath(),n.roundRect(o,a,l,c,p),n.clip(),n.drawImage(e,t,i,r,s,o,a,l,c),n.restore()):n.drawImage(e,t,i,r,s,o,a,l,c),f>0&&Ei(n,o,a,l,c,f)}function Yn(n,e,t,i,r,s,o,a,l){n.save(),a>0&&n.roundRect&&(n.beginPath(),n.roundRect(r,0,r,s,a),n.clip()),n.drawImage(e,0,0,t,i,r,0,r,s),o>0&&(n.globalAlpha=o,n.drawImage(e,t,0,t,i,r,0,r,s)),n.restore(),l>0&&Ei(n,r,0,r,s,l)}function Ei(n,e,t,i,r,s){let o=Math.min(s,Math.floor(Math.min(i,r)/2));if(o<=0)return;n.save(),n.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+r-o,i,o,[e,t+r],[e,t+r-o]],[e,t,o,r,[e,t],[e+o,t]],[e+i-o,t,o,r,[e+i,t],[e+i-o,t]]];for(let[l,c,p,f,h,d]of a){let m=n.createLinearGradient(h[0],h[1],d[0],d[1]);m.addColorStop(0,"rgba(0,0,0,1)"),m.addColorStop(1,"rgba(0,0,0,0)"),n.fillStyle=m,n.fillRect(l,c,p,f)}n.restore()}function te(n,e){return n>0&&e>0&&n/e>2.5}function $(n,e,t,i,r){let s=Math.abs(i||0),o=Math.min(n-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(n-o)/2+(r===0?i:-i);return{sx:Math.max(0,Math.min(n-o,l)),sy:(e-a)/2,sw:o,sh:a}}function _e(n,e,t){let i=Math.min(n,e*t),r=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(r/2)*2)}}function ie(n,e){let t=n/2;return[{src:"R",sx:t,sw:t,sy:0,sh:e,dx:0,dw:t,mirror:!0},{src:"L",sx:0,sw:t,sy:0,sh:e,dx:t,dw:t,mirror:!0}]}function vt(n,e,t){let i=new n.constructor(n.length);for(let r of ie(e,t))for(let s=0;s<t;s++)for(let o=0;o<r.dw;o++){let a=r.sx+(r.sw-1-o);i[s*e+r.dx+o]=n[s*e+a]}return i}function Ti(n,e){return!(n>0)||!(e>0)||e>=180?null:n/2/Math.tan(e/2*Math.PI/180)}function Pe({eyeWidthPx:n,hfovDeg:e,baselineMm:t,subjectZmm:i}){let r=Ti(n,e);return r===null||!(t>0)||!(i>0)?0:r*t/(2*i)}function Ie(n,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,n||0))}function Fe(n,e,t=.2){let i=n+t*(e-n);return Math.abs(e-i)<.05?e:i}function ve(){let n={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=n.measuredPx!==null?n.measuredPx/2:n.hello&&n.subjectZmm?Pe({eyeWidthPx:e,hfovDeg:n.hello.hfovDeg,baselineMm:n.hello.baselineMm,subjectZmm:n.subjectZmm}):0;return Ie(t+n.depth*.05*e,e)},step(e){return n.current=Fe(n.current,n.target(e)),n.current}};return n}var je=1,yt="inline3d-call/1",Ci=Object.freeze(["sbs","mono"]),ne=4,Ri=4,wt=5,Zn=150,Qn=5e3,er=/^[A-Za-z0-9_-]{16,64}$/,tr=16;function bt(n){let e=new Uint8Array(tr);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Li(e)}function Di(n){let e=new Uint8Array(8);return(n||(i=>globalThis.crypto.getRandomValues(i)))(e),Li(e)}function Li(n){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<n.length;i+=3){let s=n[i]<<16|n[i+1]<<8|n[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let r=n.length-i;if(r===1){let s=n[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(r===2){let s=n[i]<<16|n[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function re(n){return typeof n=="string"&&er.test(n)}function ye(n){if(!n)return null;let e="";if(typeof n=="object")e=n.hash||n.href&&String(n.href).split("#")[1]||"";else{let t=String(n),i=t.indexOf("#");e=i>=0?t.slice(i+1):t.includes("=")&&!t.includes("://")?t:""}e=e.replace(/^#/,"");for(let t of e.split("&")){let i=t.indexOf("=");if(i<0||decodeURIComponent(t.slice(0,i))!=="room")continue;let r=decodeURIComponent(t.slice(i+1));return re(r)?r:null}return null}function We(n,e){if(!re(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(n||"").split("#")[0]}#room=${e}`}function xt(n){if(!n||typeof n!="object"||n.type!=="hello")return null;let e=(t,i,r)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=r?t:null;return{type:"hello",v:typeof n.v=="number"?n.v:je,format:Ci.includes(n.format)?n.format:"mono",width:e(n.width,1,16384),height:e(n.height,1,16384),baselineMm:e(n.baselineMm,1,1e3),hfovDeg:e(n.hfovDeg,5,170),rectified:n.rectified===!0,sdk:typeof n.sdk=="string"?n.sdk.slice(0,64):null}}function St({format:n,width:e,height:t,baselineMm:i,hfovDeg:r,rectified:s}={}){let o={type:"hello",v:je,format:Ci.includes(n)?n:"mono",width:e||0,height:t||0,rectified:!!s,sdk:yt};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(r)&&(o.hfovDeg=r),o}function Mt(n){if(!n||n.type!=="hint")return null;let e=n.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=Zn&&e<=Qn?{type:"hint",subjectZmm:e}:null}function Oi(n){return!n||n.type!=="state"?null:{type:"state",muted:n.muted===!0,cameraOff:n.cameraOff===!0,speaking:n.speaking===!0}}function kt(n){let e=1e3/n,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function Et({format:n,woven:e,mono3D:t="auto",lift:i=!1,overBudget:r=!1,failed:s=!1}){return(n==="sbs"?"sbs":"mono")==="sbs"?{route:e?"woven-sbs":"flat-left"}:e?t==="off"||t===!1?{route:"flat",mono3d:"off"}:i?s?{route:"flat",mono3d:"failed"}:r?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function Tt(n){return n==="woven-sbs"?"3D":n==="lifted"?"2D\u21923D":"2D"}function Ct({need:n=10,needNoPose:e=30}={}){let t=0,i=0,r=!1;return{feed(s){return r?!0:(i++,s===null?r=i>=e:(t=s>=1?t+1:0,r=t>=n),r)},get live(){return r}}}function Ne(n,e){let t=Math.max(1,e|0),r=n==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return r[Math.min(t,r.length)-1]}function H(n,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let r=Math.min(t,e*Math.pow(2,Math.max(0,n)));return Math.round(r*(.8+.4*i()))}var we=Object.freeze(["VP9","VP8","AV1"]);function nr(n,e=we){let t=e.indexOf(String(n||"").toUpperCase());return t<0?e.length:t}function ze(n,e=we){let t=i=>nr(String(i.mimeType||"").split("/")[1],e);return n.map((i,r)=>({c:i,i:r,r:t(i)})).sort((i,r)=>i.r-r.r||i.i-r.i).map(i=>i.c)}function be(n,e=we){if(!n)return n;let t=n.includes(`\r
3
+ `)?`\r
4
+ `:`
5
+ `,i=n.split(t),r=i.findIndex(d=>d.startsWith("m=video"));if(r<0)return n;let s=i.findIndex((d,m)=>m>r&&d.startsWith("m="));s<0&&(s=i.length);let o=i.slice(r,s),a=new Map,l=new Map;for(let d of o){let m=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);m&&a.set(m[1],m[2].toUpperCase());let u=d.match(/^a=fmtp:(\d+) apt=(\d+)/);u&&(l.has(u[2])||l.set(u[2],[]),l.get(u[2]).push(u[1]))}let c=i[r].split(" "),p=c.slice(3),f=[];for(let d of e)for(let m of p)if(a.get(m)===d&&!f.includes(m)){f.push(m);for(let u of l.get(m)||[])p.includes(u)&&!f.includes(u)&&f.push(u)}if(!f.length)return n;let h=p.filter(d=>!f.includes(d));return i[r]=[...c.slice(0,3),...f,...h].join(" "),i.join(t)}var Ai=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),sr=4e3,or=1e4,ar=2e4,lr=8e3,cr=1e4;function Se(n){let e=Number.isInteger(n)?n:ne;return Math.max(2,Math.min(Ri,e))}function Pi(n,e){return n<e}var xe=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:r,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:cr,this.signaling=e,this.id=t,this.maxPeers=Se(i),this.pageIce=r||null,this.iceServers=r||Ai,this.PC=s||globalThis.RTCPeerConnection,this.log=o||(()=>{}),this.peers=new Map,this.session=null,this.ready=!1,this._pending=[],this.stopped=!1,this.sendFormat="mono",this.localStream=null}get size(){return this.peers.size}async start({room:e,localStream:t,sendFormat:i,onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:f}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:r,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:f};let h=u=>(...v)=>this.ready?u(...v):this._pending.push(()=>u(...v));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(u=>this._onPeerJoined(u)),onPeerLeft:h(u=>this._onPeerLeftSignaling(u)),onSignal:h((u,v)=>this._onSignal(u,v)),onDisconnect:u=>p?.(u?"closed":"reconnecting",u),onPeerUnreachable:h(u=>f?.(u,!0)),onPeerReachable:h(u=>f?.(u,!1)),onReconnect:h(u=>{p?.("connected");for(let v of u)this._onPeerJoined(v)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Ai,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let u=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw u.code="room-full",u}this.ready=!0;for(let u of d)this._onPeerJoined(u);let m=this._pending;this._pending=[];for(let u of m)u();return this.session}_onPeerJoined(e){if(this.stopped||e===this.id)return;let t=this.peers.get(e);if(t){t.absent=!1,t.state!=="connected"&&Pi(this.id,e)&&this._rebuild(t,"rejoined");return}if(this.peers.size>=this.maxPeers-1){this.log("refused",{peer:e,reason:"maxPeers",maxPeers:this.maxPeers}),this.cb.onRefused?.(e);return}let i=this._newRecord(e);this.cb.onPeer?.(e),i.offerer?this._build(i,1):i.waitTimer=setTimeout(()=>this._askRestart(i),lr)}_onPeerLeftSignaling(e){let t=this.peers.get(e);t&&(t.absent=!0,t.state!=="connected"&&this._drop(t,"left"))}_newRecord(e){let t={id:e,offerer:Pi(this.id,e),pc:null,builtAt:0,offerAt:0,dc:null,gen:0,state:"new",stream:null,attempts:0,iceRestarted:!1,absent:!1,pendingCandidates:[],timers:new Set,waitTimer:null,unreachable:!1,unreachTimer:null};return this.peers.set(e,t),this._armUnreachable(t),t}_build(e,t){this._closePc(e),e.gen=t,e.builtAt=Date.now(),e.iceRestarted=!1,e.pendingCandidates=[],e.stream=null;let i=new this.PC({iceServers:this.iceServers});e.pc=i;let r=i.createDataChannel("dxr-call",{negotiated:!0,id:0,ordered:!0});if(this._wireDc(e,r),e.offerer){let s=this.localStream?this.localStream.getTracks():[],o=s.find(p=>p.kind==="audio"),a=s.find(p=>p.kind==="video"),l=this.localStream?[this.localStream]:[];i.addTransceiver(o||"audio",{direction:"sendrecv",streams:l});let c=i.addTransceiver(a||"video",{direction:"sendrecv",streams:l});this._preferCodecs(c)}return i.onicecandidate=s=>{s.candidate&&this._signal(e,{kind:"candidate",candidate:s.candidate.toJSON?s.candidate.toJSON():s.candidate})},i.ontrack=s=>{if(e.stream||(e.stream=new MediaStream),!e.stream.getTracks().includes(s.track)){for(let o of e.stream.getTracks())o.kind===s.track.kind&&e.stream.removeTrack(o);e.stream.addTrack(s.track)}this.cb.onStream?.(e.id,e.stream)},i.onconnectionstatechange=()=>this._onConnState(e,i),this._arm(e,ar,()=>{e.pc===i&&i.connectionState!=="connected"&&this._fail(e,"connect-timeout")}),e.offerer&&this._offer(e).catch(s=>this.log("offer-error",{peer:e.id,err:String(s)})),this._setState(e,e.attempts>0?"reconnecting":"connecting"),i}async _offer(e,{iceRestart:t=!1}={}){let i=e.pc,r=await i.createOffer(t?{iceRestart:!0}:void 0);this._canPreferCodecs||(r.sdp=be(r.sdp)),await i.setLocalDescription(r),this._signal(e,{kind:"offer",sdp:i.localDescription.sdp})}async _onSignal(e,t){if(this.stopped||!t||typeof t!="object")return;let i=this.peers.get(e);if(!i&&(t.kind!=="offer"||(this._onPeerJoined(e),i=this.peers.get(e),!i)))return;let r=t.gen|0;try{switch(t.kind){case"offer":{if(i.offerer||(clearTimeout(i.waitTimer),r<i.gen))return;i.offerAt=Date.now(),(r>i.gen||!i.pc)&&this._build(i,r);let s=i.pc;await s.setRemoteDescription({type:"offer",sdp:t.sdp}),this._attachAnswererTracks(i);let o=await s.createAnswer();this._canPreferCodecs||(o.sdp=be(o.sdp)),await s.setLocalDescription(o),this._signal(i,{kind:"answer",sdp:s.localDescription.sdp}),this._flushCandidates(i);break}case"answer":if(!i.offerer||r!==i.gen||!i.pc||i.pc.signalingState!=="have-local-offer")return;await i.pc.setRemoteDescription({type:"answer",sdp:t.sdp}),this._flushCandidates(i);break;case"candidate":if(r!==i.gen||!i.pc)return;i.pc.remoteDescription?await i.pc.addIceCandidate(t.candidate).catch(()=>{}):i.pendingCandidates.push(t.candidate);break;case"restart":if(!i.offerer||i.pc&&i.state!=="connected"&&Date.now()-i.builtAt<5e3)return;this._rebuild(i,"peer-asked");break;case"bye":this._drop(i,"left");break}}catch(s){this.log("signal-error",{peer:e,kind:t.kind,err:String(s)})}}_flushCandidates(e){let t=e.pendingCandidates;e.pendingCandidates=[];for(let i of t)e.pc.addIceCandidate(i).catch(()=>{})}_attachAnswererTracks(e){let t=e.pc,i=this.localStream?this.localStream.getTracks():[];for(let r of t.getTransceivers()){let s=r.receiver&&r.receiver.track?r.receiver.track.kind:null;if(!s||r.sender.track)continue;let o=i.find(a=>a.kind===s);o&&(r.sender.replaceTrack(o).catch(()=>{}),this.localStream&&r.sender.setStreams&&r.sender.setStreams(this.localStream)),r.direction="sendrecv",s==="video"&&this._preferCodecs(r)}}_preferCodecs(e){let t=globalThis.RTCRtpReceiver&&RTCRtpReceiver.getCapabilities&&RTCRtpReceiver.getCapabilities("video");if(this._canPreferCodecs=!!(e&&e.setCodecPreferences&&t),!!this._canPreferCodecs)try{e.setCodecPreferences(ze(t.codecs))}catch{this._canPreferCodecs=!1}}_onConnState(e,t){if(e.pc!==t)return;let i=t.connectionState;this.log("pc-state",{peer:e.id,state:i,gen:e.gen}),i==="connected"?(this._clearTimers(e),e.attempts=0,e.iceRestarted=!1,this._setState(e,"connected"),this.tuneSenders()):i==="disconnected"?(this._setState(e,"reconnecting"),this._arm(e,sr,()=>{e.pc===t&&t.connectionState!=="connected"&&this._fail(e,"disconnected")})):i==="failed"?this._fail(e,"failed"):i==="closed"&&!this.stopped&&this.peers.get(e.id)===e&&this._fail(e,"closed")}_fail(e,t){if(this.stopped||this.peers.get(e.id)!==e)return;if(e.absent)return this._drop(e,"left");if(this._setState(e,"reconnecting"),!e.offerer)return this._askRestart(e);let i=e.pc;if(i&&!e.iceRestarted&&i.connectionState!=="closed"&&i.signalingState!=="closed"){e.iceRestarted=!0,this.log("ice-restart",{peer:e.id,why:t,gen:e.gen}),this._offer(e,{iceRestart:!0}).catch(()=>this._rebuild(e,"ice-restart-failed")),this._arm(e,or,()=>{e.pc===i&&i.connectionState!=="connected"&&this._rebuild(e,"ice-restart-timeout")});return}this._rebuild(e,t)}_rebuild(e,t){if(this.stopped||this.peers.get(e.id)!==e)return;this._clearTimers(e),this._closePc(e),this._setState(e,"reconnecting");let i=H(e.attempts++);this.log("redial",{peer:e.id,why:t,attempt:e.attempts,inMs:i}),this._arm(e,i,()=>this._build(e,e.gen+1))}_askRestart(e){if(this.stopped||this.peers.get(e.id)!==e||e.offerer)return;let t=Date.now();this._signal(e,{kind:"restart"}),this._arm(e,Math.max(3e3,H(e.attempts++)),()=>{e.state!=="connected"&&!(e.offerAt>=t)&&this._askRestart(e)})}_drop(e,t){this.peers.get(e.id)===e&&(this._clearTimers(e),clearTimeout(e.unreachTimer),clearTimeout(e.waitTimer),this._closePc(e),this.peers.delete(e.id),this._setState(e,"left"),this.cb.onPeerLeft?.(e.id,t),this.tuneSenders())}_closePc(e){if(e.dc){try{e.dc.close()}catch{}e.dc=null}if(e.pc){let t=e.pc;e.pc=null;try{t.close()}catch{}}}_arm(e,t,i){let r=setTimeout(()=>{e.timers.delete(r),i()},t);e.timers.add(r)}_clearTimers(e){for(let t of e.timers)clearTimeout(t);e.timers.clear()}_armUnreachable(e){e.unreachTimer||e.unreachable||(e.unreachTimer=setTimeout(()=>{e.unreachTimer=null,!(this.stopped||this.peers.get(e.id)!==e||e.state==="connected")&&(e.unreachable=!0,this.log("unreachable",{peer:e.id,afterMs:this.unreachableMs,pc:e.pc?e.pc.iceConnectionState:null}),this._setState(e,"unreachable"))},this.unreachableMs))}_setState(e,t){t==="connected"?(clearTimeout(e.unreachTimer),e.unreachTimer=null,e.unreachable=!1):(t==="connecting"||t==="reconnecting")&&(e.unreachable?t="unreachable":this._armUnreachable(e)),e.state!==t&&(e.state=t,this.cb.onPeerState?.(e.id,t))}_signal(e,t){this.session?.send(e.id,{...t,gen:e.gen})}_wireDc(e,t){e.dc=t,t.onopen=()=>this.cb.onMessage?.(e.id,{type:"__open"}),t.onmessage=i=>{let r;try{r=JSON.parse(i.data)}catch{return}if(r&&r.type==="bye")return this._drop(e,"left");this.cb.onMessage?.(e.id,r)}}send(e,t){let i=this.peers.get(e);return i&&i.dc&&i.dc.readyState==="open"?(i.dc.send(JSON.stringify(t)),!0):!1}broadcast(e){for(let t of this.peers.keys())this.send(t,e)}peerConnection(e){let t=this.peers.get(e);return t?t.pc:null}peerState(e){let t=this.peers.get(e);return t?t.state:null}async replaceTrack(e,t,i){i&&(this.localStream=i);for(let r of this.peers.values())if(r.pc)for(let s of r.pc.getTransceivers())(s.receiver&&s.receiver.track?s.receiver.track.kind:null)===e&&await s.sender.replaceTrack(t).catch(()=>{});await this.tuneSenders()}setSendFormat(e){return this.sendFormat=e,this.tuneSenders()}async tuneSenders(){let e=this.peers.size,t=Ne(this.sendFormat,e);for(let i of this.peers.values())if(i.pc){for(let r of i.pc.getSenders())if(!(!r.track||r.track.kind!=="video"))try{let s=r.getParameters();s.degradationPreference="maintain-resolution",(!s.encodings||!s.encodings.length)&&(s.encodings=[{}]),s.encodings[0].maxBitrate=t*1e3,await r.setParameters(s)}catch(s){this.log("setParameters-error",{peer:i.id,err:String(s)})}}return t}stop(){if(!this.stopped){this.broadcast({type:"bye"}),this.stopped=!0;for(let e of this.peers.values())this._clearTimers(e),clearTimeout(e.waitTimer),clearTimeout(e.unreachTimer),this._signal(e,{kind:"bye"}),this._closePc(e);this.peers.clear();try{this.session?.leave()}catch{}}}_debugKill(e){let t=this.peers.get(e);return!t||!t.pc?!1:(this._closePc(t),this._fail(t,"debug-kill"),!0)}};var Ii={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},Rt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},dr=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function hr(n){return!!n&&(n.name==="NotReadableError"||n.name==="TrackStartError"||/in use|busy/i.test(n.message||""))}function fr(n){return!!n&&(n.name==="NotAllowedError"||n.name==="PermissionDeniedError"||n.name==="SecurityError")}function Fi(n){return n.length&&n.every(e=>e.busy)?"camera-busy":n.some(e=>e.denied)?"permission-denied":"no-camera"}function Dt(n){return/stereo|\b3d\b|\bsbs\b|dual/i.test(n||"")}async function ji(n="auto",e={}){let t=e.mediaDevices||globalThis.navigator&&navigator.mediaDevices,i=e.log||(()=>{}),r=[],s=e.calibration||{};if(n&&typeof n=="object"&&typeof n.getVideoTracks=="function"){let m=n.getVideoTracks()[0],u=m?m.getSettings():{},v=e.format==="sbs"?"sbs":"mono";return{stream:n,format:v,width:u.width||0,height:u.height||0,deviceId:u.deviceId||null,label:m?m.label:"",owned:!1,skipped:r,calibration:s}}if(!t||!t.getUserMedia)throw Object.assign(new Error("getUserMedia is not available (insecure context?)"),{code:"no-camera"});let o=async m=>{let u=await t.getUserMedia({video:m,audio:!1}),v=u.getVideoTracks()[0],y=v?v.getSettings():{};if(!v||v.readyState==="ended"||!(y.width>0)||!(y.height>0))throw u.getTracks().forEach(M=>M.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let x=y.displayxrStereo&&y.displayxrStereo.layout==="side-by-side"?y.displayxrStereo:null;return{stream:u,track:v,width:y.width,height:y.height,deviceId:y.deviceId||null,label:v.label||"",stereo:x}},a=(m,u)=>{r.push({label:m,error:`${u.name}: ${u.message}`,busy:hr(u),denied:fr(u)}),i("camera-skip",{label:m,error:u.name})},l=m=>m&&m.stream.getTracks().forEach(u=>u.stop()),c=(m,u)=>({stream:m.stream,format:u,width:m.width,height:m.height,deviceId:m.deviceId,label:m.label,owned:!0,skipped:r,calibration:{rectified:!1,...u==="sbs"&&m.stereo?{rectified:!!m.stereo.rectified,...m.stereo.baselineMm>0?{baselineMm:m.stereo.baselineMm}:{},...m.stereo.horizontalFovDeg>0?{hfovDeg:m.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof n=="string"&&!["auto","stereo","mono"].includes(n)){let m;try{m=await o({deviceId:{exact:n},...Rt})}catch(u){throw a(n,u),Object.assign(new Error(`camera unavailable: ${u.message}`),{code:Fi(r),skipped:r})}return te(m.width,m.height)?c(m,"sbs"):(l(m),c(await o({deviceId:{exact:n},...Ii}),"mono"))}let p=new Set;if(n!=="mono"){let m=[];try{m=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput"&&u.deviceId&&Dt(u.label))}catch{}for(let u of m){p.add(u.deviceId);let v=null;try{v=await o({deviceId:{exact:u.deviceId},...Rt})}catch(y){a(u.label,y);continue}if(te(v.width,v.height))return i("camera-sbs",{label:v.label,width:v.width,height:v.height,direct:!0}),c(v,"sbs");l(v)}}let f=null;try{f=await o(Ii)}catch(m){a("default",m)}if(n==="mono"&&f)return c(f,"mono");if(f&&te(f.width,f.height))return c(f,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(m=>m.kind==="videoinput")}catch{}h.sort((m,u)=>Number(Dt(u.label))-Number(Dt(m.label)));for(let m of h){if(!m.deviceId||f&&m.deviceId===f.deviceId||p.has(m.deviceId))continue;let u=null;try{u=await o({deviceId:{exact:m.deviceId},...Rt})}catch(v){a(m.label,v);continue}if(te(u.width,u.height))return l(f),i("camera-sbs",{label:u.label,width:u.width,height:u.height}),c(u,"sbs");l(u)}if(f)return n==="stereo"&&i("camera-no-stereo",{fallback:f.label}),c(f,"mono");let d=Fi(r);throw Object.assign(new Error(d==="camera-busy"?"every camera is in use by another app (e.g. eye tracking)":d==="permission-denied"?"camera access was denied":"no camera could be opened"),{code:d,skipped:r})}async function Wi(n={}){let e=n.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...dr},video:!1})).getAudioTracks()[0]||null}catch(t){return(n.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}function He(n,e,t,i,r,s,o,a,l,c,p){if(s<0||s+a>t||o<0)return-1;let f=0,h=0,d=0,m=a*l;for(let y=0;y<l;y++){let x=(r+y)*e+i,M=(o+y)*e+t+s;for(let b=0;b<a;b++){let A=n[M+b];f+=A,h+=A*A,d+=n[x+b]*A}}let u=f/m,v=h/m-u*u;return v<1?-1:(d/m-c*u)/(p*Math.sqrt(v))}function ur(n,e,t,i,r,s){let o=0,a=0;for(let p=0;p<s;p++){let f=(i+p)*e+t;for(let h=0;h<r;h++){let d=n[f+h];o+=d,a+=d*d}}let l=r*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function Lt(n,e,t,i,r,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:p}={}){let f=e/2,{mean:h,std:d}=ur(n,e,i,r,s,o);if(d<6)return null;let m=-2,u=0,v=0,y=new Map,x=(L,g,w,_,S)=>{for(let D=_;D<=S;D++){let T=r+D;if(!(T<0||T+o>t))for(let j=L;j<=g;j+=w){let X=He(n,e,f,i,r,i-j,T,s,o,h,d);X>(y.get(j)??-2)&&y.set(j,X),X>m&&(m=X,u=j,v=D)}}},M=l-a>8;if(x(a,l,M?2:1,-c,c),M&&m>-1){let L=u,g=v;x(Math.max(a,L-2),Math.min(l,L+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(m<-1)return null;let b=-2,A=L=>{let g=-2;for(let w=-c;w<=c;w++){let _=r+w;if(!(_<0||_+o>t))for(let S=L-1;S<=L+1;S++)g=Math.max(g,He(n,e,f,i,r,i-S,_,s,o,h,d))}return g};for(let[L,g]of y){if(Math.abs(L-u)<3||g<=b)continue;let _=g>=(y.get(L-2)??-2)&&g>=(y.get(L+2)??-2)&&g>0?A(L):g;_>b&&(b=_)}if(l-a>12&&b>-2&&m-b<(p??.08))return null;let E=He(n,e,f,i,r,i-(u-1),r+v,s,o,h,d),O=He(n,e,f,i,r,i-(u+1),r+v,s,o,h,d),R=0,P=E-2*m+O;return E>-1&&O>-1&&P<0&&(R=Math.max(-.5,Math.min(.5,.5*(E-O)/P))),{d:u+R,dy:v,c:m}}function mr(n,e,t,i={}){let r=e/2,s=i.block||Math.max(8,Math.round(r/20)),o=i.step||Math.round(s*1.5),a=i.dMax??Math.round(r*.3),l=i.dMin??-Math.round(r*.05),c=Math.round(r*(i.roiX0??.15)),p=Math.round(r*(i.roiX1??.85))-s,f=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let m=f;m<=h;m+=o)for(let u=c;u<=p;u+=o){let v=Lt(n,e,t,u,m,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});v&&v.c>=(i.minNcc??.8)&&d.push({x:u,y:m,...v})}return d}function pr(n,{tol:e=2,minFrac:t=.12,minBlocks:i=3}={}){if(!n.length)return null;let r=Math.max(i,Math.ceil(n.length*t)),s=n.map(o=>o.d).sort((o,a)=>a-o);for(let o of s){let a=n.filter(l=>Math.abs(l.d-o)<=e);if(a.length>=r){let l=a.map(c=>c.d).sort((c,p)=>c-p);return{d:l[l.length>>1],members:a}}}return null}function gr(n,e){let t=Math.min(...n.map(l=>l.y)),r=n.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...r),o=Math.max(...r)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function Ot(n,e,t,i={}){let r=e/2,s=i.block||Math.max(8,Math.round(r/20)),o=i.dMax??Math.round(r*.3),a=i.dMin??-Math.round(r*.05),l=i.focus||null,c="focus",p=0,f=null;if(!l){let M=mr(n,e,t,{...i,block:s,dMax:o,dMin:a});p=M.length;let b=pr(M,i);if(!b)return null;l=gr(b.members,s),f=b.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),m=Math.round(Math.max(0,Math.min(r-h,l.x-h/2))),u=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),v=f===null?a:Math.max(a,Math.floor(f)-4),y=f===null?o:Math.min(o,Math.ceil(f)+4),x=Lt(n,e,t,m,u,h,d,{dMin:v,dMax:y,dyMax:i.dyMax??2});return x&&x.c>=(i.minNcc??.8)?{d:x.d,x:l.x,y:l.y,c:x.c,method:c,blocks:p}:f!==null?{d:f,x:l.x,y:l.y,c:0,method:c,blocks:p}:null}function Ve(n,e){let t=new Uint8Array(e);for(let i=0,r=0;i<e;i++,r+=4)t[i]=n[r]*77+n[r+1]*150+n[r+2]*29>>8;return t}function $e({n=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>n&&e.shift();let r=[...e].sort((s,o)=>s-o);return t.value=r[r.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function Ni(n,e,t,i,r,s){let o=new Float32Array(r*s);for(let a=0;a<s;a++)for(let l=0;l<r;l++)o[a*r+l]=n[(i+a)*e+t+l];return o}function _r(n,e,t,i,r,s,o,a,l,c){let p=e/2,f=r*s,h=0,d=0;for(let x=0;x<f;x++)h+=i[x],d+=i[x]*i[x];h/=f;let m=Math.sqrt(Math.max(1e-6,d/f-h*h)),u=-2,v=o,y=a;for(let x=Math.max(0,a-c);x<=Math.min(t-s,a+c);x++)for(let M=Math.max(0,o-l);M<=Math.min(p-r,o+l);M++){let b=0,A=0,E=0;for(let L=0;L<s;L++){let g=(x+L)*e+M;for(let w=0;w<r;w++){let _=n[g+w];b+=_,A+=_*_,E+=_*i[L*r+w]}}let O=b/f,R=A/f-O*O;if(R<1)continue;let P=(E/f-O*h)/(Math.sqrt(R)*m);P>u&&(u=P,v=M,y=x)}return{x:v,y,c:u}}function Me({fullEveryMs:n=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:r=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,p,f,h,d={}){let m=p/2,u=d.block||Math.max(8,Math.round(m/20)),v=Math.round(u*3),y=Math.round(u*1.5),x=null;if(o&&o.w===v&&o.h===y){let O=_r(c,p,f,o.tpl,v,y,o.x,o.y,t,i);if(O.c>=r){let R=Lt(c,p,f,O.x,O.y,v,y,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});R&&R.c>=.8&&(x={m:R,f:O})}}let M=({m:O,f:R})=>(o={...o,x:R.x,y:R.y,d:O.d,tpl:Ni(c,p,R.x,R.y,v,y)},{d:O.d,x:R.x+v/2,y:R.y+y/2,c:O.c,method:"track",blocks:0});if(x&&h-o.at<n)return M(x);let b=Ot(c,p,f,d);if(x&&(!b||Math.abs(b.d-x.m.d)>s)){let O=b&&a&&Math.abs(a.d-b.d)<=3;if(a=b&&!O?{d:b.d}:null,!O)return o.at=h,M(x)}else a=null;if(!b)return o=null,null;let A=Math.round(Math.max(0,Math.min(m-v,b.x-v/2))),E=Math.round(Math.max(0,Math.min(f-y,b.y-y/2)));return o={x:A,y:E,d:b.d,tpl:Ni(c,p,A,E,v,y),w:v,h:y,at:h},b},reset(){o=null,a=null}}}function zi(n,e,t,i,r,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(r/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let d=0;d<l;d++)for(let m=0;m<a;m++){let u=0;for(let v=0;v<o;v++){let y=e+(d*o+v)*t+m*o;for(let x=0;x<o;x++)u+=n[y+x]}c[d*a+m]=u/h|0}return{img:c,w:a,h:l}}let p=o>>2,f=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+p)*t,m=e+(h*o+f)*t;for(let u=0;u<a;u++){let v=u*o+p,y=u*o+f;c[h*a+u]=n[d+v]+n[d+y]+n[m+v]+n[m+y]>>2}}return{img:c,w:a,h:l}}var Hi="http://displayxr.org/ns/stereo/1.0/",Be="http://ns.adobe.com/xap/1.0/\0";function qe(n={}){let e=i=>typeof i=="number"&&Number.isFinite(i)?i:null,t=n.layout==="sbs"||n.layout==="side-by-side"?"sbs":"mono";return{layout:t,columns:t==="sbs"?2:1,rows:1,convergencePx:e(n.convergencePx),baselineMm:e(n.baselineMm),horizontalFovDeg:e(n.horizontalFovDeg),rectified:n.rectified===!0?!0:n.rectified===!1?!1:null,eyeWidth:e(n.eyeWidth),eyeHeight:e(n.eyeHeight),software:typeof n.software=="string"&&n.software?n.software:null}}var vr=n=>String(n).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),oe=n=>Math.round(n*1e3)/1e3;function Vi(n){let e=qe(n),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:oe(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:oe(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:oe(e.horizontalFovDeg)],["Rectified",e.rectified===null?null:e.rectified?"True":"False"],["EyeWidth",e.eyeWidth],["EyeHeight",e.eyeHeight],["Software",e.software]].filter(([,i])=>i!=null).map(([i,r])=>` dxr:${i}="${vr(r)}"`).join("");return`<?xpacket begin="\uFEFF" id="W5M0MpCehiHzreSzNTczkc9d"?><x:xmpmeta xmlns:x="adobe:ns:meta/"><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="" xmlns:dxr="${Hi}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Pt(n){if(typeof n!="string"||!n.includes(Hi))return null;let e=o=>{let a=new RegExp(`\\bdxr:${o}="([^"]*)"`).exec(n);if(a)return a[1];let l=new RegExp(`<dxr:${o}>([^<]*)</dxr:${o}>`).exec(n);return l?l[1]:null},t=o=>{let a=e(o);return a===null||a===""||!Number.isFinite(+a)?null:+a},i=e("Rectified"),r=e("Layout"),s=e("Software");return qe({layout:r==="side-by-side"||r==="sbs"?"sbs":"mono",convergencePx:t("ConvergencePx"),baselineMm:t("BaselineMm"),horizontalFovDeg:t("HorizontalFovDeg"),rectified:i===null?null:/^true$/i.test(i),eyeWidth:t("EyeWidth"),eyeHeight:t("EyeHeight"),software:s===null?null:s.replace(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&amp;/g,"&")})}var Ue=n=>new TextEncoder().encode(n),At=n=>new TextDecoder().decode(n),$i=n=>n.length>4&&n[0]===255&&n[1]===216;function*Bi(n){let e=2;for(;e+4<=n.length;){if(n[e]!==255)return;let t=n[e+1];if(t===216||t>=208&&t<=215||t===1||t===255){e+=t===255?1:2;continue}if(t===218||t===217)return;let i=n[e+2]<<8|n[e+3];if(i<2||e+2+i>n.length)return;yield{marker:t,start:e,end:e+2+i,data:n.subarray(e+4,e+2+i)},e+=2+i}}function Ui(n,e){if(n.length<e.length)return!1;for(let t=0;t<e.length;t++)if(n[t]!==e.charCodeAt(t))return!1;return!0}function qi(n,e){if(!$i(n))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Ue(Be),...Ue(e)]),i=t.length+2;if(i>65535)throw new RangeError("jpegWithXmp: XMP packet too large for one APP1 segment");let r=new Uint8Array(4+t.length);r[0]=255,r[1]=225,r[2]=i>>8,r[3]=i&255,r.set(t,4);let s=2,o=null;for(let p of Bi(n)){if(p.marker===225&&Ui(p.data,Be)){o=p;break}if(p.marker===224||p.marker===225)s=p.end;else break}let[a,l]=o?[o.start,o.end]:[s,s],c=new Uint8Array(n.length-(l-a)+r.length);return c.set(n.subarray(0,a),0),c.set(r,a),c.set(n.subarray(l),a+r.length),c}function It(n){if(!$i(n))return null;for(let e of Bi(n))if(e.marker===225&&Ui(e.data,Be))return At(e.data.subarray(Be.length));return null}var Xi=n=>Pt(It(n)),W={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},yr=n=>n.length>4&&n[0]===26&&n[1]===69&&n[2]===223&&n[3]===163;function Gi(n){let e=[];for(let t=n;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function Ji(n,e=0){let t=e;if(!t)for(t=1;t<8&&n>2**(7*t)-2;t++);let i=new Array(t).fill(0),r=n;for(let s=t-1;s>=1;s--)i[s]=r%256,r=Math.floor(r/256);return i[0]=128>>t-1|r,i}function Ft(n,e){let t=n[e],i=t>=128?1:t>=64?2:t>=32?3:t>=16?4:0;if(!i||e+i>n.length)return null;let r=0;for(let s=0;s<i;s++)r=r*256+n[e+s];return{id:r,width:i}}function ke(n,e){let t=n[e],i=1;for(;i<=8&&!(t&128>>i-1);)i++;if(i>8||e+i>n.length)return null;let r=t&255>>i,s=r===127>>i-1;for(let o=1;o<i;o++)r=r*256+n[e+o],n[e+o]!==255&&(s=!1);return{size:r,width:i,unknown:s}}function se(n,e){return[...Gi(n),...Ji(e.length),...e]}function wr(n){let e=[];for(let[i,r]of Object.entries(n))r!=null&&e.push(...se(W.SimpleTag,[...se(W.TagName,[...Ue(String(i))]),...se(W.TagString,[...Ue(String(r))])]));let t=se(W.Tag,[...se(W.Targets,[]),...e]);return new Uint8Array(se(W.Tags,t))}function Ki(n){let e=qe(n);return{DXR_LAYOUT:e.layout==="sbs"?"side-by-side":"mono",DXR_COLUMNS:String(e.columns),DXR_ROWS:String(e.rows),DXR_CONVERGENCE_PX:e.convergencePx===null?null:String(oe(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(oe(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(oe(e.horizontalFovDeg)),DXR_RECTIFIED:e.rectified===null?null:e.rectified?"true":"false",DXR_EYE_WIDTH:e.eyeWidth===null?null:String(e.eyeWidth),DXR_EYE_HEIGHT:e.eyeHeight===null?null:String(e.eyeHeight),DXR_SOFTWARE:e.software}}function br(n){if(!n||!("DXR_LAYOUT"in n))return null;let e=t=>n[t]===void 0||n[t]===""||!Number.isFinite(+n[t])?null:+n[t];return qe({layout:n.DXR_LAYOUT==="side-by-side"?"sbs":"mono",convergencePx:e("DXR_CONVERGENCE_PX"),baselineMm:e("DXR_BASELINE_MM"),horizontalFovDeg:e("DXR_HFOV_DEG"),rectified:n.DXR_RECTIFIED===void 0?null:n.DXR_RECTIFIED==="true",eyeWidth:e("DXR_EYE_WIDTH"),eyeHeight:e("DXR_EYE_HEIGHT"),software:n.DXR_SOFTWARE??null})}function Yi(n){if(!yr(n))return null;let e=ke(n,4);if(!e)return null;let t=4+e.width+e.size;for(;t<n.length;){let i=Ft(n,t);if(!i)return null;let r=ke(n,t+i.width);if(!r)return null;let s=t+i.width+r.width;if(i.id===W.Segment)return{sizeAt:t+i.width,sizeWidth:r.width,unknown:r.unknown,dataStart:s,size:r.size};if(r.unknown)return null;t=s+r.size}return null}function Zi(n,e){let t=Yi(n);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=wr(e);if(t.unknown){let p=new Uint8Array(n.length+i.length);return p.set(n,0),p.set(i,n.length),p}let r=Math.min(n.length,t.dataStart+t.size),s=r-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=Ji(s,o?t.sizeWidth:8),l=new Uint8Array(t.sizeAt+a.length+(r-t.dataStart)+i.length+(n.length-r));l.set(n.subarray(0,t.sizeAt),0),l.set(a,t.sizeAt);let c=t.sizeAt+a.length;return l.set(n.subarray(t.dataStart,r),c),c+=r-t.dataStart,l.set(i,c),c+=i.length,l.set(n.subarray(r),c),l}function Qi(n,e,t){let i={},r=(s,o,a)=>{let l=s;for(;l<o;){let c=Ft(n,l);if(!c)return;let p=ke(n,l+c.width);if(!p||p.unknown)return;let f=l+c.width+p.width;a(c.id,f,Math.min(o,f+p.size)),l=f+p.size}};return r(e,t,(s,o,a)=>{s===W.Tag&&r(o,a,(l,c,p)=>{if(l!==W.SimpleTag)return;let f=null,h=null;r(c,p,(d,m,u)=>{d===W.TagName?f=At(n.subarray(m,u)):d===W.TagString&&(h=At(n.subarray(m,u)))}),f!==null&&(i[f]=h??"")})}),i}function xr(n){let e=Yi(n);if(!e)return null;let t=e.unknown?n.length:Math.min(n.length,e.dataStart+e.size),i=null,r=e.dataStart;for(;r<t;){let s=Ft(n,r);if(!s)break;let o=ke(n,r+s.width);if(!o)break;let a=r+s.width+o.width;if(s.id===W.Tags&&!o.unknown&&(i={...i||{},...Qi(n,a,Math.min(t,a+o.size))}),o.unknown){i=i||Sr(n,t);break}r=a+o.size}return i}function Sr(n,e){let t=Gi(W.Tags);for(let i=e-t.length-1;i>=0;i--){if(n[i]!==t[0]||n[i+1]!==t[1]||n[i+2]!==t[2]||n[i+3]!==t[3])continue;let r=ke(n,i+4);if(r&&!r.unknown&&i+4+r.width+r.size===e)return Qi(n,i+4+r.width,e)}return null}var en=n=>br(xr(n));var ae="[inline3d/camera]",rn="inline3d-camera/1",Mr=200,kr=240,Er=4e3,Tr=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],Xe=()=>typeof document<"u"&&document&&typeof document.createElement=="function",tn=()=>{let n=new Date,e=t=>String(t).padStart(2,"0");return`${n.getFullYear()}${e(n.getMonth()+1)}${e(n.getDate())}-${e(n.getHours())}${e(n.getMinutes())}${e(n.getSeconds())}`},Cr=n=>/jpe?g/.test(n)?"jpg":/png/.test(n)?"png":/webp/.test(n)?"webp":/mp4/.test(n)?"mp4":/webm/.test(n)?"webm":"bin";function Ge(n,e,t){return`${String(n||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${Cr(t)}`}var q=(n,e,t={})=>Object.assign(new Error(`${ae} ${n}`),{code:e,...t});function nn(n,e=Er){return n?(n.readyState||0)>=2&&n.videoWidth?Promise.resolve():new Promise((t,i)=>{let r=!1,s=()=>{r||(n.readyState||0)<2||!n.videoWidth||(r=!0,clearTimeout(o),n.removeEventListener("loadeddata",s),n.removeEventListener("playing",s),n.removeEventListener("resize",s),t())},o=setTimeout(()=>{r||(r=!0,i(q("the camera delivered no frame in time","no-frame")))},e);n.addEventListener("loadeddata",s),n.addEventListener("playing",s),n.addEventListener("resize",s),n.play?.().catch(()=>{})}):Promise.reject(q("no video element (no document?)","no-frame"))}function sn(n,e,t=kr){let i=n.videoWidth,r=n.videoHeight;if(!i||!r||(n.readyState||0)<2)return null;let s=Math.min(1,t/(i/2)),o=Math.max(2,Math.round(i*s/2)*2),a=Math.max(2,Math.round(r*s));(e.width!==o||e.height!==a)&&(e.width=o,e.height=a);let l=e.getContext("2d",{willReadFrequently:!0});try{return l.drawImage(n,0,0,o,a),{img:Ve(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var jt=class{constructor(e,{log:t=null}={}){this.format=e.format,this.stream=e.stream,this.width=e.width||0,this.height=e.height||0,this.deviceId=e.deviceId||null,this.label=e.label||"",this.owned=!!e.owned,this.skipped=Object.freeze([...e.skipped||[]]),this.calibration=Object.freeze({...e.calibration||{}});let i=this.calibration;this.stereo=this.format==="sbs"?Object.freeze({rectified:!!i.rectified,baselineMm:i.baselineMm>0?i.baselineMm:null,horizontalFovDeg:i.hfovDeg>0?i.hfovDeg:null}):null,this.state="live",this._log=t,this._listeners=new Map,this._scratch=null,this._views=new Set,this.video=null,Xe()&&(this.video=Object.assign(document.createElement("video"),{muted:!0,playsInline:!0,autoplay:!0}),this.video.srcObject=this.stream,this.video.play?.().catch(()=>{})),this._onEnded=()=>this._ended("ended");for(let r of this.stream.getVideoTracks())r.addEventListener?.("ended",this._onEnded)}get eyeWidth(){return this.format==="sbs"?this.width/2:this.width}log(e,t={}){this._log&&this._log(e,t)}on(e,t){if(typeof t!="function")throw new TypeError(`${ae} on() takes a function`);return this._listeners.has(e)||this._listeners.set(e,new Set),this._listeners.get(e).add(t),()=>this._listeners.get(e)?.delete(t)}off(e,t){this._listeners.get(e)?.delete(t)}_emit(e,t){for(let i of[...this._listeners.get(e)||[]])try{i(t)}catch(r){console.error(`${ae} '${e}' listener threw`,r)}}_ended(e){this.state==="live"&&(this.state="ended",this.log("ended",{reason:e}),this._emit("ended",{reason:e}))}async measureConvergence(){if(this.format!=="sbs"||!this.video||!Xe())return null;try{await nn(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=sn(this.video,this._scratch);if(!e)return null;let t=Me().measure(e.img,e.w,e.h,0);return t?t.d/e.scale:null}_meta(e,t=this.width,i=this.height){let r=this.stereo;return{layout:this.format,convergencePx:e,baselineMm:r?r.baselineMm:null,horizontalFovDeg:r?r.horizontalFovDeg:null,rectified:r?r.rectified:null,eyeWidth:this.format==="sbs"?t/2:t,eyeHeight:i,software:rn}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:r}={}){if(this.state==="closed")throw q("the camera is closed","closed");if(!this.video||!Xe())throw q("capturePhoto needs a document","no-frame");await nn(this.video);let s=this.video.videoWidth,o=this.video.videoHeight,a=typeof r=="number"&&Number.isFinite(r)?r:await this.measureConvergence(),l=document.createElement("canvas");l.width=s,l.height=o,l.getContext("2d").drawImage(this.video,0,0,s,o);let c=await new Promise((d,m)=>l.toBlob(u=>u?d(u):m(q("toBlob produced nothing","encode-failed")),e,t)),p=this._meta(a,s,o),f=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(f=Vi(p),c=new Blob([qi(new Uint8Array(await c.arrayBuffer()),f)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:Ge(i||`photo-${tn()}`,this.format,c.type||e),xmp:f};return this.log("photo",{width:s,height:o,layout:this.format,convergencePx:a,bytes:c.size,name:h.suggestedName}),h}record({mimeType:e,mono:t=!1,audio:i=null,videoBitsPerSecond:r,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw q("the camera is closed","closed");if(typeof MediaRecorder!="function")throw q("MediaRecorder is not available here","unsupported");let l=e||Tr.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw q(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],p=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...p);let f=new MediaStream(c),h={...l?{mimeType:l}:{},...r?{videoBitsPerSecond:r}:{}},d=new MediaRecorder(f,h),m=[];d.ondataavailable=g=>g.data&&g.data.size&&m.push(g.data);let u=null,v=[],y=null,x=0,M=!!t&&this.format==="sbs"&&Xe()&&this.video;if(M){y=document.createElement("canvas");let g=()=>{x=requestAnimationFrame(g);let _=this.video,S=_.videoWidth,D=_.videoHeight;!S||!D||(_.readyState||0)<2||((y.width!==S/2||y.height!==D)&&(y.width=S/2,y.height=D),y.getContext("2d").drawImage(_,0,0,S/2,D,0,0,S/2,D))};g();let w=y.captureStream(a);for(let _ of p)w.addTrack(_);u=new MediaRecorder(w,h),u.ondataavailable=_=>_.data&&_.data.size&&v.push(_.data)}let b=performance.now(),A=[],E=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&A.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&A.push(g)),d.start(s),u?.start(s),this.log("record-start",{mimeType:l,mono:M,audio:p.length});let O=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),R=o||`clip-${tn()}`,P=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),u&&u.state==="recording"&&u.pause()},resume(){d.state==="paused"&&d.resume(),u&&u.state==="paused"&&u.resume()},async stop(){clearInterval(E),x&&cancelAnimationFrame(x);let[g,w]=await Promise.all([O(d,m),O(u,v)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",S=[...A].sort((Qe,et)=>Qe-et),D=S.length?S[Math.floor(S.length/2)]:null,T=P._meta(D),j=/webm|matroska/.test(_),X=async(Qe,et)=>{let Te=new Blob(Qe,{type:_});if(j&&Te.size)try{Te=new Blob([Zi(new Uint8Array(await Te.arrayBuffer()),Ki({...T,layout:et}))],{type:_})}catch(ti){P.log("record-tag-failed",{message:String(ti&&ti.message)})}return Te},Ze=await X(g,P.format),G={blob:Ze,type:_,layout:P.format,durationMs:Math.round(performance.now()-b),convergencePx:D,stereo:P.stereo,suggestedName:Ge(R,P.format,_),tagged:j&&Ze.size>0};return u&&(G.mono=await X(w,"mono"),G.monoSuggestedName=Ge(R,"mono",_)),P.log("record-stop",{bytes:Ze.size,mono:G.mono?G.mono.size:null,ms:G.durationMs,convergencePx:D,name:G.suggestedName}),G}}}close(){if(this.state!=="closed"){this.state="closed";for(let e of this.stream.getVideoTracks())e.removeEventListener?.("ended",this._onEnded);for(let e of[...this._views])e.remove();this.owned&&this.stream.getTracks().forEach(e=>e.stop()),this.video&&(this.video.srcObject=null),this.log("closed",{})}}};async function Nt(n={}){let e=typeof n=="string"||n&&typeof n.getVideoTracks=="function"?{prefer:n}:n||{},t=e.prefer===void 0||e.prefer===null?"auto":e.prefer,i=typeof e.log=="function"?e.log:e.debug?(a,l)=>console.log(`${ae} ${a} ${JSON.stringify(l)}`):null,r=e.calibration&&typeof e.calibration=="object"?{...e.calibration}:{};r.horizontalFovDeg>0&&!(r.hfovDeg>0)&&(r.hfovDeg=r.horizontalFovDeg),delete r.horizontalFovDeg;let s=await ji(t,{format:e.format,calibration:r,mediaDevices:e.mediaDevices,log:i||void 0});if(s.format==="sbs"&&typeof e.rectify=="function")try{let a=await e.rectify(s.stream,{width:s.width,height:s.height,deviceId:s.deviceId,label:s.label});a&&typeof a.getVideoTracks=="function"&&(s.stream=a,s.calibration={...s.calibration,rectified:!0})}catch(a){i?.("rectify-failed",{message:String(a&&a.message)}),s.rectifyError=a}let o=new jt(s,{log:i});return s.rectifyError&&(o.rectifyError=s.rectifyError),o.log("open",{format:o.format,width:o.width,height:o.height,label:o.label,stereo:o.stereo,skipped:o.skipped.length}),o}var Je=n=>!!n&&typeof n=="object"&&typeof n.capturePhoto=="function"&&typeof n.record=="function"&&n.stream&&typeof n.stream.getVideoTracks=="function";function Rr(n){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((n.clientWidth||0)*e),i=Math.round((n.clientHeight||0)*e);return!t||!i?!1:((n.width!==t||n.height!==i)&&(n.width=t,n.height=i),!0)}function zt(n,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${ae} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!Je(t))throw new TypeError(`${ae} addCameraView: cam must be a StereoCamera from openCamera()`);let r=new Wt(n,e,t,i);return t._views?.add(r),r}var Wt=class{constructor(e,t,i,r){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=r.mirror===void 0?!0:!!r.mirror,this.aspect=typeof r.aspect=="number"&&r.aspect>.3&&r.aspect<4?r.aspect:16/9,this.autoConverge=!!r.autoConverge,this.conv=ve(),this.conv.depth=0,this.setDepth(r.depth),this.route=null,this.handle=null,this.buffer=null,this.removed=!1,this._raf=0,this._loop=r._loop!==!1,this._autoAt=0,this._track=$e(),this._focus=Me(),this._scratch=null,this.disparityPx=null,this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}get convergencePx(){return this.conv.current}get depth(){return this.conv.depth}setDepth(e){let t=e==null||!Number.isFinite(+e)?0:Math.max(-1,Math.min(1,+e));return this.conv.depth=t,t}setMirror(e){return this.mirror=e===void 0?!this.mirror:!!e,this.mirror}setAutoConverge(e){return this.autoConverge=e===void 0?!this.autoConverge:!!e,this.autoConverge||(this._track.reset(),this._focus.reset(),this.conv.measuredPx=null,this.disparityPx=null),this.autoConverge}_reroute(e,t){if(t!==void 0&&(this.wall=t),this.removed)return;let i=this.cam,r=i.state==="live"&&i.video,s=i.format==="sbs"&&r&&this.wall&&this.wall.supported?"woven-sbs":i.format==="sbs"?"flat-left":"flat";!e&&s===this.route||(this._unregister(),this.route=s,s==="woven-sbs"&&(this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven(),this.handle=this.wall.addImage(this.canvas,this.buffer)))}_onWallLost(){this._reroute(!0,{supported:!1})}_unregister(){if(this.handle){try{this.handle.remove()}catch{}this.handle=null}}_start(){let e=()=>{this._raf=requestAnimationFrame(e),this.paint()};this._raf=requestAnimationFrame(e)}paint(){if(this.removed)return;let e=this.cam.video;!e||this.cam.state==="closed"||(this.route==="woven-sbs"?this._paintWoven():this._paintFlat(e))}_paintFlat(e){if(!Rr(this.canvas))return;let t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2)return;let r=this.canvas.getContext("2d"),s=this.route==="flat-left"?t/2:t,o=$(s,i,this.canvas.width/this.canvas.height,0,0);r.save(),this.mirror&&(r.translate(this.canvas.width,0),r.scale(-1,1)),r.drawImage(e,o.sx,o.sy,o.sw,o.sh,0,0,this.canvas.width,this.canvas.height),r.restore()}_paintWoven(){let e=this.cam.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.buffer)return;let r=t/2,s=this.aspect,{w:o,h:a}=_e(r,i,s),l=this.buffer;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a),this.autoConverge&&this._sample(e);let c=this.conv.step(r),p=l.getContext("2d");if(this.mirror)for(let f of ie(t,i)){let h=f.src==="L"?0:1,d=$(r,i,s,c,h),m=f.dx===0?0:o;p.save(),p.translate(m+o,0),p.scale(-1,1),p.drawImage(e,f.sx+d.sx,d.sy,d.sw,d.sh,0,0,o,a),p.restore()}else for(let f of[0,1]){let h=$(r,i,s,c,f);p.drawImage(e,f*r+h.sx,h.sy,h.sw,h.sh,f*o,0,o,a)}}_sample(e){let t=performance.now();if(t-this._autoAt<Mr)return;this._autoAt=t,this._scratch=this._scratch||document.createElement("canvas");let i=sn(e,this._scratch),r=i?this._focus.measure(i.img,i.w,i.h,t):null,s=this._track.push(r?r.d/i.scale:null);this.conv.measuredPx=s,this.disparityPx=s}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,this._unregister(),this.cam._views?.delete(this))}};var an=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],ln=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Dr=[1,0],Ht=10;function cn(n){let e=(16*n+128)*n+64;if(n>=2){let t=Math.floor(n/7)+2;e-=(25*t-10)*t-55,n>=7&&(e-=36)}return e}var on=(n,e)=>Math.floor(cn(n)/8)-an[e][n]*ln[e][n];function Vt(n,e){let t=0;for(let i=7;i>=0;i--)t=t<<1^(t>>>7)*285,t^=(e>>>i&1)*n;return t}function Lr(n){let e=new Array(n-1).fill(0);e.push(1);let t=1;for(let i=0;i<n;i++){for(let r=0;r<e.length;r++)e[r]=Vt(e[r],t),r+1<e.length&&(e[r]^=e[r+1]);t=Vt(t,2)}return e}function Or(n,e){let t=e.map(()=>0);for(let i of n){let r=i^t.shift();t.push(0),e.forEach((s,o)=>t[o]^=Vt(s,r))}return t}function $t(n,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(n))],r=1;for(;r<=Ht&&!(4+(r<=9?8:16)+i.length*8<=on(r,t)*8);r++);if(r>Ht)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${Ht} code`);let s=[],o=(g,w)=>{for(let _=w-1;_>=0;_--)s.push(g>>>_&1)};o(4,4),o(i.length,r<=9?8:16);for(let g of i)o(g,8);let a=on(r,t)*8;o(0,Math.min(4,a-s.length)),o(0,(8-s.length%8)%8);for(let g=236;s.length<a;g^=253)o(g,8);let l=[];for(let g=0;g<s.length;g+=8)l.push(s.slice(g,g+8).reduce((w,_)=>w<<1|_,0));let c=ln[t][r],p=an[t][r],f=Math.floor(cn(r)/8),h=c-f%c,d=Math.floor(f/c),m=Lr(p),u=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-p+(g<h?0:1));w+=_.length;let S=Or(_,m);g<h&&_.push(0),u.push(_.concat(S))}let v=[];for(let g=0;g<u[0].length;g++)for(let w=0;w<u.length;w++)(g!==d-p||w>=h)&&v.push(u[w][g]);let y=r*4+17,x=Array.from({length:y},()=>new Array(y).fill(!1)),M=Array.from({length:y},()=>new Array(y).fill(!1)),b=(g,w,_)=>{x[w][g]=_,M[w][g]=!0};for(let g=0;g<y;g++)b(6,g,g%2===0),b(g,6,g%2===0);let A=(g,w)=>{for(let _=-4;_<=4;_++)for(let S=-4;S<=4;S++){let D=Math.max(Math.abs(S),Math.abs(_)),T=g+S,j=w+_;T>=0&&T<y&&j>=0&&j<y&&b(T,j,D!==2&&D!==4)}};A(3,3),A(y-4,3),A(3,y-4);let E=[];if(r>1){let g=Math.floor(r/7)+2,w=Math.ceil((r*4+4)/(g*2-2))*2;E.push(6);for(let _=y-7;E.length<g;_-=w)E.splice(1,0,_)}for(let g=0;g<E.length;g++)for(let w=0;w<E.length;w++)if(!(g===0&&w===0||g===0&&w===E.length-1||g===E.length-1&&w===0))for(let _=-2;_<=2;_++)for(let S=-2;S<=2;S++)b(E[g]+S,E[w]+_,Math.max(Math.abs(S),Math.abs(_))!==1);let O=g=>{let w=Dr[t]<<3|g,_=w;for(let T=0;T<10;T++)_=_<<1^(_>>>9)*1335;let S=(w<<10|_)^21522,D=T=>(S>>>T&1)!==0;for(let T=0;T<=5;T++)b(8,T,D(T));b(8,7,D(6)),b(8,8,D(7)),b(7,8,D(8));for(let T=9;T<15;T++)b(14-T,8,D(T));for(let T=0;T<8;T++)b(y-1-T,8,D(T));for(let T=8;T<15;T++)b(8,y-15+T,D(T));b(8,y-8,!0)};if(O(0),r>=7){let g=r;for(let _=0;_<12;_++)g=g<<1^(g>>>11)*7973;let w=r<<12|g;for(let _=0;_<18;_++){let S=(w>>>_&1)!==0,D=y-11+_%3,T=Math.floor(_/3);b(D,T,S),b(T,D,S)}}let R=0;for(let g=y-1;g>=1;g-=2){g===6&&(g=5);for(let w=0;w<y;w++)for(let _=0;_<2;_++){let S=g-_,T=(g+1&2)===0?y-1-w:w;!M[T][S]&&R<v.length*8&&(x[T][S]=(v[R>>>3]>>>7-(R&7)&1)!==0,R++)}}let P=g=>{for(let w=0;w<y;w++)for(let _=0;_<y;_++){if(M[w][_])continue;let S;switch(g){case 0:S=(_+w)%2===0;break;case 1:S=w%2===0;break;case 2:S=_%3===0;break;case 3:S=(_+w)%3===0;break;case 4:S=(Math.floor(_/3)+Math.floor(w/2))%2===0;break;case 5:S=_*w%2+_*w%3===0;break;case 6:S=(_*w%2+_*w%3)%2===0;break;default:S=((_+w)%2+_*w%3)%2===0}S&&(x[w][_]=!x[w][_])}},L=Number.isInteger(e.mask)?e.mask:-1;if(L<0){let g=1/0;for(let w=0;w<8;w++){P(w),O(w);let _=Ar(x,y);_<g&&(g=_,L=w),P(w)}}return P(L),O(L),{version:r,size:y,mask:L,modules:x}}function Ar(n,e){let t=0,i=[];for(let o=0;o<e;o++)i.push(n[o]);for(let o=0;o<e;o++)i.push(n.map(a=>a[o]));for(let o of i){let a=1;for(let c=1;c<=e;c++)c<e&&o[c]===o[c-1]?a++:(a>=5&&(t+=a-2),a=1);let l=o.map(c=>c?"1":"0").join("");for(let c of["10111010000","00001011101"])for(let p=l.indexOf(c);p>=0;p=l.indexOf(c,p+1))t+=40}let r=0;for(let o=0;o<e;o++)for(let a=0;a<e;a++)if(n[o][a]&&r++,a<e-1&&o<e-1){let l=n[o][a];l===n[o][a+1]&&l===n[o+1][a]&&l===n[o+1][a+1]&&(t+=3)}let s=e*e;return t+=Math.floor(Math.abs(r*20-s*10)/s)*10,t}function dn(n,e,{px:t=4,dark:i="#000",light:r="#fff",ecl:s="M"}={}){let o=$t(e,{ecl:s}),a=o.size+8;n.width=n.height=a*t;let l=n.getContext("2d");l.fillStyle=r,l.fillRect(0,0,a*t,a*t),l.fillStyle=i;for(let c=0;c<o.size;c++)for(let p=0;p<o.size;p++)o.modules[c][p]&&l.fillRect((p+4)*t,(c+4)*t,t,t);return o}function le(n,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=n,t}async function Bt(n){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(String(n)));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}var Ut="wss://dxr-signal.displayxr.workers.dev";function ce(n=Ut,e={}){if(!n||typeof n!="string")throw le("no-signaling-url","dxrSignaling(url): url must be a ws:// or wss:// string (omit it for the hosted DisplayXR server)");let t=n.replace(/\/+$/,""),i=e.WebSocket||globalThis.WebSocket,r=e.pingMs||2e4;return{name:"dxr",url:t,async join(s,o){let a=await Bt(s),l=`${t}/v1/connect?k=${a}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,c=null,p=!1,f=0,h=null,d=new Set,m=[],u=M=>new Promise((b,A)=>{let E=!1,O=!1,R=new i(l);c=R;let P=L=>{if(!E){E=!0;try{R.close()}catch{}A(L)}};R.onopen=()=>{R.send(JSON.stringify({t:"join",v:1,room:s,id:o.id,max:o.maxPeers}))},R.onmessage=L=>{let g;try{g=JSON.parse(typeof L.data=="string"?L.data:String(L.data))}catch{return}switch(g.t){case"welcome":{f=0;let w=Array.isArray(g.peers)?g.peers.filter(S=>typeof S=="string"):[];clearInterval(h),h=setInterval(()=>v({t:"ping"}),r);let _=m;m=[];for(let S of _)v(S);if(M){let S=new Set(w);for(let D of d)S.has(D)||o.onPeerLeft?.(D);d=S,o.onReconnect?.(w)}else d=new Set(w);E=!0,O=!0,b({id:g.id,peers:w,iceServers:Array.isArray(g.iceServers)?g.iceServers:void 0,max:g.max});break}case"full":p=!0,P(le("room-full",`this call is full (${g.max} participants)`));break;case"error":!E&&["bad-room","bad-id","bad-version"].includes(g.code)?(p=!0,P(le(g.code,g.message||g.code))):!E&&g.code==="id-taken"&&P(le("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof g.id=="string"&&!d.has(g.id)&&(d.add(g.id),o.onPeerJoined?.(g.id));break;case"peer-left":typeof g.id=="string"&&(d.delete(g.id),o.onPeerLeft?.(g.id));break;case"signal":typeof g.from=="string"&&o.onSignal?.(g.from,g.data);break}},R.onerror=()=>P(le("signaling-unreachable",`cannot reach ${t}`)),R.onclose=()=>{clearInterval(h),P(le("signaling-closed","signalling closed before joining")),O&&!p&&c===R&&y()}}),v=M=>{c&&c.readyState===1?c.send(JSON.stringify(M)):p||m.push(M)},y=()=>{o.onDisconnect?.();let M=()=>{p||u(!0).catch(b=>{if(p||b&&b.code==="room-full"){o.onDisconnect?.(b);return}setTimeout(M,H(f++,{baseMs:500,maxMs:15e3}))})};setTimeout(M,H(f++,{baseMs:300,maxMs:15e3}))};return{...await u(!1),send:(M,b)=>v({t:"signal",to:M,data:b}),leave:()=>{if(!p){p=!0,clearInterval(h);try{c&&c.readyState===1&&c.send(JSON.stringify({t:"leave"})),c&&c.close(1e3,"leave")}catch{}}}}}}}var qt=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),fn=n=>typeof n=="string"&&qt[n.toLowerCase()]||n,un=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),Ee=Object.freeze({lobbyStartTitle:"Start a 3D call",lobbyJoinTitle:"Join the 3D call",lobbyFullTitle:"This call is full",lobbyLeftTitle:"You left the call",lobbyFullText:"It already has {maxPeers} participants.",lobbyText:"Check your framing below. Camera: {camera} \u2014 {kind}.",cameraDefault:"default",kindBusy:"busy (joining audio-only)",kindNone:"none (joining audio-only)",kindSbs:"sending 3D (side-by-side, {width}\xD7{height})",kindMono:"sending 2D ({width}\xD7{height})",liftOff:"Mono cameras: 2D (2D\u21923D is off).",liftChecking:"Mono cameras: checking 2D\u21923D\u2026",liftMissing:"Mono cameras: 2D\u21923D unavailable in this build.",liftNoProvider:"Mono cameras: 2D (no 2D\u21923D provider here).",liftNative:"Mono cameras: 2D\u21923D (native{provider}).",liftWeb:"Mono cameras: 2D\u21923D (in this page, WebGPU).",liftProven:"Mono cameras: 2D\u21923D.",liftUnproven:"Mono cameras: 2D\u21923D (confirmed on the first mono participant).",start:"Start 3D call",join:"Join call",rejoin:"Rejoin",retryCamera:"Retry camera",cameraSelect:"Camera",joining:"Joining\u2026",waitingTitle:"Waiting for others",waitingText:"Share this link (or scan the code). Anyone who opens it joins \u2014 keep it private.",inviteTitle:"Invite",inviteText:"Anyone with this link can join.",inviteLink:"Invite link",copyLink:"Copy link",copied:"Copied",pressCopy:"Press Ctrl/Cmd+C",qrLabel:"QR code of the invite link",banner2D:"You are seeing this call in 2D.",bannerLink:"View in 3D with DisplayXR Browser",mute:"Mute microphone",unmute:"Unmute microphone",cameraOn:"Turn camera on",cameraOff:"Turn camera off",cameraRetry:"No camera \u2014 click to retry",cameraBusyRetry:"{cameraBusy} \u2014 click to retry",depth:"Depth",invite:"Invite",leave:"Leave call",connecting:"Connecting\u2026",reconnecting:"Reconnecting\u2026",leftCall:"Left the call",cameraOffPlate:"Camera off",noCamera:"No camera",unreachable:"Can't reach this participant \u2014 the network needs a relay (TURN)",cameraBusy:"Camera busy \u2014 in use by another app (e.g. eye tracking)",you:"You",badge3D:"3D",badge2D3D:"2D\u21923D",badge2D:"2D",badgePending:"\u2026"});function mn(n){let e={...Ee,...n&&typeof n=="object"?n:{}};return(t,i)=>{let r=typeof e[t]=="string"?e[t]:Ee[t]||t;if(i)for(let[s,o]of Object.entries(i))r=r.split(`{${s}}`).join(String(o));return r}}var hn="dxr-call-style",Fr=`
6
+ .dxr-call-host{--dxr-accent:#4da3ff;--dxr-ink:#fff;--dxr-shell:rgba(16,17,22,.92);--dxr-danger:#ff5a5f;--dxr-radius:12px;
7
+ --dxr-font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
8
+ display:flex;flex-direction:column;gap:12px;color:var(--dxr-ink);
9
+ font:14px/1.4 var(--dxr-font);}
10
+ .dxr-call-host *{box-sizing:border-box;}
11
+ .dxr-call-hidden{display:none !important;}
12
+ .dxr-call-banner{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:9px 14px;border-radius:var(--dxr-radius);
13
+ background:var(--dxr-shell);border:1px solid rgba(255,255,255,.12);font-size:13px;}
14
+ .dxr-call-banner a{color:var(--dxr-accent);font-weight:600;}
15
+ /* \u2500\u2500 grid: bare boxes, nothing that makes a render surface \u2500\u2500 */
16
+ .dxr-call-grid{display:grid;gap:10px;grid-template-columns:1fr;margin-inline:auto;width:100%;
17
+ /* Fit the tiles AND the footer (self view + bar) in one viewport: tiles are 16:9 per eye, so
18
+ the grid's width is capped by the height left after --dxr-call-reserve (the footer). */
19
+ --dxr-call-h:var(--dxr-call-fit,calc(100vh - var(--dxr-call-reserve,150px)));max-width:calc(var(--dxr-call-h)*16/9);}
20
+ .dxr-call-grid[data-n="2"]{max-width:calc(var(--dxr-call-h)*32/9);}
21
+ .dxr-call-grid[data-layout="speaker"]:not([data-n="1"]){max-width:calc(var(--dxr-call-h)*4/3);}
22
+ .dxr-call-grid[data-n="2"],.dxr-call-grid[data-n="3"]{grid-template-columns:1fr 1fr;}
23
+ .dxr-call-grid[data-layout="speaker"]{grid-template-columns:repeat(3,1fr);}
24
+ .dxr-call-grid[data-layout="speaker"] .dxr-call-tile--main{grid-column:1/-1;}
25
+ .dxr-call-grid[data-layout="speaker"][data-n="1"]{grid-template-columns:1fr;}
26
+ /* layout:'none' \u2014 the module creates the tiles but does not position them: the grid box steps
27
+ aside (display:contents) so each [data-dxr-peer] tile is laid out by the PAGE's own CSS on the
28
+ host. A tile is never moved; it is styled in place (woven-canvas rule 2). */
29
+ .dxr-call-grid[data-layout="none"]{display:contents;}
30
+ .dxr-call-tile{position:relative;min-width:0;}
31
+ .dxr-call-stage{position:relative;background:#000;}
32
+ .dxr-call-stage>canvas{display:block;width:100%;height:100%;}
33
+ /* a LIFTED tile: its <video> is mounted in the stage for lift() (which floats its canvas over the
34
+ element's rect, z-index 1); the flat canvas sits above it until lift is live, then hides. */
35
+ .dxr-call-stage>video.dxr-call-liftsrc{position:absolute;left:0;top:0;width:100%;height:100%;object-fit:cover;}
36
+ .dxr-call-stage>canvas.dxr-call-liftflat{position:relative;z-index:1;}
37
+ .dxr-call-talk{height:3px;margin-top:4px;background:transparent;}
38
+ .dxr-call-tile--speaking .dxr-call-talk{background:var(--dxr-accent);}
39
+ /* \u2500\u2500 partial overlays on a tile \u2500\u2500 */
40
+ .dxr-call-badge{position:absolute;left:8px;top:8px;z-index:2;display:flex;align-items:center;gap:6px;
41
+ padding:3px 8px;border-radius:99px;background:var(--dxr-shell);font-size:11px;font-weight:600;
42
+ letter-spacing:.4px;will-change:transform;pointer-events:none;}
43
+ .dxr-call-badge b{font-weight:800;color:var(--dxr-accent);}
44
+ .dxr-call-badge svg{width:13px;height:13px;fill:var(--dxr-danger);}
45
+ .dxr-call-state{position:absolute;left:50%;top:50%;z-index:2;transform:translate(-50%,-50%);max-width:70%;
46
+ padding:8px 14px;border-radius:99px;background:var(--dxr-shell);font-size:13px;text-align:center;
47
+ will-change:transform;pointer-events:none;}
48
+ .dxr-call-cover{position:absolute;inset:0;z-index:1;background:#000;}
49
+ /* \u2500\u2500 empty room / lobby \u2500\u2500 */
50
+ .dxr-call-panel{padding:18px;border-radius:var(--dxr-radius);background:var(--dxr-shell);border:1px solid rgba(255,255,255,.1);}
51
+ .dxr-call-panel h3{margin:0 0 6px;font-size:17px;}
52
+ .dxr-call-panel p{margin:0 0 12px;opacity:.75;}
53
+ .dxr-call-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;}
54
+ .dxr-call-btn{appearance:none;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:inherit;
55
+ font:600 13px/1 var(--dxr-font);padding:9px 14px;border-radius:calc(var(--dxr-radius) * .75);cursor:pointer;}
56
+ .dxr-call-btn:hover{background:rgba(255,255,255,.16);}
57
+ .dxr-call-btn:focus-visible{outline:2px solid var(--dxr-accent);outline-offset:2px;}
58
+ .dxr-call-btn--primary{background:var(--dxr-accent);border-color:var(--dxr-accent);color:#07111d;}
59
+ .dxr-call-btn--primary:hover{background:var(--dxr-accent);}
60
+ .dxr-call-btn--danger{background:var(--dxr-danger);border-color:var(--dxr-danger);color:#fff;}
61
+ .dxr-call-select{font:inherit;color:inherit;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.18);
62
+ border-radius:calc(var(--dxr-radius) * .66);padding:7px 9px;max-width:260px;}
63
+ .dxr-call-invite{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap;}
64
+ .dxr-call-invite input{flex:1 1 240px;min-width:0;font:12px ui-monospace,Menlo,monospace;color:inherit;
65
+ background:rgba(0,0,0,.35);border:1px solid rgba(255,255,255,.14);border-radius:calc(var(--dxr-radius) * .66);padding:8px;}
66
+ .dxr-call-invite canvas{width:132px;height:132px;image-rendering:pixelated;background:#fff;}
67
+ /* \u2500\u2500 footer: self view + bar, BELOW the grid (over no tile) \u2500\u2500 */
68
+ .dxr-call-foot{display:flex;align-items:flex-end;gap:12px;flex-wrap:wrap;}
69
+ .dxr-call-self{width:200px;flex:none;}
70
+ .dxr-call-host--lobby .dxr-call-self{width:min(560px,100%);}
71
+ .dxr-call-self .dxr-call-badge b{color:var(--dxr-ink);}
72
+ .dxr-call-bar{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:8px 10px;border-radius:calc(var(--dxr-radius) + 2px);
73
+ background:var(--dxr-shell);border:1px solid rgba(255,255,255,.1);will-change:transform;}
74
+ .dxr-call-host--lobby .dxr-call-bar{display:none;}
75
+ .dxr-call-ib{appearance:none;border:0;width:40px;height:40px;border-radius:50%;padding:9px;cursor:pointer;
76
+ background:rgba(255,255,255,.1);color:var(--dxr-ink);}
77
+ .dxr-call-ib:hover{background:rgba(255,255,255,.2);}
78
+ .dxr-call-ib:focus-visible{outline:2px solid var(--dxr-accent);outline-offset:2px;}
79
+ .dxr-call-ib svg{width:100%;height:100%;fill:currentColor;display:block;}
80
+ .dxr-call-ib[aria-pressed="true"]{background:var(--dxr-ink);color:#111;}
81
+ .dxr-call-ib--leave{background:var(--dxr-danger);width:52px;border-radius:20px;}
82
+ .dxr-call-ib--leave:hover{background:var(--dxr-danger);}
83
+ .dxr-call-depth{display:flex;align-items:center;gap:6px;padding:0 8px;font-size:12px;opacity:.9;}
84
+ .dxr-call-depth input{width:110px;accent-color:var(--dxr-accent);}
85
+ .dxr-call-note{font-size:12px;opacity:.65;}
86
+ `;function pn(n=document){if(n.getElementById(hn))return;let e=n.createElement("style");e.id=hn,e.textContent=Fr,(n.head||n.documentElement).appendChild(e)}var K=n=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${n}"/></svg>`,V={mic:K("M12 14a3 3 0 0 0 3-3V5a3 3 0 0 0-6 0v6a3 3 0 0 0 3 3zm5-3a5 5 0 0 1-10 0H5a7 7 0 0 0 6 6.92V21h2v-3.08A7 7 0 0 0 19 11z"),micOff:K("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z"),cam:K("M17 10.5V7a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-3.5l4 4v-11z"),camOff:K("M21 6.5l-4 4V7a1 1 0 0 0-1-1H9.82L21 17.18zM3.27 2 2 3.27 4.73 6H4a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12c.21 0 .39-.08.54-.18L19.73 21 21 19.73z"),link:K("M3.9 12a3.1 3.1 0 0 1 3.1-3.1h4V7H7a5 5 0 0 0 0 10h4v-1.9H7A3.1 3.1 0 0 1 3.9 12zM8 13h8v-2H8zm9-6h-4v1.9h4a3.1 3.1 0 0 1 0 6.2h-4V17h4a5 5 0 0 0 0-10z"),leave:K("M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85a1 1 0 0 1-1.41-.02L.29 13.08a1 1 0 0 1 0-1.41C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67a1 1 0 0 1 0 1.41l-2.48 2.48a1 1 0 0 1-1.41.02 11.3 11.3 0 0 0-2.66-1.85 1 1 0 0 1-.56-.9v-3.1A15.3 15.3 0 0 0 12 9z"),mutedSmall:K("M19 11h-2a5 5 0 0 1-.4 1.97l1.47 1.47A6.96 6.96 0 0 0 19 11zM15 11V5a3 3 0 0 0-5.94-.6L15 10.34zM4.27 3 3 4.27l6 6V11a3 3 0 0 0 4.52 2.59l1.46 1.46A5 5 0 0 1 7 11H5a7 7 0 0 0 6 6.92V21h2v-3.08a6.9 6.9 0 0 0 3.02-1.14L19.73 21 21 19.73z")};function k(n,e={},t=[]){let i=document.createElement(n);for(let[r,s]of Object.entries(e))s!=null&&(r==="class"?i.className=s:r==="html"?i.innerHTML=s:r==="text"?i.textContent=s:r.startsWith("on")&&typeof s=="function"?i.addEventListener(r.slice(2),s):r in i&&typeof s!="string"?i[r]=s:i.setAttribute(r,s));for(let r of[].concat(t))r&&i.appendChild(typeof r=="string"?document.createTextNode(r):r);return i}var I=(n,e)=>n&&n.classList.toggle("dxr-call-hidden",!e);var _n="[inline3d/call]",jr="https://github.com/DisplayXR/displayxr-browser",vn=Object.freeze({accent:"theme.accent",tileAspect:"theme.tileAspect",inviteBase:"invite.base",updateUrl:"invite.updateUrl",browserUrl:"landing.browserUrl",maxLifted:"liftOptions.max",calibration:"openCamera({ calibration }) of '@displayxr/inline3d/camera' (pass the camera as `camera`)",rectify:"openCamera({ rectify }) of '@displayxr/inline3d/camera'",log:"debug: true (and diagnostics())",recoverSession:"nothing \u2014 a call always recovers the document's session (sharedInline3D())",wallOptions:"sharedInline3D(opts) \u2014 the document's wall is configured by the page",scrollIntoView:"nothing \u2014 always on with ui: true"}),gn=new Set;function Wr(n){gn.has(n)||(gn.add(n),console.warn(`${_n} option \`${n}\` is deprecated (removed in 1.31) \u2014 use ${vn[n]}`))}function Xt(n={}){for(let v of Object.keys(vn))n[v]!==void 0&&Wr(v);let e=n.theme&&typeof n.theme=="object"?n.theme:{},t=n.invite&&typeof n.invite=="object"?n.invite:{},i=n.landing&&typeof n.landing=="object"?n.landing:{},r=n.ui===void 0?!0:n.ui==="tiles"?"tiles":!!n.ui,s=r===!0,o=e.tileAspect!==void 0?e.tileAspect:n.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=n.room===void 0||n.room===null?"auto":n.room;if(l!=="auto"&&!re(l)){let v=ye(l);if(!v)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=v}let c=n.liftOptions&&typeof n.liftOptions=="object"?{...n.liftOptions}:null,p=c&&c.max!==void 0?c.max:n.maxLifted;c&&delete c.max;let f=e.accent!==void 0?e.accent:n.accent,h={};for(let[v,y]of Object.entries(un)){let x=v==="accent"?f:e[v];typeof x=="string"&&x?h[y]=v==="accent"?fn(x):x:typeof x=="number"&&v==="radius"&&(h[y]=`${x}px`)}let d=t.base!==void 0?t.base:n.inviteBase,m=t.updateUrl!==void 0?t.updateUrl:n.updateUrl,u=i.browserUrl!==void 0?i.browserUrl:n.browserUrl;return{room:l,signaling:n.signaling||ce(void 0,typeof n.key=="string"&&n.key?{key:n.key}:{}),iceServers:Array.isArray(n.iceServers)?n.iceServers:void 0,camera:n.camera===void 0?"auto":n.camera,format:n.format==="sbs"?"sbs":n.format==="mono"?"mono":void 0,calibration:n.calibration&&typeof n.calibration=="object"?{...n.calibration}:{},rectify:typeof n.rectify=="function"?n.rectify:null,audio:n.audio===void 0?!0:!!n.audio,autoConverge:n.autoConverge===void 0?!0:!!n.autoConverge,mono3D:pe(n.mono3D),maxPeers:Se(n.maxPeers===void 0?ne:n.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+p)&&p!==null&&p!==void 0?Math.max(0,Math.min(ne,Math.floor(+p))):ne,layout:n.layout==="speaker"?"speaker":n.layout==="none"?"none":"grid",ui:r,chrome:s,autoJoin:n.autoJoin===void 0?!s:!!n.autoJoin,selfView:n.selfView===void 0?!0:!!n.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:m===void 0?s:!!m},landing:{browserUrl:typeof u=="string"?u:jr,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!n.debug,log:typeof n.log=="function"?n.log:n.debug?(v,y)=>console.log(`${_n} ${v} ${JSON.stringify(y)}`):null,_liftImporter:typeof n._liftImporter=="function"?n._liftImporter:void 0}}var Os=Object.freeze(["normalizeCallOptions","newRoomId","isValidRoomId","buildInviteLink","normalizeHello","makeHello","routeFor","badgeFor","createLiveGate","convergenceShiftPx","lowPass","clampShift","eyeCropRect","mirrorSwapOps","mirrorSwapPixels","maxBitrateKbps","measureFocusDisparity","preferVideoCodecs","sortCodecCapabilities","VIDEO_CODEC_ORDER","MeshTransport","clampMaxPeers","qrEncode","roomKey","SIGNAL_PROTOCOL","WIRE_VERSION","CALL_SDK","PLATE_TEXT","CALL_ACCENTS","normalizeMono3D","resolveLift","createLiftPool","createFrameWatch","liftConvergenceFor","liftPriorityFor","setLiftPriority","defaultLiftSpecifier","LIFT_PRIORITY"]);var Jt="dxr-call:",Nr=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],Gt="[inline3d/call] <dxr-call>",de=n=>n!=null&&!/^(false|0|off|no)$/i.test(String(n).trim()),yn=n=>{if(n==null||String(n).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(n)),t=e?+e[1]/+e[2]:+n;return Number.isFinite(t)?t:void 0},F=n=>n==null||String(n).trim()===""?void 0:String(n).trim();function Kt(n){let e=typeof n=="function"?n:l=>n&&typeof n.getAttribute=="function"?n.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",F(e("room")));let r=F(e("signaling"));r&&(t.signaling=ce(r,F(e("key"))?{key:F(e("key"))}:{})),i("key",F(e("key"))),i("camera",F(e("camera"))),i("layout",F(e("layout"))),i("maxPeers",yn(e("max-peers")));let s=F(e("ui"));de(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),de(e("auto-join"))&&(t.autoJoin=!0);let o=F(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),de(e("no-audio"))&&(t.audio=!1),de(e("no-self-view"))&&(t.selfView=!1),de(e("no-auto-converge"))&&(t.autoConverge=!1);let a={accent:F(e("accent")),tileAspect:yn(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),F(e("invite-base"))&&(t.invite={base:F(e("invite-base"))}),F(e("browser-url"))&&(t.landing={browserUrl:F(e("browser-url"))}),de(e("debug"))&&(t.debug=!0),t}var zr=typeof HTMLElement=="function"?HTMLElement:class{},he=class n extends zr{static mount=null;constructor(){super(),this.options=null,this.call=null,this.ready=null,this._gen=0,this._off=[],this._pending=null}connectedCallback(){if(this.call||this._pending)return;let e=++this._gen,t={...Kt(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||n.mount||Yt;this._pending=new Promise(r=>r(i(this,t))).then(r=>{if(this._pending=null,e!==this._gen)return r.leave(),null;if(this.call=r,this._off=Nr.map(s=>r.on(s,o=>this._dispatch(s,o))),this._off.push(r.on("error",s=>console.warn(`${Gt} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:r}),r.state==="in-call"){this._dispatch("joined",{room:r.room,id:r.id});for(let s of r.peers)this._dispatch("peer",{id:s.id})}return r},r=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(r&&r.message||r),error:r||null}),console.warn(`${Gt} mount failed: ${String(r&&r.message||r)}`),r}),this.ready=this._pending,this.ready.catch(()=>{})}disconnectedCallback(){this._gen++;let e=this.call;this.call=null,e&&e.leave();for(let t of this._off)try{t()}catch{}this._off=[]}_dispatch(e,t){typeof CustomEvent!="function"||typeof this.dispatchEvent!="function"||this.dispatchEvent(new CustomEvent(Jt+e,{detail:t,bubbles:!0,composed:!0}))}};function Ke(n="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(n);return t?(t!==he&&console.warn(`${Gt} <${n}> is already defined by another class; leaving it`),!1):(e.define(n,he),!0)}var B="[inline3d/call]",Hr=2e3,Vr=2500,$r=500,Zt=.02,Br=4,Ur=2,qr=200,wn=240,Xr=new Set(["I420","I420A","I422","I444","NV12"]);async function Sn(n,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=Xt(t);if(!i.signaling||typeof i.signaling.join!="function")throw new TypeError("@displayxr/inline3d/call: opts.signaling must be a SignalingAdapter \u2014 dxrSignaling([url]) or your own");let r=new Qt(n,e,i);return await r._init(),r.handle}async function Yt(n,e={}){if(!n||typeof n.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,r=t||await Ae(i.wallOptions);return Sn(r,n,i)}var Qt=class{constructor(e,t,i){this.o=i,this.t=mn(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=Di(),this.room=i.room==="auto"?ye(globalThis.location):i.room,this.state="idle",this.tiles=new Map,this.listeners=new Map,this.local=null,this.muted=!1,this.camOff=!1,this.depth=0,this.speakerId=null,this.transport=null,this._raf=0,this._statsTimer=0,this._hintGate=kt(wt),this.mono3D=i.mono3D,this.mono3DOn=i.mono3D!=="off",this.liftApi=null,this.liftPool=null,this._liftP=null,this.liftProven=!1,this.liftMissing=!1,this._liftWarned=!1,this._frameWatch=rt(),this.handle=this._makeHandle(),this.wallLive&&this._hookWall(this.wall)}get woven(){return!!(this.wall&&this.wall.supported&&this.wallLive)}log(e,t={}){this.o.log&&this.o.log(e,t)}emit(e,t){let i=this.listeners.get(e);if(i)for(let r of[...i])try{r(t)}catch(s){console.error(`${B} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${B} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${B} ${e}: ${t}`),this.emit("warning",{code:e,message:t})}async _init(){this._buildDom(),this.wallLive&&this._ensureLift(),await this._openMedia(this.o.camera),this._startLoop(),this.o.autoJoin?await this.join():this._setState("lobby")}async _openMedia(e,t,{keepOnFail:i=!1}={}){let r=(h,d)=>this.log(h,d),s=null,o=null,a=Je(e)?e:null;try{if(s=a||await Nt({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:r}),a&&a.state!=="live")throw Object.assign(new Error("the camera given is not live"),{code:"no-camera",skipped:[]})}catch(h){o=h;let d=h.code==="camera-busy";if(this.error(d?"camera-busy":h.code||"no-camera",d?`${this.t("cameraBusy")}. Joining audio-only.`:`no camera: ${h.message}. Joining audio-only.`,h),i&&this.local&&this.local.videoTrack)return this.local;this.camStatus=d?"busy":"none"}s&&(this.camStatus="ok"),s&&s.rectifyError&&this.error("rectify-failed",`rectify() threw \u2014 sending the raw pair: ${s.rectifyError.message}`,s.rectifyError);let l=this.local?this.local.audioTrack:null;this.o.audio&&!l&&(l=await Wi({log:r})),l&&(l.enabled=!this.muted);let c=s&&s.stream.getVideoTracks()[0]||null;if(c){try{c.contentHint="detail"}catch{}c.enabled=!this.camOff}let p=new MediaStream([c,l].filter(Boolean)),f=this.local;return this.local={stream:p,cam:s,camStream:s?s.stream:null,video:s?s.video:null,videoTrack:c,audioTrack:l,format:s?s.format:"mono",width:s?s.width:0,height:s?s.height:0,calibration:s?s.calibration:{},owned:s?s.owned&&s!==a:!1,label:s?s.label:"",skipped:s?s.skipped:o?.skipped||[]},s&&s!==f?.cam&&(this._camEndedOff?.(),this._camEndedOff=s.on("ended",()=>{this.local?.cam===s&&(this.local.videoTrack=null,this.camStatus="none",this.error("no-camera",'the camera ended (revoked, unplugged, or taken by another app). Audio-only until "Retry camera".'),this.transport?.broadcast(this.stateMsg()),this._refreshSelf(),this._refreshBar())})),this.log("camera",{format:this.local.format,width:this.local.width,height:this.local.height,label:this.local.label,skipped:this.local.skipped.length}),f&&f.owned&&f.cam&&f.cam!==s&&f.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return St({format:e.format,width:e.width,height:e.height,baselineMm:e.calibration?.baselineMm,hfovDeg:e.calibration?.hfovDeg,rectified:!!e.calibration?.rectified})}stateMsg(){return{type:"state",muted:this.muted,cameraOff:this.camOff||!this.local?.videoTrack,speaking:!!this._selfSpeaking}}async join(){if(this.state==="joining"||this.state==="in-call")return this.handle;if(this.state==="left"&&!this.local?.videoTrack&&await this._openMedia(this.o.camera),this.room||(this.room=bt(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",We(location.href,this.room))}catch{}this._setState("joining");let e=new xe({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(t,i)=>this.log(t,i)});this.transport=e;try{await e.start({room:this.room,localStream:this.local.stream,sendFormat:this.local.format,onPeer:t=>this._onPeer(t),onPeerLeft:(t,i)=>this._onPeerLeft(t,i),onStream:(t,i)=>this.tiles.get(t)?.setStream(i),onMessage:(t,i)=>this._onMessage(t,i),onPeerState:(t,i)=>{this.tiles.get(t)?.setConn(i),this.emit("state",{id:t,state:i})},onRefused:t=>this.log("refused-peer",{id:t}),onGhost:(t,i)=>this._onGhost(t,i),onSignalingState:(t,i)=>{this.log("signaling",{state:t}),t==="closed"&&i&&this.error(i.code||"signaling-closed",i.message,i)}})}catch(t){throw this.transport=null,t&&t.code==="room-full"?(this._setState("full"),this.error("room-full",t.message,t)):(this._setState("lobby"),this.error(t.code||"join-failed",`could not join: ${t.message}`,t)),t}if(this._setState("in-call"),this.o.chrome)try{this.container.scrollIntoView?.({block:"start",behavior:"instant"}),this._fitGrid()}catch{}return this._startStats(),this._pagehide=()=>this.leave("pagehide"),globalThis.addEventListener?.("pagehide",this._pagehide),this.log("joined",{id:this.id,peers:this.tiles.size}),this.emit("joined",{room:this.room,id:this.id}),this.handle}_onPeer(e){if(this.tiles.has(e))return;let t=new Ye(this,e);this.tiles.set(e,t),this._layout(),this.emit("peer",{id:e})}_onGhost(e,t){let i=this.tiles.get(e);if(t&&!i){let r=new Ye(this,e);r.ghost=!0,this.tiles.set(e,r),r.setConn("unreachable"),this._layout()}else!t&&i&&i.ghost&&(i.destroy(),this.tiles.delete(e),this._layout())}_onPeerLeft(e,t){let i=this.tiles.get(e);i&&(i.setConn("left"),this.emit("peerleft",{id:e,reason:t}),i.leaveTimer=setTimeout(()=>{i.destroy(),this.tiles.get(e)===i&&this.tiles.delete(e),this.speakerId===e&&this._setSpeaker(null),this._layout()},Vr))}_onMessage(e,t){let i=this.tiles.get(e);if(!i||!t)return;if(t.type==="__open"){this.transport.send(e,this.hello()),this.transport.send(e,this.stateMsg()),i.onChannelOpen();return}let r=xt(t);if(r)return i.setHello(r);let s=Mt(t);if(s)return i.setHint(s);let o=Oi(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return We(e,this.room)}mute(e){return this.muted=e===void 0?!this.muted:!!e,this.local?.audioTrack&&(this.local.audioTrack.enabled=!this.muted),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this.log("mute",{muted:this.muted}),this.muted}setCameraOff(e){return this.camOff=e===void 0?!this.camOff:!!e,this.local?.videoTrack&&(this.local.videoTrack.enabled=!this.camOff),this.transport?.broadcast(this.stateMsg()),this._refreshBar(),this._refreshSelf(),this.camOff}setDepth(e){let t=e==null||!Number.isFinite(+e)?0:Math.max(-1,Math.min(1,+e));this.depth=t;for(let i of this.tiles.values())i.conv.depth=t;return this.liftPool?.setDepth(t),this.ui?.depth&&+this.ui.depth.value!==t&&(this.ui.depth.value=String(t)),t}async setCamera(e,{format:t}={}){let i=this.local?.format,r=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",r.videoTrack,r.stream),await this.transport.setSendFormat(r.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==r.format&&this.log("send-format",{format:r.format}),{format:r.format,width:r.width,height:r.height,label:r.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=Mt({type:"hint",subjectZmm:e});return t?(this.transport?.broadcast(t),!0):!1}leave(e="left"){if(this.state!=="left"){globalThis.removeEventListener?.("pagehide",this._pagehide),this.transport?.stop(),this.transport=null;for(let t of this.tiles.values())t.destroy();this.tiles.clear(),this.liftPool?.releaseAll(),clearInterval(this._statsTimer),this._setSpeaker(null),this.local&&(this._camEndedOff?.(),this._camEndedOff=null,this.local.stream.getTracks().forEach(t=>t.stop()),this.local.owned&&this.local.cam?this.local.cam.close():this.local.cam&&this.self?.detach(),this.local.videoTrack=null,this.local.audioTrack=null),this.self?.detach(),this._unhookWall(),this._setState("left"),this._layout(),this.emit("left",{room:this.room,reason:e})}}_hookWall(e){if(!e||!e.session||typeof e.session.addEventListener!="function")return;let t=e.close;this._wallHook={w:e,orig:t,pageClosed:!1};let i=this._wallHook;e.close=(...r)=>(i.pageClosed=!0,t.apply(e,r)),i.onEnd=()=>this._sessionEnded(i),e.session.addEventListener("end",i.onEnd),this._watchLive(e)}_watchLive(e){this.weaveLive=!1;let t=e.session;if(!t||typeof t.requestAnimationFrame!="function"){this.weaveLive=!0;return}let i=Ct(),r=performance.now(),s=(o,a)=>{if(e!==this.wall||!this.wallLive||this.state==="left")return;let l=null;if(e.refSpace)try{let c=a.getViewerPose(e.refSpace);l=c&&c.views?c.views.length:0}catch{l=0}if(!i.feed(l)){try{t.requestAnimationFrame(s)}catch{}return}this.weaveLive=!0,this.log("weave-live",{ms:Math.round(performance.now()-r)});for(let c of this.tiles.values())(c.route==="woven-sbs"||c.route==="lifted")&&c.reroute(!0);this.self&&this.self.route==="woven-sbs"&&this.self.reroute(!0),this._layout()};try{t.requestAnimationFrame(s)}catch{this.weaveLive=!0}}_unhookWall(){let e=this._wallHook;if(e){this._wallHook=null,e.w.close!==e.orig&&(e.w.close=e.orig);try{e.w.session.removeEventListener("end",e.onEnd)}catch{}}}_sessionEnded(e){if(this._wallHook===e){this.wallLive=!1,this.weaveLive=!1,this.log("session-ended",{byPage:e.pageClosed});for(let t of this.tiles.values())t.onWallLost();if(this.self?.onWallLost(),e.pageClosed||this.state==="left"){this._unhookWall();return}this.error("session-ended","the inline-3D session ended; tiles are flat while it is re-opened"),this._unhookWall(),this._recoverWall(0)}}_recoverWall(e){this.state==="left"||e>10||setTimeout(async()=>{if(this.state==="left")return;let t=null;try{t=await Ae()}catch{t=null}if(!t||!t.supported)return this._recoverWall(e+1);this.wall=t,this.wallLive=!0,this._hookWall(t),this.log("session-recovered",{attempt:e});for(let i of this.tiles.values())i.reroute(!0);this.self?.reroute(!0)},H(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let r of this.tiles.values())r.paint();e&&this.liftPool&&this.liftPool.anyWeb&&this._watchFrames(i-e),e=i};this._raf=requestAnimationFrame(t)}_watchFrames(e){let t=this._frameWatch.feed(e);if(!t)return;let i={degraded:t==="degraded",frameMs:Math.round(this._frameWatch.frameMs*10)/10,tiles:this.liftPool.size};this.log("lift-frame-time",i),t==="degraded"&&console.warn(`${B} lifted tiles are slowing the page (~${Math.round(1e3/i.frameMs)} fps with ${i.tiles} lifted) \u2014 setMono3D(false) shows mono peers flat`),this.emit("quality",{id:null,in:null,out:null,lift:i})}_ensureLift(){if(!this.mono3DOn)return Promise.resolve(null);if(!this._liftP){let e=(r,s)=>this.log(r,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=it(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(r=>(this.liftApi=r,r.lift?(this.liftPool=st({lift:r.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!r.caps&&r.capabilities&&Promise.resolve().then(()=>r.capabilities(i)).then(s=>{r.caps=s||null,this._refreshLobby()}).catch(()=>{})):r.reason==="import-failed"||r.reason==="no-lift-export"?this.liftMissing=!0:r.reason!=="off"&&console.info(`${B} mono\u21923D unavailable (${r.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),r))}return this._liftP}_warnLiftMissing(){this._liftWarned||!this.liftMissing||!this.mono3DOn||(this._liftWarned=!0,this.warning("lift-not-bundled","a 2D participant is on a 3D display but the 2D\u21923D module could not be imported from this build, so they stay flat. Import it explicitly \u2014 `import { lift } from '@displayxr/inline3d/lift'; mountCall(el, { mono3D: lift })` \u2014 or use `@displayxr/inline3d/call/full`, which bundles it."))}_rerouteMono(){for(let e of this.tiles.values())e.format&&e.format!=="sbs"&&e.reroute(!1)}setMono3D(e){let t=e===void 0?!this.mono3DOn:!!e;return t===this.mono3DOn||(this.mono3DOn=t,t&&this.mono3D==="off"&&(this.mono3D="auto"),this._frameWatch.reset(),this.log("mono3d",{on:t}),this._rerouteMono(),t&&this.wallLive&&this._ensureLift(),this._refreshLobby()),t}_liftHint(){if(!this.wallLive)return"";let e=this.t;if(!this.mono3DOn)return e("liftOff");let t=this.liftApi;if(!t)return e("liftChecking");if(!t.lift)return this.liftMissing?e("liftMissing"):e("liftNoProvider");let i=t.caps;return i&&i.native?e("liftNative",{provider:i.provider?`, ${i.provider}`:""}):i&&i.webFallback&&i.webFallback.webgpu?e("liftWeb"):this.liftProven?e("liftProven"):e("liftUnproven")}_mono3DInfo(){let e=this.liftApi,t=e&&e.caps;return Object.freeze({on:this.mono3DOn,state:this.mono3DOn?e?e.lift?"ready":"unavailable":this._liftP?"loading":"idle":"off",reason:e?e.reason:null,native:t?!!t.native:null,provider:t&&t.provider||null,lifted:this.liftPool?this.liftPool.size:0,max:this.o.maxLifted,proven:this.liftProven})}_startStats(){clearInterval(this._statsTimer);let e=0;this._statsTimer=setInterval(()=>this._stats(++e%4===0),$r)}async _stats(e){if(!this.transport)return;let t=null,i=0;for(let[o,a]of this.tiles){let l=this.transport.peerConnection(o);if(!l)continue;let c;try{c=await l.getStats()}catch{continue}let p={};c.forEach(d=>{d.type==="codec"&&(p[d.id]=d.mimeType)});let f={in:null,out:null};c.forEach(d=>{if(d.type==="inbound-rtp"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(a.level=Math.max(d.audioLevel,(a.level||0)*.6)),d.type==="media-source"&&d.kind==="audio"&&typeof d.audioLevel=="number"&&(i=Math.max(i,d.audioLevel)),!!e){if(d.type==="inbound-rtp"&&d.kind==="video"){let m=a._prevIn;f.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:m?Math.round((d.bytesReceived-m.bytes)*8/(d.timestamp-m.t)):null,dropped:d.framesDropped||0,decoder:d.decoderImplementation||null},a._prevIn={bytes:d.bytesReceived,t:d.timestamp}}else if(d.type==="outbound-rtp"&&d.kind==="video"){let m=a._prevOut;f.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:m?Math.round((d.bytesSent-m.bytes)*8/(d.timestamp-m.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(f.in||f.out)&&(a.quality=f,this.emit("quality",{id:o,...f}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>Zt||a.remote.speaking),h>Zt&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let r=t?t.id:null;r&&r!==this.speakerId?(this._challengeTicks=this._challenger===r?(this._challengeTicks||0)+1:1,this._challenger=r,this._challengeTicks>=2&&this._setSpeaker(r)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>Zt;s!==!!this._selfSpeaking&&(this._selfSpeaking=s,this.transport?.broadcast(this.stateMsg()),this.self?.setSpeaking(s))}_setSpeaker(e){e!==this.speakerId&&(this.speakerId=e,this._challengeTicks=0,this.liftPool?.setSpeaker(e),this.emit("speaker",{id:e}),this.o.layout==="speaker"&&this._layout())}_fitGrid(){let e=this.ui;if(!e||!this.o.chrome||typeof globalThis.innerHeight!="number")return;let t=this.container.getBoundingClientRect?.(),i=e.grid.getBoundingClientRect?.();if(!t||!i||!i.height)return;let r=Math.max(160,Math.floor(globalThis.innerHeight-Math.max(0,t.top)-(t.height-i.height)-8)),s=parseFloat(this.container.style.getPropertyValue("--dxr-call-fit"))||0;Math.abs(r-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${r}px`),this._fitHooked||(this._fitHooked=!0,globalThis.addEventListener?.("resize",()=>this._fitGrid()))}_setState(e){this.state=e,this.log("state",{state:e}),this._layout()}_buildDom(){let e=this.container,t=this.t;pn(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[r,s]of Object.entries(this.o.cssVars))e.style.setProperty(r,s);let i=this.ui={};i.banner=k("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[k("span",{text:t("banner2D")}),k("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=k("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=k("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=k("div",{class:"dxr-call-self",part:"self"}),i.bar=k("div",{class:"dxr-call-bar",part:"bar"}),i.foot=k("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=k("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||I(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new ei(this,i.selfSlot):I(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(r,s,o,a="")=>k("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":r,title:r,html:s,onclick:o});e.mic=i(t("mute"),V.mic,()=>this.mute()),e.cam=i(t("cameraOff"),V.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=k("input",{type:"range",min:"-1",max:"1",step:"0.05",value:"0","aria-label":t("depth")}),e.depth.addEventListener("input",()=>this.setDepth(+e.depth.value)),e.depth.addEventListener("dblclick",()=>this.setDepth(0)),e.inviteBtn=i(t("invite"),V.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),V.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,k("label",{class:"dxr-call-depth"},[t("depth"),e.depth]),e.inviteBtn,e.leave)}_refreshBar(){let e=this.ui;if(!e||!e.mic)return;let t=this.t;e.mic.innerHTML=this.muted?V.micOff:V.mic,e.mic.setAttribute("aria-pressed",String(this.muted)),e.mic.title=this.muted?t("unmute"):t("mute");let i=!this.local?.videoTrack;e.cam.innerHTML=this.camOff||i?V.camOff:V.cam,e.cam.setAttribute("aria-pressed",String(this.camOff||i)),e.cam.title=i?this.camStatus==="busy"?t("cameraBusyRetry",{cameraBusy:t("cameraBusy")}):t("cameraRetry"):this.camOff?t("cameraOn"):t("cameraOff")}_refreshSelf(){this.self?.update()}_refreshLobby(){(this.state==="lobby"||this.state==="idle")&&this._layout()}_renderInvite(e,t,i){e.replaceChildren();let r=this.inviteLink();if(!r)return;let s=this.t,o=k("input",{type:"text",readOnly:!0,value:r,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=k("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:s("copyLink")});a.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(r),a.textContent=s("copied")}catch{o.select(),a.textContent=s("pressCopy")}setTimeout(()=>a.textContent=s("copyLink"),1800)});let l=k("canvas",{"aria-label":s("qrLabel"),role:"img"});try{dn(l,r,{px:4})}catch{l.style.display="none"}e.append(k("h3",{text:t}),k("p",{text:i}),k("div",{class:"dxr-call-invite"},[k("div",{class:"dxr-call-row",style:"flex:1 1 280px"},[o,a]),l]))}_layout(){let e=this.ui;if(!e)return;let t=this.container,i=this.t,r=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",r),I(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),I(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,p]of this.tiles)p.el.classList.toggle("dxr-call-tile--main",c===o);if(!this.o.chrome)return;this._refreshBar(),queueMicrotask(()=>this._fitGrid());let a=e.panel;if(r){I(a,!0),a.replaceChildren();let c=this.local,p=!!this.room,f=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(p?"lobbyJoinTitle":"lobbyStartTitle"),h={width:c?.width||0,height:c?.height||0},d=this.camStatus==="busy"?i("kindBusy"):!c||!c.videoTrack?i("kindNone"):c.format==="sbs"?i("kindSbs",h):i("kindMono",h),m=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,u=k("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(p?"join":"start")});u.addEventListener("click",()=>this.join().catch(()=>{}));let v=k("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(v),v.addEventListener("change",()=>this.setCamera(v.value).catch(x=>this.error("camera-failed",x.message,x)));let y=!c||!c.videoTrack?k("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;y?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(k("h3",{text:f}),k("p",{text:m}),k("div",{class:"dxr-call-row"},[this.state==="full"?null:u,y,v]))}else this.state==="in-call"&&s===0?(I(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(I(a,!0),a.replaceChildren(k("p",{text:i("joining")}))):I(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),I(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:yt,wire:je,state:this.state,wall:this.wall,wallLive:this.wallLive,weaveLive:this.weaveLive,woven:this.woven,local:e?{format:e.format,width:e.width,height:e.height,label:e.label,calibration:e.calibration,owned:e.owned,skipped:e.skipped,camera:e.cam||null,stream:e.stream}:null,hello:this.hello(),transport:this.transport,peers:[...this.tiles.values()].map(t=>t.diag()),mono3D:{...this._mono3DInfo(),lift:this.liftApi,pool:this.liftPool?this.liftPool.list():[]},speaker:this.speakerId,depth:this.depth,options:this.o,kill:t=>this.transport?._debugKill(t)}}async _fillCameras(e){let t=[];try{t=(await navigator.mediaDevices.enumerateDevices()).filter(r=>r.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((r,s)=>k("option",{value:r.deviceId,text:r.label||`Camera ${s+1}`}))),i&&(e.value=i),I(e,t.length>1)}_makeHandle(){let e=this,t={format:"display",session:null},i={get room(){return e.room},get id(){return e.id},get state(){return e.state},get localFormat(){return e.local?e.local.format:null},get muted(){return e.muted},get cameraOff(){return e.camOff},get depth(){return e.depth},get speaker(){return e.speakerId},get camera(){return e.camStatus},get mono3D(){return e._mono3DInfo()},get peers(){return Object.freeze([...e.tiles.values()].map(s=>s.info()))},join:()=>e.join().then(()=>{}),inviteLink:()=>e.inviteLink(),mute:s=>e.mute(s),setCameraOff:s=>e.setCameraOff(s),setCamera:(s,o)=>e.setCamera(s,o),setDepth:s=>e.setDepth(s),retryCamera:()=>e.retryCamera(),setMono3D:s=>e.setMono3D(s),leave:()=>e.leave("left"),tile:s=>e.tiles.get(s)?.el||null,diagnostics:()=>e.diagnostics(),on(s,o){if(typeof o!="function")throw new TypeError(`${B} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${B} the '${s}' event is deprecated (removed in 1.31)${a?` \u2014 listen for '${a}'`:" \u2014 it is internal now; diagnostics() has the wall"}`)}return e.listeners.has(s)||e.listeners.set(s,new Set),e.listeners.get(s).add(o),()=>e.listeners.get(s)?.delete(o)},off(s,o){e.listeners.get(s)?.delete(o)}},r={wall:["diagnostics().wall (or the wall you passed / sharedInline3D())",()=>e.wall],format:["localFormat",()=>i.localFormat],sendHint:["nothing \u2014 auto-convergence superseded it",()=>s=>e.sendHint(s)],_debug:["diagnostics()",()=>({transport:e.transport,kill:s=>e.transport?._debugKill(s)})]};for(let[s,[o,a]]of Object.entries(r))Object.defineProperty(i,s,{enumerable:!1,configurable:!0,get(){return e._handleWarned?.has(s)||((e._handleWarned||=new Set).add(s),console.warn(`${B} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function Gr(n){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((n.clientWidth||0)*e),i=Math.round((n.clientHeight||0)*e);return!t||!i?!1:((n.width!==t||n.height!==i)&&(n.width=t,n.height=i),!0)}function bn(n,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Gr(n))return;let r=n.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=$(a,o,n.width/n.height,0,0);r.save(),i&&(r.translate(n.width,0),r.scale(-1,1)),r.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,n.width,n.height),r.restore()}var Ye=class{constructor(e,t){this.call=e,this.id=t,this.hello=null,this.format=null,this.route=null,this.routedKey=null,this.handle=null,this.conn="connecting",this.remote={muted:!1,cameraOff:!1,speaking:!1},this.level=0,this.speaking=!1,this.quality=null,this.conv=ve(),this.autoTrack=$e(),this.autoFocus=Me(),this.autoAt=0,this.autoCanvas=null,this.autoLocked=!1,this.autoStats={n:0,ms:0,readMs:0,method:null,via:null},this.autoPending=!1,this.autoGen=0,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=kt(wt),this.layerFails=0,this.forceFlat=!1,this.lifted=!1,this.liftHandle=null,this.liftLive=!1,this.liftFailed=!1,this.liftFails=0,this.visible=!0,this.video=Object.assign(document.createElement("video"),{muted:!0,playsInline:!0,autoplay:!0}),this.audio=Object.assign(document.createElement("audio"),{autoplay:!0}),this.video.addEventListener("playing",()=>this._maybeRoute()),this.video.addEventListener("loadeddata",()=>this._maybeRoute()),this.video.addEventListener("resize",()=>this._maybeRoute()),this.canvas=k("canvas"),this.cover=k("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=k("div",{class:"dxr-call-badge",part:"badge"}),this.plate=k("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=k("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=k("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,k("div",{class:"dxr-call-talk"})]),e.o.ui||I(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge()}display(){return Tt(this.route)}info(){return Object.freeze({id:this.id,format:this.format||"mono",display:this.display(),state:this.conn,muted:this.remote.muted,cameraOff:this.remote.cameraOff,speaking:this.speaking})}diag(){return{...this.info(),route:this.route,rectified:!!(this.hello&&this.hello.rectified),hello:this.hello,quality:this.quality,convergencePx:this.conv.current,autoConverge:{disparityPx:this.conv.measuredPx,ms:this.autoStats.n?this.autoStats.ms/this.autoStats.n:null,readMs:this.autoStats.n?this.autoStats.readMs/this.autoStats.n:null,method:this.autoStats.method,via:this.autoStats.via},lift:this.lifted?{live:this.liftLive,native:!!(this.liftHandle&&this.liftHandle.native),priority:this.call.liftPool?this.call.liftPool.priority(this.id):null,state:this.liftHandle?this.liftHandle.state||null:"pending"}:null,element:this.el}}setStream(e){this.video.srcObject!==e&&(this.video.srcObject=e,this.audio.srcObject=e,this._resetAutoConverge()),this.video.play().catch(()=>{}),this.audio.play().catch(()=>{})}onChannelOpen(){clearTimeout(this.helloTimer),this.helloTimer=setTimeout(()=>{this.format||(this.format="mono",this._maybeRoute())},Hr)}setHello(e){clearTimeout(this.helloTimer),this.hello=e,this.conv.hello=e;let t=this.format!==e.format;this.format=e.format,this.call.log("hello",{peer:this.id,format:e.format,width:e.width,height:e.height,rectified:e.rectified}),t?this._maybeRoute():this._renderBadge()}setHint(e){this.hintGate(performance.now())&&(this.conv.subjectZmm=e.subjectZmm)}setRemoteState(e){this.remote=e,this._renderBadge(),this._renderPlate(),this._updateVisible()}setSpeaking(e){e!==this.speaking&&(this.speaking=e,this.el.classList.toggle("dxr-call-tile--speaking",e))}setConn(e){e==="unreachable"&&this.conn!=="unreachable"&&this.call.error("unreachable",`${this.call.t("unreachable")}. Still retrying in the background.`,Object.assign(new Error("unreachable"),{peer:this.id})),this.conn=e,e==="connected"&&this.leaveTimer&&(clearTimeout(this.leaveTimer),this.leaveTimer=null),this._renderPlate()}_renderPlate(){let e=this.call.t,t=this.conn==="left"?e("leftCall"):this.conn==="unreachable"?e("unreachable"):this.conn==="reconnecting"?e("reconnecting"):this.conn!=="connected"?e("connecting"):this.remote.cameraOff?e("cameraOffPlate"):null;this.plate.textContent=t||"",I(this.plate,!!t)}_renderBadge(){let e=this.call.t,t=this.route==="woven-sbs"?e("badge3D"):this.route==="lifted"?e("badge2D3D"):e("badge2D"),i=this.route?this.route==="lifted"&&!this.liftLive?`${t}${e("badgePending")}`:t:e("badgePending");this.badge.replaceChildren(k("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",V.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,r=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:Et({format:this.format,woven:t.woven,mono3D:t.mono3DOn?"auto":"off",lift:!!i,overBudget:i?!i.canAcquire(this.id):!1,failed:this.liftFailed});this.format!=="sbs"&&t.woven&&t.mono3DOn&&!t._liftP&&t._ensureLift(),this.format!=="sbs"&&t.woven&&t.liftMissing&&t._warnLiftMissing();let s=`${r.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=r.route,r.route==="woven-sbs"?this._registerWoven():r.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:r.route,format:this.format,mono3d:r.mono3d||null}),t.emit("display",{id:this.id,display:this.display()}),t.listeners.get("format")?.size&&t.emit("format",{id:this.id,format:this.format,route:r.route,mono3d:r.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),I(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(I(this.cover,!1),e.log("first-woven",{peer:this.id,woven:i.woven,reason:i.reason,ms:Math.round(i.ms)}),!i.woven&&i.reason==="layer-failed"&&this._layerFailed())})}_registerLifted(){let e=this.call,t=e.liftPool;this.lifted=!0,this.liftLive=!1,this.video.classList.add("dxr-call-liftsrc"),this.canvas.classList.add("dxr-call-liftflat"),this.video.parentNode!==this.stage&&this.stage.insertBefore(this.video,this.stage.firstChild),this._observeVisible(),t.acquire(this.id,this.video,{wall:e.wall,visible:this.visible,onError:i=>this._liftError(i)}).then(i=>{if(!i||!this.lifted||t.handle(this.id)!==i)return;this.liftHandle=i;let r=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>r(s&&s.state)),i.on?.("error",s=>{s&&s.fatal&&this._liftError(s.error)})],i.state==="live"?this._liftShowing(!0):i.canvas&&i.canvas.style&&(i.canvas.style.visibility="hidden"),e.log("lifted",{peer:this.id,native:!!i.native,woven:!!i.woven,state:i.state||null,provider:i.stats&&i.stats.provider||null})})}_liftShowing(e){if(e===this.liftLive)return;this.liftLive=e;let t=this.liftHandle;e?(t&&t.canvas&&t.canvas.style&&!t.native&&(t.canvas.style.visibility=""),this.canvas.style.visibility="hidden",this.liftFails=0,this.call.liftProven||(this.call.liftProven=!0,this.call._refreshLobby())):this.canvas.style.visibility="",this.call.log("lift-live",{peer:this.id,live:e}),this._renderBadge()}_liftError(e){this.lifted&&(this.call.log("lift-error",{peer:this.id,message:String(e&&e.message||e).slice(0,200)}),this.liftFailed=!0,this.reroute(!0),!(this.liftFails++>=Ur)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},H(this.liftFails-1,{baseMs:3e3,maxMs:3e4}))))}_observeVisible(){this._io||typeof IntersectionObserver!="function"||(this._io=new IntersectionObserver(e=>{let t=e[e.length-1];this._onscreen=!!(t&&t.isIntersecting),this._updateVisible()}),this._io.observe(this.stage))}_updateVisible(){let e=this._onscreen!==!1&&!this.remote.cameraOff;e!==this.visible&&(this.visible=e,this.call.liftPool?.setVisible(this.id,e))}_layerFailed(){if(this.forceFlat=!0,this.reroute(!0),this.layerFails++>=Br)return;let e=H(this.layerFails-1,{baseMs:1500,maxMs:2e4});this.call.log("layer-retry",{peer:this.id,attempt:this.layerFails,inMs:e}),clearTimeout(this.layerTimer),this.layerTimer=setTimeout(()=>{this.forceFlat=!1,this.call.woven&&this.reroute(!0)},e)}onWallLost(){this.handle=null,this.reroute(!0)}_unregister(){if(I(this.cover,!1),this.lifted){this.lifted=!1;for(let e of this._liftOff||[])typeof e=="function"&&e();this._liftOff=null,this.call.liftPool?.release(this.id),queueMicrotask(()=>this.call.state!=="left"&&this.call._rerouteMono()),this.liftHandle=null,this.liftLive=!1,this.canvas.style.visibility="",this.canvas.classList.remove("dxr-call-liftflat"),this._io&&(this._io.disconnect(),this._io=null),this.video.parentNode&&(this.video.remove(),this.video.classList.remove("dxr-call-liftsrc"),setTimeout(()=>this.video.srcObject&&this.video.play().catch(()=>{}),0))}if(this.handle){try{this.handle.remove()}catch{}this.handle=null}}paint(){this.route&&(this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||bn(this.canvas,this.video):bn(this.canvas,this.video,{eyeHalf:this.route==="flat-left"?0:null}))}_paintConv(){let e=this.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.convCanvas)return;let r=t/2,s=this.call.o.tileAspect,{w:o,h:a}=_e(r,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a),this.call.o.autoConverge&&this._sampleDisparity(e,t,i);let c=this.conv.step(r),p=l.getContext("2d");for(let f of[0,1]){let h=$(r,i,s,c,f);p.drawImage(e,f*r+h.sx,h.sy,h.sw,h.sh,f*o,0,o,a)}}_sampleDisparity(e,t,i){let r=performance.now();if(this.autoPending||r-this.autoAt<qr)return;if(this.autoAt=r,typeof VideoFrame=="function"){let f=null;try{f=new VideoFrame(e)}catch{f=null}if(f&&Xr.has(f.format)){this.autoPending=!0;let h=this.autoGen,d=f.visibleRect?f.visibleRect.width:f.displayWidth,m=f.visibleRect?f.visibleRect.height:f.displayHeight,u=new Uint8Array(f.allocationSize());f.copyTo(u).then(v=>{if(h!==this.autoGen)return;let y=performance.now(),x=Math.max(1,Math.ceil(d/2/wn)),M=zi(u,v[0].offset,v[0].stride,d,m,x);this._applyMeasurement(M.img,M.w,M.h,M.w/d,r,performance.now()-y,"videoframe")}).catch(()=>{h===this.autoGen&&this._applyMeasurement(null,0,0,1,r,0,"videoframe")}).finally(()=>{f.close(),this.autoPending=!1});return}f&&f.close()}let s=Math.min(1,wn/(t/2)),o=Math.max(2,Math.round(t*s/2)*2),a=Math.max(2,Math.round(i*s));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let l=this.autoCanvas;(l.width!==o||l.height!==a)&&(l.width=o,l.height=a);let c=l.getContext("2d",{willReadFrequently:!0}),p=null;try{c.drawImage(e,0,0,o,a),p=Ve(c.getImageData(0,0,o,a).data,o*a)}catch{p=null}this._applyMeasurement(p,o,a,o/t,r,performance.now()-r,"canvas")}_applyMeasurement(e,t,i,r,s,o,a){if(this.destroyed)return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,p=this.autoTrack.push(c?c.d/r:null);this.conv.measuredPx=p,this.autoStats.n++,this.autoStats.readMs+=o,this.autoStats.ms+=o+(performance.now()-l),this.autoStats.method=c?c.method:null,this.autoStats.via=a,c&&!this.autoLocked&&(this.autoLocked=!0,this.call.log("auto-converge",{peer:this.id,disparityPx:Math.round(p*10)/10,at:{x:Math.round(c.x/r),y:Math.round(c.y/r)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,clearTimeout(this.helloTimer),clearTimeout(this.layerTimer),clearTimeout(this.leaveTimer),clearTimeout(this.liftTimer),this._unregister(),this.video.srcObject=null,this.audio.srcObject=null,this.el.remove()}},ei=class{constructor(e,t){this.call=e,this.canvas=k("canvas"),this.badge=k("div",{class:"dxr-call-badge",part:"badge"}),this.plate=k("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=k("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=k("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,k("div",{class:"dxr-call-talk"})]),t.appendChild(this.el),this.view=null,this.cam=null}get route(){return this.view?this.view.route:null}update(){let e=this.call.local,t=this.call.t,i=!e||!e.videoTrack;this.plate.textContent=i?this.call.camStatus==="busy"?t("cameraBusy"):this.call.camStatus==="pending"?"":t("noCamera"):this.call.camOff?t("cameraOffPlate"):"",I(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,r=this.call.woven?this.call.wall:{supported:!1};if(!i||i.state!=="live")return this.detach(),this._badge();this.view&&this.cam===i?this.view._reroute(e,r):(this.detach(),this.cam=i,this.view=zt(r,this.canvas,i,{mirror:!0,autoConverge:!1,aspect:this.call.o.tileAspect})),this._badge()}_badge(){let e=this.call.t;this.badge.replaceChildren(k("b",{text:`${e("you")} \xB7 ${this.route==="woven-sbs"?e("badge3D"):e("badge2D")}`}))}onWallLost(){this.view?._onWallLost(),this._badge()}detach(){this.view&&this.view.remove(),this.view=null,this.cam=null}setSpeaking(e){this.el.classList.toggle("dxr-call-tile--speaking",e)}},Jr="1.31",xn=new Set;function C(n,e,t){let i=()=>{xn.has(n)||(xn.add(n),console.warn(`${B} \`${n}\` is internal and leaves '@displayxr/inline3d/call' in ${Jr} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(r,s,o){return i(),Reflect.apply(r,s,o)},construct(r,s){return i(),Reflect.construct(r,s)}}):t&&typeof t=="object"?new Proxy(t,{get(r,s,o){return typeof s=="string"&&i(),Reflect.get(r,s,o)}}):t}var Ks=C("normalizeCallOptions","js/call/options.js",Xt),Ys=C("newRoomId","js/call/wire.js",bt),Zs=C("isValidRoomId","js/call/wire.js",re),Qs=C("buildInviteLink","js/call/wire.js",We),eo=C("normalizeHello","js/call/wire.js",xt),to=C("makeHello","js/call/wire.js",St),io=C("routeFor","js/call/wire.js",Et),no=C("badgeFor","js/call/wire.js",Tt),ro=C("createLiveGate","js/call/wire.js",Ct),so=C("convergenceShiftPx","js/camera/converge.js",Pe),oo=C("lowPass","js/camera/converge.js",Fe),ao=C("clampShift","js/camera/converge.js",Ie),lo=C("eyeCropRect","js/camera/geometry.js",$),co=C("mirrorSwapOps","js/camera/geometry.js",ie),ho=C("mirrorSwapPixels","js/camera/geometry.js",vt),fo=C("maxBitrateKbps","js/call/wire.js",Ne),uo=C("measureFocusDisparity","js/camera/disparity.js",Ot),mo=C("preferVideoCodecs","js/call/sdp.js",be),po=C("sortCodecCapabilities","js/call/sdp.js",ze),go=C("VIDEO_CODEC_ORDER","js/call/sdp.js",we),_o=C("MeshTransport","js/call/transport.js",xe),vo=C("clampMaxPeers","js/call/transport.js",Se),yo=C("qrEncode","js/call/qr.js",$t),wo=C("roomKey","js/call/signaling.js",Bt);var bo=C("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:Ee.unreachable,cameraBusy:Ee.cameraBusy})),xo=C("CALL_ACCENTS","js/call/ui.js",qt),So=C("normalizeMono3D","js/call/lift.js",pe),Mo=C("resolveLift","js/call/lift.js",it),ko=C("createLiftPool","js/call/lift.js",st),Eo=C("createFrameWatch","js/call/lift.js",rt),To=C("liftConvergenceFor","js/call/lift.js",me),Co=C("liftPriorityFor","js/call/lift.js",Ce),Ro=C("setLiftPriority","js/call/lift.js",nt),Do=C("defaultLiftSpecifier","js/call/lift.js",tt),Lo=C("LIFT_PRIORITY","js/call/lift.js",ue);Ke();ii(()=>new URL("./lift.js",import.meta.url).href);export{Jt as CALL_EVENT_PREFIX,rn as CAMERA_SDK,Ut as DXR_SIGNAL_DEFAULT,he as DxrCallElement,Sn as addCall,zt as addCameraView,Kt as attrsToOpts,ki as createInline3D,Ke as defineCallElement,ce as dxrSignaling,Si as inline3DAvailable,Je as isStereoCamera,Yt as mountCall,Nt as openCamera,ye as parseInviteLink,Pt as parseStereoXmp,Xi as readJpegStereoMeta,It as readJpegXmp,en as readWebmStereoMeta,Ae as sharedInline3D,Ge as suggestedName};
package/index.d.ts CHANGED
@@ -31,6 +31,8 @@ export interface TileOptions {
31
31
  *
32
32
  * - `woven: true, reason: 'hold-elapsed'` — a stereo frame is on a layer that has existed for
33
33
  * `firstWovenHoldMs`. Drop the poster covering the canvas.
34
+ * - `woven: true, reason: 'hold-capped'` — `rewoven()` only: the canvas kept resizing, so it
35
+ * stopped waiting four holds after the call. Drop the cover; the rect may still be settling.
34
36
  * - `woven: false` — the window will not weave (`'layer-failed'`, `'session-ended'`,
35
37
  * `'removed'`; the subpaths add `'unsupported'`). The canvas is already flat (image/video) or
36
38
  * its `onLayerLost` has run (scene). Drop the poster onto the 2D fallback.
@@ -42,7 +44,7 @@ export interface FirstWovenResult {
42
44
  * that, so the result is the SDK's worst-case hold rather than a report.
43
45
  */
44
46
  readonly confirmed: boolean;
45
- readonly reason: 'hold-elapsed' | 'layer-failed' | 'session-ended' | 'removed' | 'unsupported';
47
+ readonly reason: 'hold-elapsed' | 'hold-capped' | 'layer-failed' | 'session-ended' | 'removed' | 'unsupported';
46
48
  /** Milliseconds from the add*() call to settling. */
47
49
  readonly ms: number;
48
50
  }
@@ -384,6 +386,16 @@ export interface TileHandle {
384
386
  readonly firstWoven: Promise<FirstWovenResult>;
385
387
  /** Callback form of {@link TileHandle.firstWoven}: called once, asynchronously. Returns an unsubscribe. */
386
388
  onFirstWoven(cb: (result: FirstWovenResult) => void): () => void;
389
+ /**
390
+ * {@link TileHandle.firstWoven}, measured from NOW. Cover an already-woven canvas across a rect
391
+ * change (fullscreen, a layout resize), then release on this. A change of the canvas's CSS size
392
+ * or devicePixelRatio while pending restarts the hold (checked every frame, any window kind; a
393
+ * move without a resize is not detected). It settles anyway, `woven: true, reason:
394
+ * 'hold-capped'`, four holds after the call, so a size that never stops animating cannot hold a
395
+ * cover up for good. A second call while pending returns the same promise, restarted. Before the
396
+ * first join it is `firstWoven`; on a window that will not weave it is that `woven: false` result.
397
+ */
398
+ rewoven(): Promise<FirstWovenResult>;
387
399
  }
388
400
 
389
401
  /** An open inline-3D session you add weaved windows to. Returned by {@link createInline3D}. */
@@ -678,6 +690,20 @@ export function createInline3D(
678
690
  opts?: CreateInline3DOptions,
679
691
  ): Promise<Inline3D | Inline3DUnsupported>;
680
692
 
693
+ /**
694
+ * The document's shared manager: the live {@link createInline3D} result if one exists, else a new
695
+ * one. One inline-3D session per document (woven-canvas rule 1) is the point: a module that needs
696
+ * a wall it did not create (`mountCall`, `<dxr-call>`) uses this instead of opening a second
697
+ * session, and a page that made its own wall first gets that same wall back here.
698
+ *
699
+ * `opts` apply only when this call creates the manager. An unsupported browser resolves to
700
+ * `{ supported: false }` every time (nothing is cached; a later call re-probes). Two callers
701
+ * racing before the first session resolves share one creation. Additive since 1.29.
702
+ */
703
+ export function sharedInline3D(
704
+ opts?: CreateInline3DOptions,
705
+ ): Promise<Inline3D | Inline3DUnsupported>;
706
+
681
707
  /**
682
708
  * Back-compatible single-scene helper: open a session, weave one canvas, drive a render callback
683
709
  * each frame. Equivalent to `createInline3D({lazy:false})` then `addScene(canvas, onFrame)`.