@displayxr/inline3d 1.42.0 → 1.42.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/call.js +4 -4
- package/js/camera/converge.js +6 -2
- package/js/camera/disparity.js +12 -3
- package/js/camera/pair-cursor.js +107 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,30 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
|
|
|
5
5
|
`./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
|
|
6
6
|
which tier they touch, because that is what tells you whether an upgrade can move your pixels.
|
|
7
7
|
|
|
8
|
+
## 1.42.1 — 2026-10-12
|
|
9
|
+
|
|
10
|
+
Touches the **preview tier** (`./call`, `./camera`) only: auto-convergence and the stereo-tile depth
|
|
11
|
+
cursor are steadier on a wide-baseline camera. No API change.
|
|
12
|
+
|
|
13
|
+
### Auto-convergence holds the face on a 120 mm-baseline camera
|
|
14
|
+
|
|
15
|
+
- Found on the SR laptop's built-in stereo camera (120 mm baseline, grayscale): auto-convergence
|
|
16
|
+
flipped between the face and the background. On a dim frame the sparse block grid (1.5 blocks
|
|
17
|
+
apart) matched ~9 blocks, 3-4 on the face, too few to form the subject mode, so the background
|
|
18
|
+
won. The grid is now one block apart (~36 blocks: the face on every frame, ±1 px instead of ±4),
|
|
19
|
+
and a mode's bin widens with its disparity (10%), so a near face's own relief stays one group.
|
|
20
|
+
- The convergence shift may now reach 20% of the eye width (was 12%): that camera sees a face at
|
|
21
|
+
0.6 m at ~22% of the eye width, ~11% per eye, which left no room to lean in.
|
|
22
|
+
|
|
23
|
+
### Stereo-tile depth cursor: steady at foreground edges
|
|
24
|
+
|
|
25
|
+
- The footprint was matched from the left eye's image only. At a foreground edge the left eye's
|
|
26
|
+
block can sit on the subject while the right eye's sits on the background, and the arrow jumped
|
|
27
|
+
out and back frame to frame. Each footprint point is now matched from BOTH eyes, every match must
|
|
28
|
+
pass a left-right consistency check (matched back, it lands within 1 px of where it started), and
|
|
29
|
+
the nearest value counts only when a second sample agrees; otherwise the arrow stays on the
|
|
30
|
+
glass. Over 20 live frames across a face edge: 200 → 35 large jumps.
|
|
31
|
+
|
|
8
32
|
## 1.42.0 — 2026-10-11
|
|
9
33
|
|
|
10
34
|
Touches the **core** `./three` (`DepthCursor`) and the **preview tier** (`./model`, `./splat`,
|
package/dist/call.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/* @displayxr/inline3d 1.42.
|
|
2
|
-
var un=Object.defineProperty;var ge=(r,e)=>()=>(r&&(e=r(r=0)),e);var fn=(r,e)=>{for(var t in e)un(r,t,{get:e[t],enumerable:!0})};function ki(r,e,t=1){let i=Pe,n=!!r&&r.displayWidthMeters>0&&r.displayHeightMeters>0&&r.displayPixelWidth>0&&r.displayPixelHeight>0,s=n?[r.displayWidthMeters,r.displayHeightMeters]:[...i.displaySizeM],o=n?[r.displayPixelWidth,r.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=n?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),p=r?.nominalViewerPosition?.z,m=Number.isFinite(p)&&p>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:m?p:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:n?"display":"default",viewer:m?"display":"default",eyeSeparation:"default"}}}var Pe,gt=ge(()=>{"use strict";Pe=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063})});function Ge(r,e,t,i,n,s,o,a,l,c,p){if(s<0||s+a>t||o<0)return-1;let m=0,h=0,d=0,u=a*l;for(let v=0;v<l;v++){let b=(n+v)*e+i,k=(o+v)*e+t+s;for(let x=0;x<a;x++){let P=r[k+x];m+=P,h+=P*P,d+=r[b+x]*P}}let f=m/u,y=h/u-f*f;return y<1?-1:(d/u-c*f)/(p*Math.sqrt(y))}function as(r,e,t,i,n,s){let o=0,a=0;for(let p=0;p<s;p++){let m=(i+p)*e+t;for(let h=0;h<n;h++){let d=r[m+h];o+=d,a+=d*d}}let l=n*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function Te(r,e,t,i,n,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:p}={}){let m=e/2,{mean:h,std:d}=as(r,e,i,n,s,o);if(d<6)return null;let u=-2,f=0,y=0,v=new Map,b=(T,g,w,_,M)=>{for(let O=_;O<=M;O++){let S=n+O;if(!(S<0||S+o>t))for(let F=T;F<=g;F+=w){let H=Ge(r,e,m,i,n,i-F,S,s,o,h,d);H>(v.get(F)??-2)&&v.set(F,H),H>u&&(u=H,f=F,y=O)}}},k=l-a>8;if(b(a,l,k?2:1,-c,c),k&&u>-1){let T=f,g=y;b(Math.max(a,T-2),Math.min(l,T+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(u<-1)return null;let x=-2,P=T=>{let g=-2;for(let w=-c;w<=c;w++){let _=n+w;if(!(_<0||_+o>t))for(let M=T-1;M<=T+1;M++)g=Math.max(g,Ge(r,e,m,i,n,i-M,_,s,o,h,d))}return g};for(let[T,g]of v){if(Math.abs(T-f)<3||g<=x)continue;let _=g>=(v.get(T-2)??-2)&&g>=(v.get(T+2)??-2)&&g>0?P(T):g;_>x&&(x=_)}if(l-a>12&&x>-2&&u-x<(p??.08))return null;let R=Ge(r,e,m,i,n,i-(f-1),n+y,s,o,h,d),L=Ge(r,e,m,i,n,i-(f+1),n+y,s,o,h,d),I=0,A=R-2*u+L;return R>-1&&L>-1&&A<0&&(I=Math.max(-.5,Math.min(.5,.5*(R-L)/A))),{d:f+I,dy:y,c:u}}function ls(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.step||Math.round(s*1.5),a=i.dMax??Math.round(n*.3),l=i.dMin??-Math.round(n*.05),c=Math.round(n*(i.roiX0??.15)),p=Math.round(n*(i.roiX1??.85))-s,m=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let u=m;u<=h;u+=o)for(let f=c;f<=p;f+=o){let y=Te(r,e,t,f,u,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});y&&y.c>=(i.minNcc??.8)&&d.push({x:f,y:u,...y})}return d}function cs(r,{tol:e=2,minFrac:t=.12,minBlocks:i=3}={}){if(!r.length)return null;let n=Math.max(i,Math.ceil(r.length*t)),s=r.map(o=>o.d).sort((o,a)=>a-o);for(let o of s){let a=r.filter(l=>Math.abs(l.d-o)<=e);if(a.length>=n){let l=a.map(c=>c.d).sort((c,p)=>c-p);return{d:l[l.length>>1],members:a}}}return null}function hs(r,e){let t=Math.min(...r.map(l=>l.y)),n=r.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...n),o=Math.max(...n)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function Xt(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.dMax??Math.round(n*.3),a=i.dMin??-Math.round(n*.05),l=i.focus||null,c="focus",p=0,m=null;if(!l){let k=ls(r,e,t,{...i,block:s,dMax:o,dMin:a});p=k.length;let x=cs(k,i);if(!x)return null;l=hs(x.members,s),m=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),u=Math.round(Math.max(0,Math.min(n-h,l.x-h/2))),f=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),y=m===null?a:Math.max(a,Math.floor(m)-4),v=m===null?o:Math.min(o,Math.ceil(m)+4),b=Te(r,e,t,u,f,h,d,{dMin:y,dMax:v,dyMax:i.dyMax??2});return b&&b.c>=(i.minNcc??.8)?{d:b.d,x:l.x,y:l.y,c:b.c,method:c,blocks:p}:m!==null?{d:m,x:l.x,y:l.y,c:0,method:c,blocks:p}:null}function Je(r,e){let t=new Uint8Array(e);for(let i=0,n=0;i<e;i++,n+=4)t[i]=r[n]*77+r[n+1]*150+r[n+2]*29>>8;return t}function Ye({n:r=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>r&&e.shift();let n=[...e].sort((s,o)=>s-o);return t.value=n[n.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function dr(r,e,t,i,n,s){let o=new Float32Array(n*s);for(let a=0;a<s;a++)for(let l=0;l<n;l++)o[a*n+l]=r[(i+a)*e+t+l];return o}function ds(r,e,t,i,n,s,o,a,l,c){let p=e/2,m=n*s,h=0,d=0;for(let b=0;b<m;b++)h+=i[b],d+=i[b]*i[b];h/=m;let u=Math.sqrt(Math.max(1e-6,d/m-h*h)),f=-2,y=o,v=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let k=Math.max(0,o-l);k<=Math.min(p-n,o+l);k++){let x=0,P=0,R=0;for(let T=0;T<s;T++){let g=(b+T)*e+k;for(let w=0;w<n;w++){let _=r[g+w];x+=_,P+=_*_,R+=_*i[T*n+w]}}let L=x/m,I=P/m-L*L;if(I<1)continue;let A=(R/m-L*h)/(Math.sqrt(I)*u);A>f&&(f=A,y=k,v=b)}return{x:y,y:v,c:f}}function De({fullEveryMs:r=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:n=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,p,m,h,d={}){let u=p/2,f=d.block||Math.max(8,Math.round(u/20)),y=Math.round(f*3),v=Math.round(f*1.5),b=null;if(o&&o.w===y&&o.h===v){let L=ds(c,p,m,o.tpl,y,v,o.x,o.y,t,i);if(L.c>=n){let I=Te(c,p,m,L.x,L.y,y,v,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});I&&I.c>=.8&&(b={m:I,f:L})}}let k=({m:L,f:I})=>(o={...o,x:I.x,y:I.y,d:L.d,tpl:dr(c,p,I.x,I.y,y,v)},{d:L.d,x:I.x+y/2,y:I.y+v/2,c:L.c,method:"track",blocks:0});if(b&&h-o.at<r)return k(b);let x=Xt(c,p,m,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let L=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!L?{d:x.d}:null,!L)return o.at=h,k(b)}else a=null;if(!x)return o=null,null;let P=Math.round(Math.max(0,Math.min(u-y,x.x-y/2))),R=Math.round(Math.max(0,Math.min(m-v,x.y-v/2)));return o={x:P,y:R,d:x.d,tpl:dr(c,p,P,R,y,v),w:y,h:v,at:h},x},reset(){o=null,a=null}}}function ur(r,e,t,i,n,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(n/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let d=0;d<l;d++)for(let u=0;u<a;u++){let f=0;for(let y=0;y<o;y++){let v=e+(d*o+y)*t+u*o;for(let b=0;b<o;b++)f+=r[v+b]}c[d*a+u]=f/h|0}return{img:c,w:a,h:l}}let p=o>>2,m=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+p)*t,u=e+(h*o+m)*t;for(let f=0;f<a;f++){let y=f*o+p,v=f*o+m;c[h*a+f]=r[d+y]+r[d+v]+r[u+y]+r[u+v]>>2}}return{img:c,w:a,h:l}}var Gt=ge(()=>{"use strict"});function us(r,e="@displayxr/inline3d"){if(r==null||r===!1)return null;if(r==="depth"||r===!0)return{};if(typeof r!="object")throw new Error(`${e}: cursor ${JSON.stringify(r)} \u2014 expected 'depth' or { height, margin, anchor, pointerScope }.`);let t=Object.keys(r).filter(i=>!pr.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${pr.join(", ")}.`);if(r.anchor!==void 0&&!fr.includes(r.anchor))throw new Error(`${e}: cursor.anchor "${r.anchor}" \u2014 expected ${fr.join(", ")}.`);if(r.pointerScope!==void 0&&r.pointerScope!=="canvas"&&r.pointerScope!=="window")throw new Error(`${e}: cursor.pointerScope "${r.pointerScope}" \u2014 expected 'canvas' or 'window'.`);for(let i of["height","margin"])if(r[i]!==void 0&&!(typeof r[i]=="number"&&r[i]>0&&Number.isFinite(r[i])))throw new Error(`${e}: cursor.${i} must be a positive number.`);return{...r}}function Ke(r,e="@displayxr/inline3d"){let t=us(r,e);if(!t)return null;let i=Object.keys(t).filter(n=>!mr.includes(n));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${mr.join(", ")}.`);return t}var fr,pr,mr,Jt=ge(()=>{"use strict";fr=Object.freeze(["hybrid","screen","world"]),pr=Object.freeze(["height","margin","anchor","pointerScope"]);mr=Object.freeze(["height","pointerScope"])});function Dr(r){return r>0&&Number.isFinite(r)?Math.min(.5,ti/r):vs}function Lr(r,e){return r<=ws?!(e>0&&Number.isFinite(e))||-r*e>=bs:!1}function ii(r,e,t){if(!e||!Number.isFinite(t)||!(t<0))return 0;let i=Math.min(0,Number.isFinite(r.maxDisparity)?r.maxDisparity:0);return Math.min(i,Math.max(r.minDisparity,t-r.margin))}function Ar(r,e,t,i){if(!r.primed||i<r.last||i-r.last>e.stale)return r.primed=!0,r.disparity=t,r.last=i,t;if(i===r.last)return r.disparity;let n=i-r.last,s=t<r.disparity?e.riseTau:e.sinkTau,o=s>0?1-Math.exp(-n/s):1;return r.disparity+=o*(t-r.disparity),r.last=i,r.disparity}function xs(r){let e=globalThis.document;if(!(!e||!e.documentElement)){if(r&&!e.getElementById("inline3d-cursor-style")){let t=e.createElement("style");t.id="inline3d-cursor-style",t.textContent="html.inline3d-cursor-hidden, html.inline3d-cursor-hidden * { cursor: none !important; }",(e.head||e.documentElement).appendChild(t)}ei=Math.max(0,ei+(r?1:-1)),e.documentElement.classList.toggle("inline3d-cursor-hidden",ei>0)}}function Ss(r,e,t,i){let n=.75*t,s=[[r,e]];for(let o=0;o<8;o++){let a=o*Math.PI/4;s.push([r+n*Math.cos(a)/i,e+n*Math.sin(a)])}return s}function Or(r,e,t,i){return[[r,e],...Ss(r+.3*t/i,e+.5*t,t,i)]}function ri(r,e=rt){let t=0;for(let s=0;s<e.length;s++){let[o,a]=e[s],[l,c]=e[(s+1)%e.length];t+=o*c-l*a}let i=t>0?1:-1,n=e.map((s,o)=>{let a=e[(o+1)%e.length],l=a[0]-s[0],c=a[1]-s[1],p=Math.hypot(l,c)||1;return[-c/p*i,l/p*i]});return e.map((s,o)=>{let a=n[(o+e.length-1)%e.length],l=n[o],c=r/(1+a[0]*l[0]+a[1]*l[1]);return[s[0]+(a[0]+l[0])*c,s[1]+(a[1]+l[1])*c]})}var vs,ti,ws,bs,it,tt,ei,rt,Fo,Wo,jo,No,Pr=ge(()=>{"use strict";vs=.03,ti=19;ws=-.005,bs=.5;it=Object.freeze({margin:.015,minDisparity:-.6,maxDisparity:0,riseTau:.03,sinkTau:.25,stale:.5});tt=class{constructor(e,{scope:t="canvas"}={}){if(t!=="canvas"&&t!=="window")throw new Error(`@displayxr/inline3d: cursor pointerScope "${t}" \u2014 expected 'canvas' or 'window'.`);this.canvas=e,this.scope=t,this.uv=null,this._hidden=!1,this._prev="",this._onMove=i=>{let n=e.getBoundingClientRect();if(!(n.width>0&&n.height>0))return void(this.uv=null);let s=(i.clientX-n.left)/n.width,o=(i.clientY-n.top)/n.height;this.uv=s>=0&&s<=1&&o>=0&&o<=1?[s,o]:null},this._onLeave=()=>{this.uv=null},this._target=t==="window"?globalThis:e,this._target.addEventListener("pointermove",this._onMove),t==="window"?(this._onOut=i=>{i.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}set(e,t){this.uv=e==null?null:[e,t]}aspect(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.width/e.height:1}cssHeight(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.height:0}panelPx(){return this.cssHeight()*(globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1)}hideCss(e){e!==this._hidden&&(this.scope==="window"?xs(e):e?(this._prev=this.canvas.style.cursor||"",this.canvas.style.cursor="none"):this.canvas.style.cursor==="none"&&(this.canvas.style.cursor=this._prev),this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}},ei=0;rt=Object.freeze([[0,0],[0,16],[4.2,12.4],[6.9,18.6],[9.5,17.5],[6.8,11.5],[11.7,11.5]].map(([r,e])=>Object.freeze([r/19,e/19]))),Fo=Object.freeze([[0,1,2],[0,2,5],[0,5,6],[2,3,4],[2,4,5]]);Wo=Object.freeze(ri(1/19).map(r=>Object.freeze(r))),jo=Object.freeze([1,1,1,1]),No=Object.freeze([.02,.02,.03,1])});var si={};fn(si,{PAIR_CURSOR_ARROW:()=>Rs,PAIR_CURSOR_CSS_PX:()=>Es,PAIR_CURSOR_CSS_PX_M:()=>Fr,PAIR_CURSOR_HEIGHT:()=>Ir,PairCursor:()=>ni,drawPairArrow:()=>zr,pairCursorScale:()=>jr,pairCursorTarget:()=>Cs,pairFootprintDisparity:()=>Wr,pairPxPerBaseline:()=>Nr});function Wr(r,e,t,i,n,s){if(!r||!r.img||!e||!e.rL||!e.rR||!(e.outW>0))return null;let{img:o,w:a,h:l,scale:c}=r,p=a/2,m=Math.max(8,Math.round(p/20)),h=Math.round(p*.3),d=-Math.round(p*.05),{rL:u,rR:f}=e,y=e.outW/u.sw,v=null;for(let[b,k]of Or(t,i,n,s)){if(!(b>=0&&b<=1&&k>=0&&k<=1))continue;let x=e.mirror?1-b:b,P=Math.round((u.sx+x*u.sw)*c-m/2),R=Math.round((u.sy+k*u.sh)*c-m/2);if(P<0||P+m>p||R<0||R+m>l)continue;let L=Te(o,a,l,P,R,m,m,{dMin:d,dMax:h,dyMax:2});if(!L||L.c<.8)continue;let I=(L.d/c-(u.sx-f.sx))*y;(v===null||I>v)&&(v=I)}return v}function jr(r,e,t){let i=t>0&&Number.isFinite(t)?t:Fr;return e>0?r/e/i:r/(1e3*i)}function Nr(r,e,t,i=Pe.eyeSeparationM){return jr(r,e,t)*i}function Cs(r,e,t=it){return r===null||!Number.isFinite(r)||!(e>0)?0:-ii(t,!0,-r/e)*e||0}function ks(r){let e=r>0?Math.max(.05263157894736842,1/r):.05263157894736842,t=Math.round(e*1e4),i=nt.get(t);return i||(nt.size>32&&nt.clear(),nt.set(t,i=ri(e))),i}function zr(r,e,t,i,n,s,o){let a=n*t,l=ks(o);for(let c of[0,1]){let p=c*e+i*e+(c===0?s/2:-s/2);r.save(),r.beginPath(),r.rect(c*e,0,e,t),r.clip();for(let[m,h]of[[rt,"#000"],[l,"#fff"]])r.beginPath(),m.forEach(([d,u],f)=>(f?r.lineTo:r.moveTo).call(r,p+d*o,a+u*o)),r.closePath(),r.fillStyle=h,r.fill();r.restore()}}var Es,Ir,Rs,Fr,nt,ni,oi=ge(()=>{"use strict";Pr();gt();Gt();Es=ti,Ir=.06,Rs=rt,Fr=.0254/96;nt=new Map;ni=class{constructor(e,{height:t,pointerScope:i="window"}={}){this.pointer=new tt(e,{scope:i}),this.height=t>0?t:null,this.filter={},this._luma=null,this._uv=null,this._content=null,this._metricsFor=null,this.metersPerCssPx=null,this.eyeSeparationM=Pe.eyeSeparationM,this.last=null}get hovering(){return!!this.pointer.uv}draw(e,t,i,n){let s=this.pointer.uv;if(!s)return this.idle();let[o,a]=s,l=this.height??this._osArrowFraction();(t!==this._luma||!this._uv||this._uv[0]!==o||this._uv[1]!==a)&&(this._content=Wr(t,i,o,a,l,i.outW/i.outH),this._luma=t,this._uv=s),this._askMetrics(i.handle);let c=this.pointer.canvas.getBoundingClientRect?.(),p=Nr(i.outW,c&&c.width,this.metersPerCssPx,this.eyeSeparationM),m=this._content===null?null:-this._content/p,h=ii(it,m!==null,m),d=Ar(this.filter,it,h,n),u=Lr(d,p),f=-d*p;return u&&zr(e,i.outW,i.outH,o,a,f,l*i.outH),this.pointer.hideCss(u),this.last={contentPx:this._content,targetPx:-h*p||0,disparityPx:u?f:0,filteredPx:f||0,drawn:u,pxPerBaseline:p},this.last}_askMetrics(e){!e||e===this._metricsFor||typeof e.displayMetrics!="function"||(this._metricsFor=e,Promise.resolve().then(()=>e.displayMetrics()).then(t=>{this._metricsFor!==e||!t||(t.metersPerCssPx>0&&(this.metersPerCssPx=t.metersPerCssPx),t.eyeSeparationM>0&&(this.eyeSeparationM=t.eyeSeparationM))}).catch(()=>{}))}_osArrowFraction(){let e=this.pointer.canvas.getBoundingClientRect?.();return e&&e.height>0?Dr(e.height):Ir}idle(){return this.pointer.hideCss(!1),this.filter={},this._uv=null,this.last=null,null}dispose(){this.pointer.dispose()}}});var ye=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),pn=["high","normal","low","paused"],mn=.02,gn=1e3/20,_n=3e3,yn=1e3/28;function we(r){return typeof r=="function"?r:r===!1||r==="off"?"off":"auto"}function dt(r=import.meta.url){return _e?typeof _e=="function"?_e():_e:new URL("../lift/index.js",r).href}var _e=null;function Ei(r){_e=r||null}function vn(){return import(dt())}async function ut(r,{importer:e=vn,nav:t=globalThis.navigator,log:i=null,capsOpts:n={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=we(r);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,m=null;if(p){try{m=await p(n)}catch{m=null}let h=!!(m&&m.webFallback&&m.webFallback.webgpu);if(m&&!m.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(m&&m.native),provider:m&&m.provider||null}),{lift:c,capabilities:p,caps:m,source:"module",reason:null}}function ve(r){let e=Number.isFinite(+r)&&r!==null?Math.max(-1,Math.min(1,+r)):0;return Math.abs(e)<mn?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Oe({id:r,speakerId:e,visible:t=!0}){return t?r!=null&&r===e?ye.speaker:ye.other:ye.hidden}function ft(r,e){if(!r||!pn.includes(e)||typeof r.setPriority!="function")return!1;try{return r.setPriority(e)!==!1}catch{return!1}}function pt({degradedMs:r=gn,recoveredMs:e=yn,holdMs:t=_n,alpha:i=.1}={}){let n=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(n=n===null?a:n+i*(a-n),o){if(n<e)return o=!1,s=0,"recovered"}else if(s=n>r?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){n=null,s=0,o=!1},get frameMs(){return n},get degraded(){return o}}}function mt({lift:r,max:e=4,log:t=null,options:i=null}={}){let n=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 u=Oe({id:h,speakerId:o,visible:d.visible});if(u===d.priority)return;d.priority=u;let f=ft(d.handle,u);c("lift-priority",{peer:h,priority:u,applied:f})},m={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:u,visible:f=!0,onError:y}={}){let v=s.get(h);if(v)return v.pending||Promise.resolve(v.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,k=Oe({id:h,speakerId:o,visible:f}),x={gen:b,handle:null,visible:f,priority:k,pending:null};s.set(h,x);let P={quality:"auto",...n,mode:"live",wall:u,ui:"none",convergence:ve(a),priority:k};return c("lift-acquire",{peer:h,priority:k,convergence:P.convergence}),x.pending=Promise.resolve().then(()=>r(d,P)).then(R=>{if(s.get(h)!==x||x.gen!==b){try{R&&R.remove&&R.remove()}catch{}return null}return x.pending=null,x.handle=R||null,x.priority=null,p(h,x),R&&typeof R.setConvergence=="function"&&R.setConvergence(ve(a)),x.handle},R=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(R&&R.message||R).slice(0,200)}),y&&y(R),null)),x.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()])m.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,u]of s)p(d,u)},setVisible(h,d){let u=s.get(h);!u||u.visible===!!d||(u.visible=!!d,p(h,u))},setDepth(h){a=h;let d=ve(h);for(let u of s.values())u.handle&&typeof u.handle.setConvergence=="function"&&u.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 m}var bn=null;function Ri(r){bn=typeof r=="function"?r:null}var xn=new WeakMap;function Ci(r,e){r&&(typeof r=="object"||typeof r=="function")&&xn.set(r,e)}gt();var Ti=new WeakMap,J;function Di(r){let e=null;for(let[t,i]of r)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function Sn(r){if(!r||typeof r.getParameter!="function")return null;let e=Ti.get(r);if(e)return e;let t,i,n;try{t=r.getParameter(r.MAX_TEXTURE_SIZE??3379),i=r.getParameter(r.MAX_RENDERBUFFER_SIZE??34024),n=r.getParameter(r.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=n&&n.length>=2?n[0]:0,o=n&&n.length>=2?n[1]:0,a=Di([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=Di([["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 Ti.set(r,c),c}function Li(){if(J!==void 0)return J;J=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return J;let r=document.createElement("canvas"),e=r.getContext("webgl2")||r.getContext("webgl");if(!e)return J;J=Sn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function Ai(r,e,t,{cols:i=2,rows:n=1}={}){let s=r*i,o=e*n,a={eyeW:r,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(r>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 m=l<=c,h=Math.max(1,Math.min(Math.floor(r*p+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*p+1e-9),Math.floor(t.maxH/n)));return{eyeW:h,eyeH:d,cols:i,scale:p,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*n,limitName:m?t.nameW:t.nameH,limitValue:m?t.valueW:t.valueH}}function _t(r){return Math.round(r*1e3)/1e3}function Oi(r,e,t){let i=typeof t=="number"?` (renderScale ${_t(t)} \u2192 ${_t(t*e.scale)})`:` (scale ${_t(e.scale)})`;return`${r} ${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 Pi(r,e){let t=r?.width||0,i=r?.height||0,n=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?n/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:n,h:s,mismatch:o!==1||a!==1}}function Ii(r,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${r} 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 re="smoothstep",vt=["linear","smoothstep","easeoutcubic"];function wt(r){if(typeof r!="string")return null;let e=r.toLowerCase().replace(/[-_\s]/g,"");return vt.includes(e)?e:null}function Mn(r,e){if(e<=0)return 0;if(e>=1)return 1;if(r==="linear")return e;if(r==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var ie="idle",Fi="rampDownThenFire",yt="fireThenRampUp",Ie=class{constructor(e,t){this._phase=ie,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=re,(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=wt(t)||re),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:n,current:s,steady:o=1}={}){let a=!(t>1),l=!(n>1),c=Number.isFinite(o)?o:1,p=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=p,a&&!l?(this._phase=Fi,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=yt,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=yt,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!==ie){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)*Mn(this._easing,this._t),this._phase===yt?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=ie)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=ie)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==ie}value(){return this._cur}firePending(){return this._phase===Fi?this._fireAtEnd:this._firePending}cancel(){return this._phase=ie,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var B=null;Ri(r=>{let e=B;if(!e||!e._running||!r)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===r&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof r.contains=="function"&&r.contains(i.canvas))return t(i);for(let i of e._windows.values()){let n=i.canvas.parentElement;if(i.layer&&n&&typeof n.contains=="function"&&n.contains(r))return t(i)}return null});var En=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Fe=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,bt=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Rn=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Xi=["renderingmodechange","hardwaredisplaystatechange"],Dt="trackingstatechange",Gi=["unknown","tracking","searching"],ji=[...Xi,Dt];function We(r){try{let e=r?r.trackingState:void 0;return Gi.includes(e)?e:null}catch{return null}}var xt=()=>{if(!Q())return!1;try{let r=window.XRDisplayLayer.prototype;return Rn.every(e=>typeof r[e]=="function")}catch{return!1}},St=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},se=null;function ne(){if(se!==null)return se;if(!Q())return!1;try{let r=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof r=="boolean")return se=r}catch{}return!1}function Cn(r){if(se!==null)return se;if(!r||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return se=!!r.occlusionByDrawOrder}catch{return null}}var Ni=!1;function Mt(){Ni||(Ni=!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 Ji(){return En()&&Q()}function Et(r){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:r.virtualDisplayHeight>0?r.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function kn(r,e){let t=Number.isFinite(r.ipdFactor)?r.ipdFactor:1,i=Number.isFinite(r.parallaxFactor)?r.parallaxFactor:1;return{...r,ipdFactor:t*e,parallaxFactor:i*e}}var Tn=16;function N(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Lt=1200,Dn=new Set(["pending","woven","withheld"]),zi=3,Ln=new Set(["getDisplayInfo","getRenderingModes","requestRenderingMode"]),An=new Set(["getDisplayInfo","getRenderingModes"]);function On(r){return r==null||Array.isArray(r)&&r.length===0}function Rt(){try{let r=typeof XRDisplayLayer=="function"?XRDisplayLayer:null;return!!(r&&r.prototype&&"wovenState"in r.prototype)}catch{return!1}}function je(r){try{let e=r?r.wovenState:null;return Dn.has(e)?e:null}catch{return null}}function Ct(r){try{let e=r?r.withheldReason:null;return typeof e=="string"&&e?e:null}catch{return null}}var Hi=!1;function Pn(r){if(r==null)return re;let e=wt(r);return e||(Hi||(Hi=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(r)} } }) is not a curve this SDK knows (${vt.join(" / ")}); using '${re}'.`)),re)}var $i=!1;function In(){$i||($i=!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 At(r){return r&&r.detail!==void 0&&r.detail!==null?r.detail:void 0}function Yi(r){let e=At(r);return e!==void 0?[e,r]:[r]}function Fn(r){for(let e of Yi(r)){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 Wn(r){for(let e of Yi(r)){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 Vi=!1;function jn(){Vi||(Vi=!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 Ui=!1;function Nn(){Ui||(Ui=!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(r={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:n=!0,modeSwitch:s=null,untrackedFallback:o="none",viewerEase:a}=r;if(!Ji())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(p){return{supported:!1,trackingState:"unknown",error:p}}a!==void 0&&Ci(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new Ot(l,c,{lazy:t,rootMargin:i,autoChrome:n,modeSwitch:s,untrackedFallback:o})}var be=null;function ze(r={}){return B&&B._running?Promise.resolve(B):be||(be=Ki(r).finally(()=>{be=null}),be)}var Bi=.7,zn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function Hn(r){let e=[],t=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(zn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let n of i.childNodes)if(n.nodeType===Node.TEXT_NODE&&n.nodeValue.trim()){e.push(i);break}}return e}var kt=4;function Tt(r){let e=typeof window<"u"&&window.devicePixelRatio||1,t="";if(typeof r.getBoundingClientRect=="function"){let i=r.getBoundingClientRect()||{},n=typeof window<"u"&&window.scrollX||0,s=typeof window<"u"&&window.scrollY||0;t=`+${Math.round((i.left??i.x??0)+n)},${Math.round((i.top??i.y??0)+s)}`}return`${r.clientWidth}x${r.clientHeight}@${e}${t}`}function qi(r){let e=typeof window<"u"&&window.devicePixelRatio||1;return{width:r.clientWidth||0,height:r.clientHeight||0,dpr:e}}function $n(r){if(r==null||r===!1||r==="off")return null;if(r==="auto"||r===!0)return{color:"#000",snapshot:!0};if(typeof r=="object"){if(r.color!==void 0&&typeof r.color!="string")throw new TypeError("[inline3d] rectCover.color must be a CSS color string.");return{color:r.color||"#000",snapshot:r.snapshot!==!1}}throw new TypeError(`[inline3d] rectCover: expected 'auto', 'off' or { color?, snapshot? }; got ${JSON.stringify(r)}.`)}var Ot=class{constructor(e,t,{lazy:i,rootMargin:n,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._claims=new Map,this._doubleWarned=new WeakSet,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 Ie((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,Pn(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=We(e)!==null,this._trackingState=this._trackingSupported?We(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=St()?{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:n}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,B&&B._running&&B!==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."),B=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))){ne()&&Mt(),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(ne()||!this._autoChrome||!Fe()||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,n=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of n){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 Hn(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={}){this._warnDoubleAttach(e,"addImage",i._dxrClaim);let n=this._register(e,"image",i);return n.method="addImage",n.ready=Un(t).then(s=>{n.img=s,n.repaint()}),this._handle(e,n)}addVideo(e,t,i={}){this._warnDoubleAttach(e,"addVideo",i._dxrClaim);let n=this._register(e,"video",i);return n.method="addVideo",n.video=t,this._handle(e,n)}addScene(e,t,i={}){this._warnDoubleAttach(e,"addScene",i._dxrClaim),i.viewRig&&i.virtualDisplayHeight!==void 0&&Nn();let n=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return n.method="addScene",n.onFrame=t,n.ownsBuffer=!1,i.bufferClamped===!0&&(n.warnedBufMismatch=!0),this._handle(e,n)}_liveRegistration(e,t){let i=this._claims.get(e);if(i&&i.token!==t)return i.method;let n=this._windows.get(e);return n?n.method||"add*":null}_warnDoubleAttach(e,t,i){let n=this._liveRegistration(e,i);!n||this._doubleWarned.has(e)||(this._doubleWarned.add(e),console.warn(`[inline3d] ${t}() on a canvas that is already registered on this inline-3D session (by ${n}(), not yet removed). This call is rebuilding the canvas's layer (a fresh 0.4-1.2 s identity gap) or putting a second renderer on its context. Change what is IN the canvas instead (setSource, your onFrame, a redrawn source canvas), or call handle.remove() on the first registration first. (Warned once per canvas.)`,e))}_attachGuard(e,t,i={}){let n=this._claims.get(e);if(i&&i._dxrClaim&&n&&n.token===i._dxrClaim)return{opts:i,own:()=>{}};this._warnDoubleAttach(e,t,null);let s={};return{opts:{...i,_dxrClaim:s},own:o=>this._claim(e,t,o,s)}}_claim(e,t,i,n){if(!this._running||!i||typeof i!="object")return;let s={token:n,method:t};this._claims.set(e,s);let o=i.remove,a=(...l)=>(this._claims.get(e)===s&&this._claims.delete(e),typeof o=="function"?o.apply(i,l):void 0);Object.defineProperty(i,"remove",{configurable:!0,enumerable:!0,get:()=>a,set:l=>{o=l}})}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:n=>{n&&(ne()&&Mt(),t.excluded.add(n),this._applyExclusion(t,n))},unexclude:n=>{!n||!t.excluded.delete(n)||this._dropExclusion(t,n)},get trackingState(){return i._trackingState},setViewRig:n=>(t.viewRig=n||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let n=null;try{n=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return ki(n,e.getBoundingClientRect(),globalThis.devicePixelRatio||1)},getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:n=>this._requestRenderingModeEased(n,t),setStereoEnabled:n=>this._setStereoEnabled(n,t),on:(n,s)=>this.on(n,s),off:(n,s)=>this.off(n,s),onDisplayModeChange:n=>this._onDisplayModeChange(n),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get wovenState(){return Rt()?t.layer?je(t.layer):"pending":null},get withheldReason(){return!Rt()||!t.layer?null:je(t.layer)==="withheld"?Ct(t.layer):null},get firstWoven(){return t.fwPromise},onFirstWoven:n=>{if(typeof n!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{n(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?Et(e):null):(e.viewRig||(e.stereoSynthRig=!0),kn(e.viewRig||Et(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&In(),!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 n=i.viewRig||Et(i);i.stereoSaved={ipdFactor:n.ipdFactor,parallaxFactor:n.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!bt())return jn(),!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,n=[]){if(!xt())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 }.`));if(Ln.has(t)&&!e.layerFramed&&this._layerReadPending(e))return this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n));let o;try{o=Promise.resolve(e.layer[t](...n))}catch(l){return Promise.reject(l)}if(!An.has(t)||!this._layerReadPending(e))return o;let a=e.layer;return o.then(l=>e.layer!==a?l:On(l)?this._layerReadPending(e)?this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n)):l:(e.lfAnswered=!0,l))}_layerFramedCap(e){return kt*Math.max(e.fwHoldMs,Lt)}_layerReadPending(e){return!e.layer||e.lfAnswered||e.lfCapped?!1:N()-e.lfAt>=this._layerFramedCap(e)?(e.lfCapped=!0,!1):!0}_whenLayerFramed(e){return new Promise(t=>{let i=e.layer,n={resolve:t,timer:null},s=Math.max(0,this._layerFramedCap(e)-(N()-e.lfAt));n.timer=setTimeout(()=>{let o=e.framedWaiters.indexOf(n);o>=0&&e.framedWaiters.splice(o,1),e.layer===i&&(e.lfCapped=!0),t()},s),n.timer&&typeof n.timer.unref=="function"&&n.timer.unref(),e.framedWaiters.push(n)})}_tickLayerFramed(e){let t=e.wsLive?je(e.layer):null;(t?t==="woven":e.lfStereo)?this._noteLayerFramed(e,!0):e.framedWaiters.length&&!this._layerReadPending(e)&&this._noteLayerFramed(e,!1)}_noteLayerFramed(e,t=!0){t&&(e.layerFramed=!0);let i=e.framedWaiters.splice(0);for(let n of i)clearTimeout(n.timer),n.resolve()}_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 n=i.find(s=>s.isActive);return n&&(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.viewCount,(n.viewCount===1||n.viewCount===2)&&this._setStereoCollapsed(n.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||!bt())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 n=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=n&&Number.isFinite(n.viewCount)?n.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((n,s)=>{i.resolve=n,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 n=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=n?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 n=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.`);n.name=e,i.reject(n)}_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 n of this._windows.values())this._pushViewRig(n)}if(i.fire&&this._msFire){let n=this._msFire;this._msFire=null,this._requestRenderingMode(n.modeIndex,n.win).then(s=>n.resolve(s),s=>{this._startUpRamp(),n.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())},Tn))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,n=await this._getRenderingModes(t),s=Array.isArray(n)?n:[],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"||xt()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=Wn(e),i=At(e),n=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&n(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;n(c)}}).catch(()=>{t||n(null)})}async _onRenderingModeChange(e){let t=At(e),i=Fn(e),n=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];n=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}n?(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.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:n,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let n=t||[e];for(let s of[...i])try{s(...n)}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(!ji.includes(e))throw new TypeError(`[inline3d] on() knows ${ji.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=Xi.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!St())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 n={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,onResize:t==="scene"&&typeof i.onResize=="function"?i.onResize:null,resizeBox:null,inResize:!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(n,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:Vn(i.firstWovenHoldMs),fwRegAt:N(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null,wsLive:!1,rc:null,layerFramed:!1,lfAnswered:!1,lfStereo:!1,lfAt:0,lfCapped:!1,framedWaiters:[]},s=$n(i.rectCover);return s&&(n.rc={cfg:s,box:null,el:null,up:!1,snapped:!1,snapWanted:!1,waiting:null,w:0,h:0}),n.fwPromise=new Promise(o=>{n.fwResolve=o}),this._windows.set(e,n),this._lazy&&this._observer?this._observer.observe(n.observeEl):this._activate(n),n}_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"),this._dropCover(t))}_onIntersect(e){for(let t of e){let i=null;for(let n of this._windows.values())if(n.observeEl===t.target){i=n;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=bt()?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),e.wsLive=Rt(),e.layerFramed=!1,e.lfAnswered=!1,e.lfStereo=!1,e.lfCapped=!1,e.lfAt=N(),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&xt()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),St()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),Cn(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._noteLayerFramed(e,!1),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(),n=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=n.width*n.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,n.right)-Math.max(i.left,n.left),l=Math.min(i.bottom,n.bottom)-Math.max(i.top,n.top);if(a<=0||l<=0)return!1;let c=a*l;return c/s<Bi||c/o<Bi?!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(ne()||!e.layer||!Fe()||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 n=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=n,t.dataset.inline3dIsolated="1"}try{e.layer.excludeElement(t)}catch{}}_dropExclusion(e,t){if(ne())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Fe()))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&&Mt()}_startOverlayScan(e){if(ne()||!Fe()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let n=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)n.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of n)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),n=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/n,a.h/s);c<1&&(o=c,n=Math.max(1,Math.round(n*c)),s=Math.max(1,Math.round(s*c)))}let l=Ai(n,s,Li(),{cols:t?2:1});return l.clamped&&(o*=l.scale,n=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(Oi("[inline3d]",l)))),e.bufScale=o,{w:n,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,n=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(n>0)?null:{w:i/2,h:n}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let n=null;try{n=t.getContext("webgl2")||t.getContext("webgl")}catch{n=null}e.sceneGl=n&&typeof n.drawingBufferWidth=="number"?n:null}if(!e.sceneGl)return;let i=Pi(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(Ii("[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:n}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=n,e.canvas.width=t?i*2:i,e.canvas.height=n,e.sbs=t}_startSizeWatch(e){if(typeof ResizeObserver=="function"&&!e.sizeObserver){if(e.kind==="scene"){if(!e.onResize)return;e.resizeBox=qi(e.canvas),e.sizeObserver=new ResizeObserver(()=>this._onSceneResize(e)),e.sizeObserver.observe(e.canvas);return}!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas))}}_onSceneResize(e){if(!e.layer||!e.onResize||e.inResize)return;let t=qi(e.canvas),i=e.resizeBox;if(!(i&&i.width===t.width&&i.height===t.height&&i.dpr===t.dpr)){e.resizeBox=t,e.inResize=!0;try{e.onResize(t)}catch(n){e.resizeThrewWarned||(e.resizeThrewWarned=!0,console.warn("[inline3d] a scene window's onResize threw; further throws from it are silent.",n))}finally{e.inResize=!1}}}_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:n}=this._eyeSize(e);i===e.eyeW&&n===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 n=e.kind==="video"?e.video:e.img;if(!n)return;if(e.kind==="video"&&(n.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=n.videoWidth||n.naturalWidth||n.width,l=n.videoHeight||n.naturalHeight||n.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:f,h:y}=this._eyeSize(e,e.sbs);(f!==e.eyeW||y!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let p=e.bufScale||1,m=e.cornerRadius*p,h=e.feather*p;if(o.clearRect(0,0,s.width,s.height),!e.sbs){Ne(o,n,0,0,a/2,l,0,0,s.width,s.height,m,h);return}let d=s.width/2,u=Math.min(this._stereoFactor,this._bakedStereo);if(u<1){Ne(o,n,0,0,a/2,l,0,0,d,s.height,m,h),Bn(o,n,a/2,l,d,s.height,u,m,h);return}m>0||h>0?(Ne(o,n,0,0,a/2,l,0,0,d,s.height,m,h),Ne(o,n,a/2,0,a/2,l,d,0,d,s.height,m,h)):o.drawImage(n,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(Dt,()=>{this._setTrackingState(We(e)||"unknown")})}_setTrackingState(e){let t=Gi.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:Dt,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(We(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,n=this._bakedTarget;if(i===n)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=n>i?Math.min(n,i+s):Math.max(n,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,n)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,n))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,n=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.rc&&this._rectCoverCheck(s),s.kind==="scene"){if(n&&s.onFrame){if(s.frames++,n.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(n,s.layer,t),n.length>=2&&(s.fwStereo=!0,s.lfStereo=!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,n),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.lfStereo=!0,s.rw&&(s.rw.stereo=!0));s.rc&&s.rc.snapWanted&&this._rectCoverSnap(s),(!s.layerFramed||s.framedWaiters.length)&&this._tickLayerFramed(s),this._tickFirstWoven(s)}}_tickFirstWoven(e){let t=e.wsLive&&e.layer?je(e.layer):null;if(t){this._tickWovenState(e,t);return}if(e.rw){this._noteRewovenBox(e);let i=e.rw,n=N();i.stereo&&n-i.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):i.at>i.calledAt&&n-i.calledAt>=kt*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")}_tickWovenState(e,t){let i=N(),n=kt*Math.max(e.fwHoldMs,Lt);if(e.rw){this._noteRewovenBox(e);let s=e.rw;t!=="woven"?s.gap=!0:s.stereo&&(s.gap||s.boxFrame!==null&&this._frameCount-s.boxFrame>=zi||s.boxFrame===null&&this._frameCount-s.callFrame>=zi)&&this._settleRewoven(e,!0,"woven",!0),e.rw&&i-s.calledAt>=n&&(t==="woven"?this._settleRewoven(e,!0,"hold-capped",!0):this._settleRewoven(e,!1,Ct(e.layer)||t,!0))}e.fwResult||e.fwLayerAt===null||(e.fwStereo&&t==="woven"?this._settleFirstWoven(e,!0,"woven",!0):i-e.fwLayerAt>=n&&(t==="woven"?this._settleFirstWoven(e,!0,"hold-capped",!0):this._settleFirstWoven(e,!1,Ct(e.layer)||t,!0)))}_settleFirstWoven(e,t,i,n=!1){!t&&!n&&(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:n,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&&!e.fwResult.confirmed)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}),n=N();return e.rw={promise:i,resolve:t,calledAt:n,at:n,stereo:!1,box:Tt(e.canvas),gap:!1,boxFrame:null,callFrame:this._frameCount},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=Tt(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=N(),e.rw.stereo=!1,e.rw.gap=!1,e.rw.boxFrame=this._frameCount)}_settleRewoven(e,t,i,n=!1){let s=e.rw;s&&(e.rw=null,s.resolve(Object.freeze({woven:t,confirmed:n,reason:i,ms:Math.round(N()-s.calledAt)})))}_rectCoverCheck(e){let t=e.rc,i=Tt(e.canvas);if(i===t.box)return;let n=t.box===null,s=t.w,o=t.h;if(t.box=i,t.w=e.canvas.clientWidth||0,t.h=e.canvas.clientHeight||0,n)return;t.up&&this._placeCover(e);let a=e.fwResult;if(!a||e.rwGone||!(a.woven||a.confirmed))return;t.up||(t.snapped||(t.aspect=o>0?s/o:0),this._raiseCover(e)),t.cfg.snapshot&&!t.snapped&&t.w>0&&t.h>0&&(t.snapWanted=!0);let l;e.rw?(this._noteRewovenBox(e),l=e.rw.promise):(l=this._rewoven(e),e.rw&&(e.rw.boxFrame=this._frameCount)),t.waiting!==l&&(t.waiting=l,l.then(()=>{t.waiting===l&&(t.waiting=null,this._lowerCover(e))}))}_raiseCover(e){let t=e.rc;if(!t.el){if(typeof document>"u"||!document||typeof document.createElement!="function"||!e.canvas.parentElement)return;let i=document.createElement("canvas");i.setAttribute?.("aria-hidden","true"),i.dataset&&(i.dataset.inline3dCover="");let n=i.style;n.position="absolute",n.pointerEvents="none",n.margin="0",n.border="0",n.padding="0",n.background=t.cfg.color,n.display="none";try{let s=typeof getComputedStyle=="function"?getComputedStyle(e.canvas).zIndex:"auto";s&&s!=="auto"&&(n.zIndex=s)}catch{}t.el=i}this._placeCover(e),t.el.style.display="block",t.up=!0,this._fullTileWarned.add(t.el),this._applyExclusion(e,t.el)}_placeCover(e){let i=e.rc.el,n=e.canvas;if(!i)return;let s=n.parentElement;s&&(i.parentElement!==s||i.previousSibling!==n)&&s.insertBefore(i,n.nextSibling);let o=i.style;if(n.offsetParent)o.position="absolute",o.left=`${n.offsetLeft}px`,o.top=`${n.offsetTop}px`,o.width=`${n.offsetWidth}px`,o.height=`${n.offsetHeight}px`;else{let a=n.getBoundingClientRect();o.position="fixed",o.left=`${a.left??a.x??0}px`,o.top=`${a.top??a.y??0}px`,o.width=`${a.width}px`,o.height=`${a.height}px`}}_rectCoverSnap(e){let t=e.rc;t.snapWanted=!1;let i=t.el,n=e.canvas;if(!i||!t.up||!(n.width>1)||!(n.height>0))return;let s=Math.max(1,Math.round(t.w)),o=Math.max(1,Math.round(t.h)),a=s/o,l=t.aspect>0?t.aspect:n.width/2/n.height,c=1,p=1;a>l?p=l/a:c=a/l;let m=n.width/2*c,h=n.height*p,d=(n.width/2-m)/2,u=(n.height-h)/2;try{i.width=s,i.height=o;let f=i.getContext("2d");if(!f)return;f.drawImage(n,d,u,m,h,0,0,s,o),t.snapped=!0}catch{}}_lowerCover(e){let t=e.rc;t&&(t.up=!1,t.snapped=!1,t.snapWanted=!1,t.el&&(t.el.style.display="none",this._dropExclusion(e,t.el)))}_dropCover(e){let t=e.rc;t&&(t.waiting=null,this._lowerCover(e),t.el&&t.el.parentElement&&t.el.parentElement.removeChild(t.el),t.el=null)}_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,B===this&&(B=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._dropCover(e),this._noteLayerFramed(e,!1)}this._windows.clear(),this._claims.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function Vn(r){return typeof r=="number"&&Number.isFinite(r)&&r>=0?r:Lt}function Un(r){return typeof r!="string"?Promise.resolve(r):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=r})}function Ne(r,e,t,i,n,s,o,a,l,c,p,m){p>0&&r.roundRect?(r.save(),r.beginPath(),r.roundRect(o,a,l,c,p),r.clip(),r.drawImage(e,t,i,n,s,o,a,l,c),r.restore()):r.drawImage(e,t,i,n,s,o,a,l,c),m>0&&Zi(r,o,a,l,c,m)}function Bn(r,e,t,i,n,s,o,a,l){r.save(),a>0&&r.roundRect&&(r.beginPath(),r.roundRect(n,0,n,s,a),r.clip()),r.drawImage(e,0,0,t,i,n,0,n,s),o>0&&(r.globalAlpha=o,r.drawImage(e,t,0,t,i,n,0,n,s)),r.restore(),l>0&&Zi(r,n,0,n,s,l)}function Zi(r,e,t,i,n,s){let o=Math.min(s,Math.floor(Math.min(i,n)/2));if(o<=0)return;r.save(),r.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+n-o,i,o,[e,t+n],[e,t+n-o]],[e,t,o,n,[e,t],[e+o,t]],[e+i-o,t,o,n,[e+i,t],[e+i-o,t]]];for(let[l,c,p,m,h,d]of a){let u=r.createLinearGradient(h[0],h[1],d[0],d[1]);u.addColorStop(0,"rgba(0,0,0,1)"),u.addColorStop(1,"rgba(0,0,0,0)"),r.fillStyle=u,r.fillRect(l,c,p,m)}r.restore()}function oe(r,e){return r>0&&e>0&&r/e>2.5}function V(r,e,t,i,n){let s=Math.abs(i||0),o=Math.min(r-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(r-o)/2+(n===0?i:-i);return{sx:Math.max(0,Math.min(r-o,l)),sy:(e-a)/2,sw:o,sh:a}}function xe(r,e,t){let i=Math.min(r,e*t),n=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(n/2)*2)}}function ae(r,e){let t=r/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 Pt(r,e,t){let i=new r.constructor(r.length);for(let n of ae(e,t))for(let s=0;s<t;s++)for(let o=0;o<n.dw;o++){let a=n.sx+(n.sw-1-o);i[s*e+n.dx+o]=r[s*e+a]}return i}function Qi(r,e){return!(r>0)||!(e>0)||e>=180?null:r/2/Math.tan(e/2*Math.PI/180)}function He({eyeWidthPx:r,hfovDeg:e,baselineMm:t,subjectZmm:i}){let n=Qi(r,e);return n===null||!(t>0)||!(i>0)?0:n*t/(2*i)}function $e(r,e,t=.12){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,r||0))}function Ve(r,e,t=.2){let i=r+t*(e-r);return Math.abs(e-i)<.05?e:i}function Se(){let r={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=r.measuredPx!==null?r.measuredPx/2:r.hello&&r.subjectZmm?He({eyeWidthPx:e,hfovDeg:r.hello.hfovDeg,baselineMm:r.hello.baselineMm,subjectZmm:r.subjectZmm}):0;return $e(t+r.depth*.05*e,e)},step(e){return r.current=Ve(r.current,r.target(e)),r.current}};return r}var Ue=1,It="inline3d-call/1",er=Object.freeze(["sbs","mono"]),le=4,tr=4,Ft=5,qn=150,Xn=5e3,Gn=/^[A-Za-z0-9_-]{16,64}$/,Jn=16;function Wt(r){let e=new Uint8Array(Jn);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),rr(e)}function ir(r){let e=new Uint8Array(8);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),rr(e)}function rr(r){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<r.length;i+=3){let s=r[i]<<16|r[i+1]<<8|r[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let n=r.length-i;if(n===1){let s=r[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(n===2){let s=r[i]<<16|r[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function ce(r){return typeof r=="string"&&Gn.test(r)}function Me(r){if(!r)return null;let e="";if(typeof r=="object")e=r.hash||r.href&&String(r.href).split("#")[1]||"";else{let t=String(r),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 n=decodeURIComponent(t.slice(i+1));return ce(n)?n:null}return null}function Be(r,e){if(!ce(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(r||"").split("#")[0]}#room=${e}`}function jt(r){if(!r||typeof r!="object"||r.type!=="hello")return null;let e=(t,i,n)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=n?t:null;return{type:"hello",v:typeof r.v=="number"?r.v:Ue,format:er.includes(r.format)?r.format:"mono",width:e(r.width,1,16384),height:e(r.height,1,16384),baselineMm:e(r.baselineMm,1,1e3),hfovDeg:e(r.hfovDeg,5,170),rectified:r.rectified===!0,sdk:typeof r.sdk=="string"?r.sdk.slice(0,64):null}}function Nt({format:r,width:e,height:t,baselineMm:i,hfovDeg:n,rectified:s}={}){let o={type:"hello",v:Ue,format:er.includes(r)?r:"mono",width:e||0,height:t||0,rectified:!!s,sdk:It};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(n)&&(o.hfovDeg=n),o}function zt(r){if(!r||r.type!=="hint")return null;let e=r.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=qn&&e<=Xn?{type:"hint",subjectZmm:e}:null}function nr(r){return!r||r.type!=="state"?null:{type:"state",muted:r.muted===!0,cameraOff:r.cameraOff===!0,speaking:r.speaking===!0}}function Ht(r){let e=1e3/r,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function $t({format:r,woven:e,mono3D:t="auto",lift:i=!1,overBudget:n=!1,failed:s=!1}){return(r==="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"}:n?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function Vt(r){return r==="woven-sbs"?"3D":r==="lifted"?"2D\u21923D":"2D"}function Ut({need:r=10,needNoPose:e=30}={}){let t=0,i=0,n=!1;return{feed(s){return n?!0:(i++,s===null?n=i>=e:(t=s>=1?t+1:0,n=t>=r),n)},get live(){return n}}}function qe(r,e){let t=Math.max(1,e|0),n=r==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return n[Math.min(t,n.length)-1]}function q(r,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let n=Math.min(t,e*Math.pow(2,Math.max(0,r)));return Math.round(n*(.8+.4*i()))}var Ee=Object.freeze(["VP9","VP8","AV1"]);function Kn(r,e=Ee){let t=e.indexOf(String(r||"").toUpperCase());return t<0?e.length:t}function Xe(r,e=Ee){let t=i=>Kn(String(i.mimeType||"").split("/")[1],e);return r.map((i,n)=>({c:i,i:n,r:t(i)})).sort((i,n)=>i.r-n.r||i.i-n.i).map(i=>i.c)}function Re(r,e=Ee){if(!r)return r;let t=r.includes(`\r
|
|
1
|
+
/* @displayxr/inline3d 1.42.1 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
|
|
2
|
+
var _n=Object.defineProperty;var _e=(r,e)=>()=>(r&&(e=r(r=0)),e);var yn=(r,e)=>{for(var t in e)_n(r,t,{get:e[t],enumerable:!0})};function Ti(r,e,t=1){let i=Pe,n=!!r&&r.displayWidthMeters>0&&r.displayHeightMeters>0&&r.displayPixelWidth>0&&r.displayPixelHeight>0,s=n?[r.displayWidthMeters,r.displayHeightMeters]:[...i.displaySizeM],o=n?[r.displayPixelWidth,r.displayPixelHeight]:[...i.displayPixels],a=(s[0]/o[0]+s[1]/o[1])/2,l=t>0?t:1,c=n?a*l:a*(o[1]/Math.max(1,globalThis.innerHeight||o[1])),f=r?.nominalViewerPosition?.z,m=Number.isFinite(f)&&f>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:m?f:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:n?"display":"default",viewer:m?"display":"default",eyeSeparation:"default"}}}var Pe,gt=_e(()=>{"use strict";Pe=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063})});function Ge(r,e,t,i,n,s,o,a,l,c,f){if(s<0||s+a>t||o<0)return-1;let m=0,h=0,d=0,u=a*l;for(let w=0;w<l;w++){let b=(n+w)*e+i,T=(o+w)*e+t+s;for(let x=0;x<a;x++){let P=r[T+x];m+=P,h+=P*P,d+=r[b+x]*P}}let p=m/u,y=h/u-p*p;return y<1?-1:(d/u-c*p)/(f*Math.sqrt(y))}function us(r,e,t,i,n,s){let o=0,a=0;for(let f=0;f<s;f++){let m=(i+f)*e+t;for(let h=0;h<n;h++){let d=r[m+h];o+=d,a+=d*d}}let l=n*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function he(r,e,t,i,n,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:f}={}){let m=e/2,{mean:h,std:d}=us(r,e,i,n,s,o);if(d<6)return null;let u=-2,p=0,y=0,w=new Map,b=(M,g,v,_,S)=>{for(let D=_;D<=S;D++){let E=n+D;if(!(E<0||E+o>t))for(let F=M;F<=g;F+=v){let H=Ge(r,e,m,i,n,i-F,E,s,o,h,d);H>(w.get(F)??-2)&&w.set(F,H),H>u&&(u=H,p=F,y=D)}}},T=l-a>8;if(b(a,l,T?2:1,-c,c),T&&u>-1){let M=p,g=y;b(Math.max(a,M-2),Math.min(l,M+2),1,Math.max(-c,g-1),Math.min(c,g+1))}if(u<-1)return null;let x=-2,P=M=>{let g=-2;for(let v=-c;v<=c;v++){let _=n+v;if(!(_<0||_+o>t))for(let S=M-1;S<=M+1;S++)g=Math.max(g,Ge(r,e,m,i,n,i-S,_,s,o,h,d))}return g};for(let[M,g]of w){if(Math.abs(M-p)<3||g<=x)continue;let _=g>=(w.get(M-2)??-2)&&g>=(w.get(M+2)??-2)&&g>0?P(M):g;_>x&&(x=_)}if(l-a>12&&x>-2&&u-x<(f??.08))return null;let C=Ge(r,e,m,i,n,i-(p-1),n+y,s,o,h,d),O=Ge(r,e,m,i,n,i-(p+1),n+y,s,o,h,d),I=0,L=C-2*u+O;return C>-1&&O>-1&&L<0&&(I=Math.max(-.5,Math.min(.5,.5*(C-O)/L))),{d:p+I,dy:y,c:u}}function fs(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.step||s,a=i.dMax??Math.round(n*.3),l=i.dMin??-Math.round(n*.05),c=Math.round(n*(i.roiX0??.15)),f=Math.round(n*(i.roiX1??.85))-s,m=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,d=[];for(let u=m;u<=h;u+=o)for(let p=c;p<=f;p+=o){let y=he(r,e,t,p,u,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});y&&y.c>=(i.minNcc??.8)&&d.push({x:p,y:u,...y})}return d}function ps(r,{tol:e=2,relTol:t=.1,minFrac:i=.12,minBlocks:n=3}={}){if(!r.length)return null;let s=Math.max(n,Math.ceil(r.length*i)),o=r.map(a=>a.d).sort((a,l)=>l-a);for(let a of o){let l=Math.max(e,t*Math.abs(a)),c=r.filter(f=>Math.abs(f.d-a)<=l);if(c.length>=s){let f=c.map(m=>m.d).sort((m,h)=>m-h);return{d:f[f.length>>1],members:c}}}return null}function ms(r,e){let t=Math.min(...r.map(l=>l.y)),n=r.filter(l=>l.y<=t+2*e).map(l=>l.x),s=Math.min(...n),o=Math.max(...n)+e,a=o-s;return{x:(s+o)/2,y:t+.4*1.3*a}}function Xt(r,e,t,i={}){let n=e/2,s=i.block||Math.max(8,Math.round(n/20)),o=i.dMax??Math.round(n*.3),a=i.dMin??-Math.round(n*.05),l=i.focus||null,c="focus",f=0,m=null;if(!l){let T=fs(r,e,t,{...i,block:s,dMax:o,dMin:a});f=T.length;let x=ps(T,i);if(!x)return null;l=ms(x.members,s),m=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),d=Math.round(s*(i.refineH??1.5)),u=Math.round(Math.max(0,Math.min(n-h,l.x-h/2))),p=Math.round(Math.max(0,Math.min(t-d,l.y-d/2))),y=m===null?a:Math.max(a,Math.floor(m)-4),w=m===null?o:Math.min(o,Math.ceil(m)+4),b=he(r,e,t,u,p,h,d,{dMin:y,dMax:w,dyMax:i.dyMax??2});return b&&b.c>=(i.minNcc??.8)?{d:b.d,x:l.x,y:l.y,c:b.c,method:c,blocks:f}:m!==null?{d:m,x:l.x,y:l.y,c:0,method:c,blocks:f}:null}function Je(r,e){let t=new Uint8Array(e);for(let i=0,n=0;i<e;i++,n+=4)t[i]=r[n]*77+r[n+1]*150+r[n+2]*29>>8;return t}function Ye({n:r=3}={}){let e=[],t={value:null,push(i){if(i===null||!Number.isFinite(i))return t.value;e.push(i),e.length>r&&e.shift();let n=[...e].sort((s,o)=>s-o);return t.value=n[n.length>>1],t.value},reset(){e.length=0,t.value=null}};return t}function ur(r,e,t,i,n,s){let o=new Float32Array(n*s);for(let a=0;a<s;a++)for(let l=0;l<n;l++)o[a*n+l]=r[(i+a)*e+t+l];return o}function gs(r,e,t,i,n,s,o,a,l,c){let f=e/2,m=n*s,h=0,d=0;for(let b=0;b<m;b++)h+=i[b],d+=i[b]*i[b];h/=m;let u=Math.sqrt(Math.max(1e-6,d/m-h*h)),p=-2,y=o,w=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let T=Math.max(0,o-l);T<=Math.min(f-n,o+l);T++){let x=0,P=0,C=0;for(let M=0;M<s;M++){let g=(b+M)*e+T;for(let v=0;v<n;v++){let _=r[g+v];x+=_,P+=_*_,C+=_*i[M*n+v]}}let O=x/m,I=P/m-O*O;if(I<1)continue;let L=(C/m-O*h)/(Math.sqrt(I)*u);L>p&&(p=L,y=T,w=b)}return{x:y,y:w,c:p}}function De({fullEveryMs:r=2e3,dWin:e=4,rx:t=12,ry:i=8,minTrackNcc:n=.75,jump:s=8}={}){let o=null,a=null;return{measure(c,f,m,h,d={}){let u=f/2,p=d.block||Math.max(8,Math.round(u/20)),y=Math.round(p*3),w=Math.round(p*1.5),b=null;if(o&&o.w===y&&o.h===w){let O=gs(c,f,m,o.tpl,y,w,o.x,o.y,t,i);if(O.c>=n){let I=he(c,f,m,O.x,O.y,y,w,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});I&&I.c>=.8&&(b={m:I,f:O})}}let T=({m:O,f:I})=>(o={...o,x:I.x,y:I.y,d:O.d,tpl:ur(c,f,I.x,I.y,y,w)},{d:O.d,x:I.x+y/2,y:I.y+w/2,c:O.c,method:"track",blocks:0});if(b&&h-o.at<r)return T(b);let x=Xt(c,f,m,d);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let O=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!O?{d:x.d}:null,!O)return o.at=h,T(b)}else a=null;if(!x)return o=null,null;let P=Math.round(Math.max(0,Math.min(u-y,x.x-y/2))),C=Math.round(Math.max(0,Math.min(m-w,x.y-w/2)));return o={x:P,y:C,d:x.d,tpl:ur(c,f,P,C,y,w),w:y,h:w,at:h},x},reset(){o=null,a=null}}}function fr(r,e,t,i,n,s){let o=Math.max(1,s|0),a=Math.floor(i/o);a-=a&1;let l=Math.floor(n/o),c=new Uint8Array(a*l);if(o<=2){let h=o*o;for(let d=0;d<l;d++)for(let u=0;u<a;u++){let p=0;for(let y=0;y<o;y++){let w=e+(d*o+y)*t+u*o;for(let b=0;b<o;b++)p+=r[w+b]}c[d*a+u]=p/h|0}return{img:c,w:a,h:l}}let f=o>>2,m=3*o>>2;for(let h=0;h<l;h++){let d=e+(h*o+f)*t,u=e+(h*o+m)*t;for(let p=0;p<a;p++){let y=p*o+f,w=p*o+m;c[h*a+p]=r[d+y]+r[d+w]+r[u+y]+r[u+w]>>2}}return{img:c,w:a,h:l}}var Gt=_e(()=>{"use strict"});function _s(r,e="@displayxr/inline3d"){if(r==null||r===!1)return null;if(r==="depth"||r===!0)return{};if(typeof r!="object")throw new Error(`${e}: cursor ${JSON.stringify(r)} \u2014 expected 'depth' or { height, margin, anchor, pointerScope }.`);let t=Object.keys(r).filter(i=>!mr.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${mr.join(", ")}.`);if(r.anchor!==void 0&&!pr.includes(r.anchor))throw new Error(`${e}: cursor.anchor "${r.anchor}" \u2014 expected ${pr.join(", ")}.`);if(r.pointerScope!==void 0&&r.pointerScope!=="canvas"&&r.pointerScope!=="window")throw new Error(`${e}: cursor.pointerScope "${r.pointerScope}" \u2014 expected 'canvas' or 'window'.`);for(let i of["height","margin"])if(r[i]!==void 0&&!(typeof r[i]=="number"&&r[i]>0&&Number.isFinite(r[i])))throw new Error(`${e}: cursor.${i} must be a positive number.`);return{...r}}function Ke(r,e="@displayxr/inline3d"){let t=_s(r,e);if(!t)return null;let i=Object.keys(t).filter(n=>!gr.includes(n));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${gr.join(", ")}.`);return t}var pr,mr,gr,Jt=_e(()=>{"use strict";pr=Object.freeze(["hybrid","screen","world"]),mr=Object.freeze(["height","margin","anchor","pointerScope"]);gr=Object.freeze(["height","pointerScope"])});function Lr(r){return r>0&&Number.isFinite(r)?Math.min(.5,ti/r):Ms}function Ar(r,e){return r<=Es?!(e>0&&Number.isFinite(e))||-r*e>=Rs:!1}function ii(r,e,t){if(!e||!Number.isFinite(t)||!(t<0))return 0;let i=Math.min(0,Number.isFinite(r.maxDisparity)?r.maxDisparity:0);return Math.min(i,Math.max(r.minDisparity,t-r.margin))}function Or(r,e,t,i){if(!r.primed||i<r.last||i-r.last>e.stale)return r.primed=!0,r.disparity=t,r.last=i,t;if(i===r.last)return r.disparity;let n=i-r.last,s=t<r.disparity?e.riseTau:e.sinkTau,o=s>0?1-Math.exp(-n/s):1;return r.disparity+=o*(t-r.disparity),r.last=i,r.disparity}function Cs(r){let e=globalThis.document;if(!(!e||!e.documentElement)){if(r&&!e.getElementById("inline3d-cursor-style")){let t=e.createElement("style");t.id="inline3d-cursor-style",t.textContent="html.inline3d-cursor-hidden, html.inline3d-cursor-hidden * { cursor: none !important; }",(e.head||e.documentElement).appendChild(t)}ei=Math.max(0,ei+(r?1:-1)),e.documentElement.classList.toggle("inline3d-cursor-hidden",ei>0)}}function ks(r,e,t,i){let n=.75*t,s=[[r,e]];for(let o=0;o<8;o++){let a=o*Math.PI/4;s.push([r+n*Math.cos(a)/i,e+n*Math.sin(a)])}return s}function Pr(r,e,t,i){return[[r,e],...ks(r+.3*t/i,e+.5*t,t,i)]}function ri(r,e=rt){let t=0;for(let s=0;s<e.length;s++){let[o,a]=e[s],[l,c]=e[(s+1)%e.length];t+=o*c-l*a}let i=t>0?1:-1,n=e.map((s,o)=>{let a=e[(o+1)%e.length],l=a[0]-s[0],c=a[1]-s[1],f=Math.hypot(l,c)||1;return[-c/f*i,l/f*i]});return e.map((s,o)=>{let a=n[(o+e.length-1)%e.length],l=n[o],c=r/(1+a[0]*l[0]+a[1]*l[1]);return[s[0]+(a[0]+l[0])*c,s[1]+(a[1]+l[1])*c]})}var Ms,ti,Es,Rs,it,tt,ei,rt,Ho,$o,Uo,Vo,Ir=_e(()=>{"use strict";Ms=.03,ti=19;Es=-.005,Rs=.5;it=Object.freeze({margin:.015,minDisparity:-.6,maxDisparity:0,riseTau:.03,sinkTau:.25,stale:.5});tt=class{constructor(e,{scope:t="canvas"}={}){if(t!=="canvas"&&t!=="window")throw new Error(`@displayxr/inline3d: cursor pointerScope "${t}" \u2014 expected 'canvas' or 'window'.`);this.canvas=e,this.scope=t,this.uv=null,this._hidden=!1,this._prev="",this._onMove=i=>{let n=e.getBoundingClientRect();if(!(n.width>0&&n.height>0))return void(this.uv=null);let s=(i.clientX-n.left)/n.width,o=(i.clientY-n.top)/n.height;this.uv=s>=0&&s<=1&&o>=0&&o<=1?[s,o]:null},this._onLeave=()=>{this.uv=null},this._target=t==="window"?globalThis:e,this._target.addEventListener("pointermove",this._onMove),t==="window"?(this._onOut=i=>{i.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}set(e,t){this.uv=e==null?null:[e,t]}aspect(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.width/e.height:1}cssHeight(){let e=this.canvas.getBoundingClientRect();return e.height>0?e.height:0}panelPx(){return this.cssHeight()*(globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1)}hideCss(e){e!==this._hidden&&(this.scope==="window"?Cs(e):e?(this._prev=this.canvas.style.cursor||"",this.canvas.style.cursor="none"):this.canvas.style.cursor==="none"&&(this.canvas.style.cursor=this._prev),this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}},ei=0;rt=Object.freeze([[0,0],[0,16],[4.2,12.4],[6.9,18.6],[9.5,17.5],[6.8,11.5],[11.7,11.5]].map(([r,e])=>Object.freeze([r/19,e/19]))),Ho=Object.freeze([[0,1,2],[0,2,5],[0,5,6],[2,3,4],[2,4,5]]);$o=Object.freeze(ri(1/19).map(r=>Object.freeze(r))),Uo=Object.freeze([1,1,1,1]),Vo=Object.freeze([.02,.02,.03,1])});var oi={};yn(oi,{PAIR_CURSOR_ARROW:()=>Ds,PAIR_CURSOR_CSS_PX:()=>Ts,PAIR_CURSOR_CSS_PX_M:()=>Nr,PAIR_CURSOR_HEIGHT:()=>jr,PAIR_SUPPORT_COPY_PX:()=>Hr,PairCursor:()=>si,consistentMatch:()=>ni,drawPairArrow:()=>Br,pairCursorScale:()=>Ur,pairCursorTarget:()=>As,pairFootprintDisparity:()=>zr,pairNearestSupported:()=>$r,pairPxPerBaseline:()=>Vr});function zr(r,e,t,i,n,s){if(!r||!r.img||!e||!e.rL||!e.rR||!(e.outW>0))return null;let{img:o,w:a,h:l,scale:c}=r,f=a/2,m=Math.max(8,Math.round(f/20)),h=Math.round(f*.3),d=-Math.round(f*.05),{rL:u,rR:p}=e,y=e.outW/u.sw,w=Ls(r),b=[],T=new Set,x=(M,g)=>{let v=Math.round((u.sy+g*u.sh)*c-m/2);if(v<0||v+m>l)return;let _=Math.round((u.sx+M*u.sw)*c-m/2),S=Math.round((p.sx+M*p.sw)*c-m/2);if(!T.has(`L${_},${v}`)){T.add(`L${_},${v}`);let D=ni(o,w,a,l,_,v,m,d,h);D!==null&&b.push({d:D,x:_,y:v,eye:0})}if(!T.has(`R${S},${v}`)){T.add(`R${S},${v}`);let D=ni(w,o,a,l,S,v,m,-h,-d);D!==null&&b.push({d:-D,x:S,y:v,eye:1})}},P=0,C=0,O=0;for(let[M,g]of Pr(t,i,n,s))M>=0&&M<=1&&g>=0&&g<=1&&(x(e.mirror?1-M:M,g),P+=M,C+=g,O++);if(!O)return null;let I=m/2/c/u.sw,L=m/2/c/u.sh;for(let[M,g]of[[-I,0],[I,0],[0,-L],[0,L]]){let v=P/O+M,_=C/O+g;v>=0&&v<=1&&_>=0&&_<=1&&x(e.mirror?1-v:v,_)}for(let M of b)M.d=(M.d/c-(u.sx-p.sx))*y;return $r(b,Hr/c*y,m/2)}function Ls(r){let e=Wr.get(r);if(e)return e;let{img:t,w:i,h:n}=r,s=i/2;e=new Uint8Array(i*n);for(let o=0;o<n;o++){let a=o*i;for(let l=0;l<s;l++)e[a+l]=t[a+s+l],e[a+s+l]=t[a+l]}return Wr.set(r,e),e}function ni(r,e,t,i,n,s,o,a,l){let c=t/2;if(n<0||n+o>c)return null;let f=he(r,t,i,n,s,o,o,{dMin:a,dMax:l,dyMax:2});if(!f||f.c<.8)return null;let m=Math.round(n-f.d),h=s+f.dy;if(m<0||m+o>c||h<0||h+o>i)return null;let d=he(e,t,i,m,h,o,o,{dMin:-Math.ceil(f.d)-2,dMax:-Math.floor(f.d)+2,dyMax:1});return!d||d.c<.8||Math.abs(-d.d-f.d)>1?null:f.d}function $r(r,e,t=0){let i=r.map(o=>typeof o=="number"?{d:o,x:0,y:0,eye:-1}:o);if(i.length<2)return null;let n=[...i].sort((o,a)=>a.d-o.d),s=(o,a)=>o.eye===-1||o.eye!==a.eye||Math.abs(o.x-a.x)+Math.abs(o.y-a.y)>=t;for(let o of n)for(let a of n)if(a!==o&&Math.abs(o.d-a.d)<=e&&s(o,a))return o.d;return null}function Ur(r,e,t){let i=t>0&&Number.isFinite(t)?t:Nr;return e>0?r/e/i:r/(1e3*i)}function Vr(r,e,t,i=Pe.eyeSeparationM){return Ur(r,e,t)*i}function As(r,e,t=it){return r===null||!Number.isFinite(r)||!(e>0)?0:-ii(t,!0,-r/e)*e||0}function Os(r){let e=r>0?Math.max(.05263157894736842,1/r):.05263157894736842,t=Math.round(e*1e4),i=nt.get(t);return i||(nt.size>32&&nt.clear(),nt.set(t,i=ri(e))),i}function Br(r,e,t,i,n,s,o){let a=n*t,l=Os(o);for(let c of[0,1]){let f=c*e+i*e+(c===0?s/2:-s/2);r.save(),r.beginPath(),r.rect(c*e,0,e,t),r.clip();for(let[m,h]of[[rt,"#000"],[l,"#fff"]])r.beginPath(),m.forEach(([d,u],p)=>(p?r.lineTo:r.moveTo).call(r,f+d*o,a+u*o)),r.closePath(),r.fillStyle=h,r.fill();r.restore()}}var Ts,jr,Ds,Nr,Hr,Wr,nt,si,ai=_e(()=>{"use strict";Ir();gt();Gt();Ts=ti,jr=.06,Ds=rt,Nr=.0254/96;Hr=1.5,Wr=new WeakMap;nt=new Map;si=class{constructor(e,{height:t,pointerScope:i="window"}={}){this.pointer=new tt(e,{scope:i}),this.height=t>0?t:null,this.filter={},this._luma=null,this._uv=null,this._content=null,this._metricsFor=null,this.metersPerCssPx=null,this.eyeSeparationM=Pe.eyeSeparationM,this.last=null}get hovering(){return!!this.pointer.uv}draw(e,t,i,n){let s=this.pointer.uv;if(!s)return this.idle();let[o,a]=s,l=this.height??this._osArrowFraction();(t!==this._luma||!this._uv||this._uv[0]!==o||this._uv[1]!==a)&&(this._content=zr(t,i,o,a,l,i.outW/i.outH),this._luma=t,this._uv=s),this._askMetrics(i.handle);let c=this.pointer.canvas.getBoundingClientRect?.(),f=Vr(i.outW,c&&c.width,this.metersPerCssPx,this.eyeSeparationM),m=this._content===null?null:-this._content/f,h=ii(it,m!==null,m),d=Or(this.filter,it,h,n),u=Ar(d,f),p=-d*f;return u&&Br(e,i.outW,i.outH,o,a,p,l*i.outH),this.pointer.hideCss(u),this.last={contentPx:this._content,targetPx:-h*f||0,disparityPx:u?p:0,filteredPx:p||0,drawn:u,pxPerBaseline:f},this.last}_askMetrics(e){!e||e===this._metricsFor||typeof e.displayMetrics!="function"||(this._metricsFor=e,Promise.resolve().then(()=>e.displayMetrics()).then(t=>{this._metricsFor!==e||!t||(t.metersPerCssPx>0&&(this.metersPerCssPx=t.metersPerCssPx),t.eyeSeparationM>0&&(this.eyeSeparationM=t.eyeSeparationM))}).catch(()=>{}))}_osArrowFraction(){let e=this.pointer.canvas.getBoundingClientRect?.();return e&&e.height>0?Lr(e.height):jr}idle(){return this.pointer.hideCss(!1),this.filter={},this._uv=null,this.last=null,null}dispose(){this.pointer.dispose()}}});var ve=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),vn=["high","normal","low","paused"],wn=.02,bn=1e3/20,xn=3e3,Sn=1e3/28;function be(r){return typeof r=="function"?r:r===!1||r==="off"?"off":"auto"}function dt(r=import.meta.url){return ye?typeof ye=="function"?ye():ye:new URL("../lift/index.js",r).href}var ye=null;function Ri(r){ye=r||null}function Mn(){return import(dt())}async function ut(r,{importer:e=Mn,nav:t=globalThis.navigator,log:i=null,capsOpts:n={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=be(r);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 f=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,m=null;if(f){try{m=await f(n)}catch{m=null}let h=!!(m&&m.webFallback&&m.webFallback.webgpu);if(m&&!m.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(m&&m.native),provider:m&&m.provider||null}),{lift:c,capabilities:f,caps:m,source:"module",reason:null}}function we(r){let e=Number.isFinite(+r)&&r!==null?Math.max(-1,Math.min(1,+r)):0;return Math.abs(e)<wn?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Oe({id:r,speakerId:e,visible:t=!0}){return t?r!=null&&r===e?ve.speaker:ve.other:ve.hidden}function ft(r,e){if(!r||!vn.includes(e)||typeof r.setPriority!="function")return!1;try{return r.setPriority(e)!==!1}catch{return!1}}function pt({degradedMs:r=bn,recoveredMs:e=Sn,holdMs:t=xn,alpha:i=.1}={}){let n=null,s=0,o=!1;return{feed(a){if(!(a>0)||a>1e3)return null;if(n=n===null?a:n+i*(a-n),o){if(n<e)return o=!1,s=0,"recovered"}else if(s=n>r?s+a:0,s>=t)return o=!0,"degraded";return null},reset(){n=null,s=0,o=!1},get frameMs(){return n},get degraded(){return o}}}function mt({lift:r,max:e=4,log:t=null,options:i=null}={}){let n=i&&typeof i=="object"?i:{},s=new Map,o=null,a=0,l=0,c=(h,d)=>t&&t(h,d),f=(h,d)=>{if(!d.handle)return;let u=Oe({id:h,speakerId:o,visible:d.visible});if(u===d.priority)return;d.priority=u;let p=ft(d.handle,u);c("lift-priority",{peer:h,priority:u,applied:p})},m={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:u,visible:p=!0,onError:y}={}){let w=s.get(h);if(w)return w.pending||Promise.resolve(w.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,T=Oe({id:h,speakerId:o,visible:p}),x={gen:b,handle:null,visible:p,priority:T,pending:null};s.set(h,x);let P={quality:"auto",...n,mode:"live",wall:u,ui:"none",convergence:we(a),priority:T};return c("lift-acquire",{peer:h,priority:T,convergence:P.convergence}),x.pending=Promise.resolve().then(()=>r(d,P)).then(C=>{if(s.get(h)!==x||x.gen!==b){try{C&&C.remove&&C.remove()}catch{}return null}return x.pending=null,x.handle=C||null,x.priority=null,f(h,x),C&&typeof C.setConvergence=="function"&&C.setConvergence(we(a)),x.handle},C=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(C&&C.message||C).slice(0,200)}),y&&y(C),null)),x.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()])m.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[d,u]of s)f(d,u)},setVisible(h,d){let u=s.get(h);!u||u.visible===!!d||(u.visible=!!d,f(h,u))},setDepth(h){a=h;let d=we(h);for(let u of s.values())u.handle&&typeof u.handle.setConvergence=="function"&&u.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 m}var Rn=null;function Ci(r){Rn=typeof r=="function"?r:null}var Cn=new WeakMap;function ki(r,e){r&&(typeof r=="object"||typeof r=="function")&&Cn.set(r,e)}gt();var Di=new WeakMap,J;function Li(r){let e=null;for(let[t,i]of r)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function kn(r){if(!r||typeof r.getParameter!="function")return null;let e=Di.get(r);if(e)return e;let t,i,n;try{t=r.getParameter(r.MAX_TEXTURE_SIZE??3379),i=r.getParameter(r.MAX_RENDERBUFFER_SIZE??34024),n=r.getParameter(r.MAX_VIEWPORT_DIMS??3386)}catch{return null}let s=n&&n.length>=2?n[0]:0,o=n&&n.length>=2?n[1]:0,a=Li([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=Li([["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 Di.set(r,c),c}function Ai(){if(J!==void 0)return J;J=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return J;let r=document.createElement("canvas"),e=r.getContext("webgl2")||r.getContext("webgl");if(!e)return J;J=kn(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{J=null}return J}function Oi(r,e,t,{cols:i=2,rows:n=1}={}){let s=r*i,o=e*n,a={eyeW:r,eyeH:e,cols:i,scale:1,clamped:!1,reqW:s,reqH:o,bufW:s,bufH:o,limitName:"",limitValue:0};if(!t||!(r>0)||!(e>0))return a;let l=t.maxW/s,c=t.maxH/o,f=Math.min(l,c);if(!(f<1))return a;let m=l<=c,h=Math.max(1,Math.min(Math.floor(r*f+1e-9),Math.floor(t.maxW/i))),d=Math.max(1,Math.min(Math.floor(e*f+1e-9),Math.floor(t.maxH/n)));return{eyeW:h,eyeH:d,cols:i,scale:f,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:d*n,limitName:m?t.nameW:t.nameH,limitValue:m?t.valueW:t.valueH}}function _t(r){return Math.round(r*1e3)/1e3}function Pi(r,e,t){let i=typeof t=="number"?` (renderScale ${_t(t)} \u2192 ${_t(t*e.scale)})`:` (scale ${_t(e.scale)})`;return`${r} ${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 Ii(r,e){let t=r?.width||0,i=r?.height||0,n=e&&e.drawingBufferWidth>0?e.drawingBufferWidth:t,s=e&&e.drawingBufferHeight>0?e.drawingBufferHeight:i,o=t>0?n/t:1,a=i>0?s/i:1;return{sx:o,sy:a,w:n,h:s,mismatch:o!==1||a!==1}}function Fi(r,e,t,i="laying the eyes out from the drawing buffer. Lower renderScale to stay inside the device limit."){return`${r} 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 re="smoothstep",vt=["linear","smoothstep","easeoutcubic"];function wt(r){if(typeof r!="string")return null;let e=r.toLowerCase().replace(/[-_\s]/g,"");return vt.includes(e)?e:null}function Tn(r,e){if(e<=0)return 0;if(e>=1)return 1;if(r==="linear")return e;if(r==="easeoutcubic"){let t=1-e;return 1-t*t*t}return e*e*(3-2*e)}var ie="idle",Wi="rampDownThenFire",yt="fireThenRampUp",Ie=class{constructor(e,t){this._phase=ie,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=re,(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=wt(t)||re),this}get durationS(){return this._dur}get easing(){return this._easing}request({targetMode:e=null,targetViewCount:t,currentMode:i=null,currentViewCount:n,current:s,steady:o=1}={}){let a=!(t>1),l=!(n>1),c=Number.isFinite(o)?o:1,f=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=f,a&&!l?(this._phase=Wi,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=yt,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=yt,this._to=a?f: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!==ie){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)*Tn(this._easing,this._t),this._phase===yt?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=ie)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=ie)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==ie}value(){return this._cur}firePending(){return this._phase===Wi?this._fireAtEnd:this._firePending}cancel(){return this._phase=ie,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var B=null;Ci(r=>{let e=B;if(!e||!e._running||!r)return null;let t=i=>({layer:i.layer,session:e.session});for(let i of e._windows.values())if(i.canvas===r&&i.layer)return t(i);for(let i of e._windows.values())if(i.layer&&typeof r.contains=="function"&&r.contains(i.canvas))return t(i);for(let i of e._windows.values()){let n=i.canvas.parentElement;if(i.layer&&n&&typeof n.contains=="function"&&n.contains(r))return t(i)}return null});var Dn=()=>typeof navigator<"u"&&!!navigator.xr,Q=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Fe=()=>Q()&&"excludeElement"in window.XRDisplayLayer.prototype,bt=()=>{if(!Q())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Ln=["getDisplayInfo","getRenderingModes","requestRenderingMode"],Gi=["renderingmodechange","hardwaredisplaystatechange"],Dt="trackingstatechange",Ji=["unknown","tracking","searching"],Ni=[...Gi,Dt];function We(r){try{let e=r?r.trackingState:void 0;return Ji.includes(e)?e:null}catch{return null}}var xt=()=>{if(!Q())return!1;try{let r=window.XRDisplayLayer.prototype;return Ln.every(e=>typeof r[e]=="function")}catch{return!1}},St=()=>{if(!Q())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},se=null;function ne(){if(se!==null)return se;if(!Q())return!1;try{let r=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof r=="boolean")return se=r}catch{}return!1}function An(r){if(se!==null)return se;if(!r||!Q()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return se=!!r.occlusionByDrawOrder}catch{return null}}var zi=!1;function Mt(){zi||(zi=!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 Yi(){return Dn()&&Q()}function Et(r){return{type:"display",position:{x:0,y:0,z:0},orientation:{x:0,y:0,z:0,w:1},virtualDisplayHeight:r.virtualDisplayHeight>0?r.virtualDisplayHeight:.24,ipdFactor:1,parallaxFactor:1,perspectiveFactor:1}}function On(r,e){let t=Number.isFinite(r.ipdFactor)?r.ipdFactor:1,i=Number.isFinite(r.parallaxFactor)?r.parallaxFactor:1;return{...r,ipdFactor:t*e,parallaxFactor:i*e}}var Pn=16;function N(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var Lt=1200,In=new Set(["pending","woven","withheld"]),Hi=3,Fn=new Set(["getDisplayInfo","getRenderingModes","requestRenderingMode"]),Wn=new Set(["getDisplayInfo","getRenderingModes"]);function jn(r){return r==null||Array.isArray(r)&&r.length===0}function Rt(){try{let r=typeof XRDisplayLayer=="function"?XRDisplayLayer:null;return!!(r&&r.prototype&&"wovenState"in r.prototype)}catch{return!1}}function je(r){try{let e=r?r.wovenState:null;return In.has(e)?e:null}catch{return null}}function Ct(r){try{let e=r?r.withheldReason:null;return typeof e=="string"&&e?e:null}catch{return null}}var $i=!1;function Nn(r){if(r==null)return re;let e=wt(r);return e||($i||($i=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(r)} } }) is not a curve this SDK knows (${vt.join(" / ")}); using '${re}'.`)),re)}var Ui=!1;function zn(){Ui||(Ui=!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 At(r){return r&&r.detail!==void 0&&r.detail!==null?r.detail:void 0}function Ki(r){let e=At(r);return e!==void 0?[e,r]:[r]}function Hn(r){for(let e of Ki(r)){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(r){for(let e of Ki(r)){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 Vi=!1;function Un(){Vi||(Vi=!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 Bi=!1;function Vn(){Bi||(Bi=!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 Zi(r={}){let{referenceSpace:e="viewer",lazy:t=!0,rootMargin:i="50% 0px",autoChrome:n=!0,modeSwitch:s=null,untrackedFallback:o="none",viewerEase:a}=r;if(!Yi())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(f){return{supported:!1,trackingState:"unknown",error:f}}a!==void 0&&ki(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new Ot(l,c,{lazy:t,rootMargin:i,autoChrome:n,modeSwitch:s,untrackedFallback:o})}var xe=null;function ze(r={}){return B&&B._running?Promise.resolve(B):xe||(xe=Zi(r).finally(()=>{xe=null}),xe)}var qi=.7,Bn=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function qn(r){let e=[],t=document.createTreeWalker(r,NodeFilter.SHOW_ELEMENT);for(let i=t.nextNode();i;i=t.nextNode())if(!i.closest("[data-inline3d-no-overlay]")){if(Bn.has(i.tagName.toUpperCase())){e.push(i);continue}for(let n of i.childNodes)if(n.nodeType===Node.TEXT_NODE&&n.nodeValue.trim()){e.push(i);break}}return e}var kt=4;function Tt(r){let e=typeof window<"u"&&window.devicePixelRatio||1,t="";if(typeof r.getBoundingClientRect=="function"){let i=r.getBoundingClientRect()||{},n=typeof window<"u"&&window.scrollX||0,s=typeof window<"u"&&window.scrollY||0;t=`+${Math.round((i.left??i.x??0)+n)},${Math.round((i.top??i.y??0)+s)}`}return`${r.clientWidth}x${r.clientHeight}@${e}${t}`}function Xi(r){let e=typeof window<"u"&&window.devicePixelRatio||1;return{width:r.clientWidth||0,height:r.clientHeight||0,dpr:e}}function Xn(r){if(r==null||r===!1||r==="off")return null;if(r==="auto"||r===!0)return{color:"#000",snapshot:!0};if(typeof r=="object"){if(r.color!==void 0&&typeof r.color!="string")throw new TypeError("[inline3d] rectCover.color must be a CSS color string.");return{color:r.color||"#000",snapshot:r.snapshot!==!1}}throw new TypeError(`[inline3d] rectCover: expected 'auto', 'off' or { color?, snapshot? }; got ${JSON.stringify(r)}.`)}var Ot=class{constructor(e,t,{lazy:i,rootMargin:n,autoChrome:s=!0,modeSwitch:o=null,untrackedFallback:a="none"}){this.supported=!0,this.session=e,this.refSpace=t,this._windows=new Map,this._claims=new Map,this._doubleWarned=new WeakSet,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 Ie((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,Nn(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=We(e)!==null,this._trackingState=this._trackingSupported?We(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=St()?{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:n}):null,this._loopId=0,this._framePending=!1,this._frameCount=0,this._frameWatchdog=null,this._suspended=null,B&&B._running&&B!==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."),B=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))){ne()&&Mt(),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(ne()||!this._autoChrome||!Fe()||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,n=t.querySelectorAll(":scope > *, :scope > * > *, :scope > * > * > *");for(let s of n){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 qn(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={}){this._warnDoubleAttach(e,"addImage",i._dxrClaim);let n=this._register(e,"image",i);return n.method="addImage",n.ready=Jn(t).then(s=>{n.img=s,n.repaint()}),this._handle(e,n)}addVideo(e,t,i={}){this._warnDoubleAttach(e,"addVideo",i._dxrClaim);let n=this._register(e,"video",i);return n.method="addVideo",n.video=t,this._handle(e,n)}addScene(e,t,i={}){this._warnDoubleAttach(e,"addScene",i._dxrClaim),i.viewRig&&i.virtualDisplayHeight!==void 0&&Vn();let n=this._register(e,"scene",{virtualDisplayHeight:.24,...i});return n.method="addScene",n.onFrame=t,n.ownsBuffer=!1,i.bufferClamped===!0&&(n.warnedBufMismatch=!0),this._handle(e,n)}_liveRegistration(e,t){let i=this._claims.get(e);if(i&&i.token!==t)return i.method;let n=this._windows.get(e);return n?n.method||"add*":null}_warnDoubleAttach(e,t,i){let n=this._liveRegistration(e,i);!n||this._doubleWarned.has(e)||(this._doubleWarned.add(e),console.warn(`[inline3d] ${t}() on a canvas that is already registered on this inline-3D session (by ${n}(), not yet removed). This call is rebuilding the canvas's layer (a fresh 0.4-1.2 s identity gap) or putting a second renderer on its context. Change what is IN the canvas instead (setSource, your onFrame, a redrawn source canvas), or call handle.remove() on the first registration first. (Warned once per canvas.)`,e))}_attachGuard(e,t,i={}){let n=this._claims.get(e);if(i&&i._dxrClaim&&n&&n.token===i._dxrClaim)return{opts:i,own:()=>{}};this._warnDoubleAttach(e,t,null);let s={};return{opts:{...i,_dxrClaim:s},own:o=>this._claim(e,t,o,s)}}_claim(e,t,i,n){if(!this._running||!i||typeof i!="object")return;let s={token:n,method:t};this._claims.set(e,s);let o=i.remove,a=(...l)=>(this._claims.get(e)===s&&this._claims.delete(e),typeof o=="function"?o.apply(i,l):void 0);Object.defineProperty(i,"remove",{configurable:!0,enumerable:!0,get:()=>a,set:l=>{o=l}})}_handle(e,t){let i=this;return{remove:()=>this._remove(e),exclude:n=>{n&&(ne()&&Mt(),t.excluded.add(n),this._applyExclusion(t,n))},unexclude:n=>{!n||!t.excluded.delete(n)||this._dropExclusion(t,n)},get trackingState(){return i._trackingState},setViewRig:n=>(t.viewRig=n||null,this._pushViewRig(t)),getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let n=null;try{n=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return Ti(n,e.getBoundingClientRect(),globalThis.devicePixelRatio||1)},getRenderingModes:()=>this._getRenderingModes(t),requestRenderingMode:n=>this._requestRenderingModeEased(n,t),setStereoEnabled:n=>this._setStereoEnabled(n,t),on:(n,s)=>this.on(n,s),off:(n,s)=>this.off(n,s),onDisplayModeChange:n=>this._onDisplayModeChange(n),stats:()=>({frames:t.frames,monoFrames:t.monoFrames}),get wovenState(){return Rt()?t.layer?je(t.layer):"pending":null},get withheldReason(){return!Rt()||!t.layer?null:je(t.layer)==="withheld"?Ct(t.layer):null},get firstWoven(){return t.fwPromise},onFirstWoven:n=>{if(typeof n!="function")throw new TypeError("[inline3d] onFirstWoven() takes a function.");let s=!0;return t.fwPromise.then(o=>{if(s)try{n(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?Et(e):null):(e.viewRig||(e.stereoSynthRig=!0),On(e.viewRig||Et(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&zn(),!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 n=i.viewRig||Et(i);i.stereoSaved={ipdFactor:n.ipdFactor,parallaxFactor:n.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!bt())return Un(),!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,n=[]){if(!xt())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 }.`));if(Fn.has(t)&&!e.layerFramed&&this._layerReadPending(e))return this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n));let o;try{o=Promise.resolve(e.layer[t](...n))}catch(l){return Promise.reject(l)}if(!Wn.has(t)||!this._layerReadPending(e))return o;let a=e.layer;return o.then(l=>e.layer!==a?l:jn(l)?this._layerReadPending(e)?this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n)):l:(e.lfAnswered=!0,l))}_layerFramedCap(e){return kt*Math.max(e.fwHoldMs,Lt)}_layerReadPending(e){return!e.layer||e.lfAnswered||e.lfCapped?!1:N()-e.lfAt>=this._layerFramedCap(e)?(e.lfCapped=!0,!1):!0}_whenLayerFramed(e){return new Promise(t=>{let i=e.layer,n={resolve:t,timer:null},s=Math.max(0,this._layerFramedCap(e)-(N()-e.lfAt));n.timer=setTimeout(()=>{let o=e.framedWaiters.indexOf(n);o>=0&&e.framedWaiters.splice(o,1),e.layer===i&&(e.lfCapped=!0),t()},s),n.timer&&typeof n.timer.unref=="function"&&n.timer.unref(),e.framedWaiters.push(n)})}_tickLayerFramed(e){let t=e.wsLive?je(e.layer):null;(t?t==="woven":e.lfStereo)?this._noteLayerFramed(e,!0):e.framedWaiters.length&&!this._layerReadPending(e)&&this._noteLayerFramed(e,!1)}_noteLayerFramed(e,t=!0){t&&(e.layerFramed=!0);let i=e.framedWaiters.splice(0);for(let n of i)clearTimeout(n.timer),n.resolve()}_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 n=i.find(s=>s.isActive);return n&&(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.viewCount,(n.viewCount===1||n.viewCount===2)&&this._setStereoCollapsed(n.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||!bt())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 n=(Array.isArray(i)?i:[]).find(a=>a&&a.modeIndex===e),s=n&&Number.isFinite(n.viewCount)?n.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((n,s)=>{i.resolve=n,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 n=this._msFire!==null&&e===this._activeModeIndex;this._settlePendingDown("superseded",`a request for mode ${e} reversed it`);let s=n?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 n=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.`);n.name=e,i.reject(n)}_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 n of this._windows.values())this._pushViewRig(n)}if(i.fire&&this._msFire){let n=this._msFire;this._msFire=null,this._requestRenderingMode(n.modeIndex,n.win).then(s=>n.resolve(s),s=>{this._startUpRamp(),n.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())},Pn))}_disarmModeSwitchTick(){this._msTick!==null&&(typeof clearTimeout=="function"&&clearTimeout(this._msTick),this._msTick=null)}async _setStereoEnabled(e,t){let i=e?2:1,n=await this._getRenderingModes(t),s=Array.isArray(n)?n:[],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"||xt()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=$n(e),i=At(e),n=a=>{a&&(this._hardwareDisplayState=a),this._emitDisplay({type:"hardwaredisplaystatechange",state:a||this._hardwareDisplayState,detail:i})};t&&n(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;n(c)}}).catch(()=>{t||n(null)})}async _onRenderingModeChange(e){let t=At(e),i=Hn(e),n=null;try{let s=await this._getRenderingModes(null),o=Array.isArray(s)?s:[];n=(i>=0?o.find(a=>a.modeIndex===i):null)||o.find(a=>a.isActive)||null}catch{}n?(this._activeModeIndex=n.modeIndex,this._activeViewCount=n.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:n,detail:t})}_emitDisplay(e,t){let i=this._displayListeners.get(e.type);if(!i)return;let n=t||[e];for(let s of[...i])try{s(...n)}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(!Ni.includes(e))throw new TypeError(`[inline3d] on() knows ${Ni.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=Gi.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!St())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 n={canvas:e,kind:t,layer:null,img:null,video:null,onFrame:null,onLayerLost:typeof i.onLayerLost=="function"?i.onLayerLost:null,layerLostSent:!1,onResize:t==="scene"&&typeof i.onResize=="function"?i.onResize:null,resizeBox:null,inResize:!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(n,null),excluded:new Set,autoExcluded:new Set,overlayObserver:null,sizeObserver:null,resizePending:!1,frames:0,monoFrames:0,fwResult:null,fwResolve:null,fwPromise:null,fwHoldMs:Gn(i.firstWovenHoldMs),fwRegAt:N(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null,wsLive:!1,rc:null,layerFramed:!1,lfAnswered:!1,lfStereo:!1,lfAt:0,lfCapped:!1,framedWaiters:[]},s=Xn(i.rectCover);return s&&(n.rc={cfg:s,box:null,el:null,up:!1,snapped:!1,snapWanted:!1,waiting:null,w:0,h:0}),n.fwPromise=new Promise(o=>{n.fwResolve=o}),this._windows.set(e,n),this._lazy&&this._observer?this._observer.observe(n.observeEl):this._activate(n),n}_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"),this._dropCover(t))}_onIntersect(e){for(let t of e){let i=null;for(let n of this._windows.values())if(n.observeEl===t.target){i=n;break}i&&(t.isIntersecting?this._activate(i):this._deactivate(i))}}_activate(e){if(!e.layer){this._scanChrome();try{let t=bt()?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),e.wsLive=Rt(),e.layerFramed=!1,e.lfAnswered=!1,e.lfStereo=!1,e.lfCapped=!1,e.lfAt=N(),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&xt()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),St()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),An(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._noteLayerFramed(e,!1),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(),n=e.canvas.getBoundingClientRect(),s=i.width*i.height,o=n.width*n.height;if(s<=0||o<=0)return!1;let a=Math.min(i.right,n.right)-Math.max(i.left,n.left),l=Math.min(i.bottom,n.bottom)-Math.max(i.top,n.top);if(a<=0||l<=0)return!1;let c=a*l;return c/s<qi||c/o<qi?!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(ne()||!e.layer||!Fe()||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 n=t.style.willChange&&t.style.willChange!=="auto"?t.style.willChange+", transform":"transform";t.style.willChange=n,t.dataset.inline3dIsolated="1"}try{e.layer.excludeElement(t)}catch{}}_dropExclusion(e,t){if(ne())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Fe()))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&&Mt()}_startOverlayScan(e){if(ne()||!Fe()||typeof MutationObserver!="function")return;let t=e.canvas.parentElement;if(!t)return;let i=()=>{let n=new Set(t.querySelectorAll("[data-inline3d-overlay]"));for(let s of e.autoExcluded)n.has(s)||(e.autoExcluded.delete(s),this._dropExclusion(e,s));for(let s of n)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),n=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/n,a.h/s);c<1&&(o=c,n=Math.max(1,Math.round(n*c)),s=Math.max(1,Math.round(s*c)))}let l=Oi(n,s,Ai(),{cols:t?2:1});return l.clamped&&(o*=l.scale,n=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(Pi("[inline3d]",l)))),e.bufScale=o,{w:n,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,n=t.videoHeight||t.naturalHeight||t.height;return!(i>1)||!(n>0)?null:{w:i/2,h:n}}_checkSceneBuffer(e){let t=e.canvas;if(!t||typeof t.getContext!="function")return;if(e.sceneGl===void 0){let n=null;try{n=t.getContext("webgl2")||t.getContext("webgl")}catch{n=null}e.sceneGl=n&&typeof n.drawingBufferWidth=="number"?n:null}if(!e.sceneGl)return;let i=Ii(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(Fi("[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:n}=this._eyeSize(e,t);e.eyeW=i,e.eyeH=n,e.canvas.width=t?i*2:i,e.canvas.height=n,e.sbs=t}_startSizeWatch(e){if(typeof ResizeObserver=="function"&&!e.sizeObserver){if(e.kind==="scene"){if(!e.onResize)return;e.resizeBox=Xi(e.canvas),e.sizeObserver=new ResizeObserver(()=>this._onSceneResize(e)),e.sizeObserver.observe(e.canvas);return}!e.ownsBuffer||e.reqW&&e.reqH||(e.sizeObserver=new ResizeObserver(()=>this._onBoxChange(e)),e.sizeObserver.observe(e.canvas))}}_onSceneResize(e){if(!e.layer||!e.onResize||e.inResize)return;let t=Xi(e.canvas),i=e.resizeBox;if(!(i&&i.width===t.width&&i.height===t.height&&i.dpr===t.dpr)){e.resizeBox=t,e.inResize=!0;try{e.onResize(t)}catch(n){e.resizeThrewWarned||(e.resizeThrewWarned=!0,console.warn("[inline3d] a scene window's onResize threw; further throws from it are silent.",n))}finally{e.inResize=!1}}}_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:n}=this._eyeSize(e);i===e.eyeW&&n===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 n=e.kind==="video"?e.video:e.img;if(!n)return;if(e.kind==="video"&&(n.readyState||0)<2){i&&this._recommitLastFrame(e);return}let s=e.canvas,o=e.ctx,a=n.videoWidth||n.naturalWidth||n.width,l=n.videoHeight||n.naturalHeight||n.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:p,h:y}=this._eyeSize(e,e.sbs);(p!==e.eyeW||y!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let f=e.bufScale||1,m=e.cornerRadius*f,h=e.feather*f;if(o.clearRect(0,0,s.width,s.height),!e.sbs){Ne(o,n,0,0,a/2,l,0,0,s.width,s.height,m,h);return}let d=s.width/2,u=Math.min(this._stereoFactor,this._bakedStereo);if(u<1){Ne(o,n,0,0,a/2,l,0,0,d,s.height,m,h),Yn(o,n,a/2,l,d,s.height,u,m,h);return}m>0||h>0?(Ne(o,n,0,0,a/2,l,0,0,d,s.height,m,h),Ne(o,n,a/2,0,a/2,l,d,0,d,s.height,m,h)):o.drawImage(n,0,0,a,l,0,0,s.width,s.height)}_bindTrackingEvents(){let e=this.session;!e||typeof e.addEventListener!="function"||this._trackingSupported&&e.addEventListener(Dt,()=>{this._setTrackingState(We(e)||"unknown")})}_setTrackingState(e){let t=Ji.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:Dt,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(We(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,n=this._bakedTarget;if(i===n)return;let s=this._bakedEaseS>0?t/this._bakedEaseS:1;this._bakedStereo=n>i?Math.min(n,i+s):Math.max(n,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,n)=>{t===this._loopId&&(this._framePending=!1,this._frameCount++,this._frame(i,n))})}catch{this._framePending=!1}}_frame(e,t){if(!this._running)return;this._requestFrame(),this._advanceModeSwitch();let i=this.refSpace?t.getViewerPose(this.refSpace):null,n=i?i.views:null;this._trackBakedStereo(e);for(let s of this._windows.values())if(s.layer){if(s.rc&&this._rectCoverCheck(s),s.kind==="scene"){if(n&&s.onFrame){if(s.frames++,n.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(n,s.layer,t),n.length>=2&&(s.fwStereo=!0,s.lfStereo=!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,n),s.sbs&&(s.kind==="video"?(s.video&&s.video.readyState||0)>=2:s.img)&&(s.fwStereo=!0,s.lfStereo=!0,s.rw&&(s.rw.stereo=!0));s.rc&&s.rc.snapWanted&&this._rectCoverSnap(s),(!s.layerFramed||s.framedWaiters.length)&&this._tickLayerFramed(s),this._tickFirstWoven(s)}}_tickFirstWoven(e){let t=e.wsLive&&e.layer?je(e.layer):null;if(t){this._tickWovenState(e,t);return}if(e.rw){this._noteRewovenBox(e);let i=e.rw,n=N();i.stereo&&n-i.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):i.at>i.calledAt&&n-i.calledAt>=kt*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")}_tickWovenState(e,t){let i=N(),n=kt*Math.max(e.fwHoldMs,Lt);if(e.rw){this._noteRewovenBox(e);let s=e.rw;t!=="woven"?s.gap=!0:s.stereo&&(s.gap||s.boxFrame!==null&&this._frameCount-s.boxFrame>=Hi||s.boxFrame===null&&this._frameCount-s.callFrame>=Hi)&&this._settleRewoven(e,!0,"woven",!0),e.rw&&i-s.calledAt>=n&&(t==="woven"?this._settleRewoven(e,!0,"hold-capped",!0):this._settleRewoven(e,!1,Ct(e.layer)||t,!0))}e.fwResult||e.fwLayerAt===null||(e.fwStereo&&t==="woven"?this._settleFirstWoven(e,!0,"woven",!0):i-e.fwLayerAt>=n&&(t==="woven"?this._settleFirstWoven(e,!0,"hold-capped",!0):this._settleFirstWoven(e,!1,Ct(e.layer)||t,!0)))}_settleFirstWoven(e,t,i,n=!1){!t&&!n&&(e.rwGone||(e.rwGone=i),this._settleRewoven(e,!1,i)),!e.fwResult&&(e.fwResult=Object.freeze({woven:t,confirmed:n,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&&!e.fwResult.confirmed)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}),n=N();return e.rw={promise:i,resolve:t,calledAt:n,at:n,stereo:!1,box:Tt(e.canvas),gap:!1,boxFrame:null,callFrame:this._frameCount},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=Tt(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=N(),e.rw.stereo=!1,e.rw.gap=!1,e.rw.boxFrame=this._frameCount)}_settleRewoven(e,t,i,n=!1){let s=e.rw;s&&(e.rw=null,s.resolve(Object.freeze({woven:t,confirmed:n,reason:i,ms:Math.round(N()-s.calledAt)})))}_rectCoverCheck(e){let t=e.rc,i=Tt(e.canvas);if(i===t.box)return;let n=t.box===null,s=t.w,o=t.h;if(t.box=i,t.w=e.canvas.clientWidth||0,t.h=e.canvas.clientHeight||0,n)return;t.up&&this._placeCover(e);let a=e.fwResult;if(!a||e.rwGone||!(a.woven||a.confirmed))return;t.up||(t.snapped||(t.aspect=o>0?s/o:0),this._raiseCover(e)),t.cfg.snapshot&&!t.snapped&&t.w>0&&t.h>0&&(t.snapWanted=!0);let l;e.rw?(this._noteRewovenBox(e),l=e.rw.promise):(l=this._rewoven(e),e.rw&&(e.rw.boxFrame=this._frameCount)),t.waiting!==l&&(t.waiting=l,l.then(()=>{t.waiting===l&&(t.waiting=null,this._lowerCover(e))}))}_raiseCover(e){let t=e.rc;if(!t.el){if(typeof document>"u"||!document||typeof document.createElement!="function"||!e.canvas.parentElement)return;let i=document.createElement("canvas");i.setAttribute?.("aria-hidden","true"),i.dataset&&(i.dataset.inline3dCover="");let n=i.style;n.position="absolute",n.pointerEvents="none",n.margin="0",n.border="0",n.padding="0",n.background=t.cfg.color,n.display="none";try{let s=typeof getComputedStyle=="function"?getComputedStyle(e.canvas).zIndex:"auto";s&&s!=="auto"&&(n.zIndex=s)}catch{}t.el=i}this._placeCover(e),t.el.style.display="block",t.up=!0,this._fullTileWarned.add(t.el),this._applyExclusion(e,t.el)}_placeCover(e){let i=e.rc.el,n=e.canvas;if(!i)return;let s=n.parentElement;s&&(i.parentElement!==s||i.previousSibling!==n)&&s.insertBefore(i,n.nextSibling);let o=i.style;if(n.offsetParent)o.position="absolute",o.left=`${n.offsetLeft}px`,o.top=`${n.offsetTop}px`,o.width=`${n.offsetWidth}px`,o.height=`${n.offsetHeight}px`;else{let a=n.getBoundingClientRect();o.position="fixed",o.left=`${a.left??a.x??0}px`,o.top=`${a.top??a.y??0}px`,o.width=`${a.width}px`,o.height=`${a.height}px`}}_rectCoverSnap(e){let t=e.rc;t.snapWanted=!1;let i=t.el,n=e.canvas;if(!i||!t.up||!(n.width>1)||!(n.height>0))return;let s=Math.max(1,Math.round(t.w)),o=Math.max(1,Math.round(t.h)),a=s/o,l=t.aspect>0?t.aspect:n.width/2/n.height,c=1,f=1;a>l?f=l/a:c=a/l;let m=n.width/2*c,h=n.height*f,d=(n.width/2-m)/2,u=(n.height-h)/2;try{i.width=s,i.height=o;let p=i.getContext("2d");if(!p)return;p.drawImage(n,d,u,m,h,0,0,s,o),t.snapped=!0}catch{}}_lowerCover(e){let t=e.rc;t&&(t.up=!1,t.snapped=!1,t.snapWanted=!1,t.el&&(t.el.style.display="none",this._dropExclusion(e,t.el)))}_dropCover(e){let t=e.rc;t&&(t.waiting=null,this._lowerCover(e),t.el&&t.el.parentElement&&t.el.parentElement.removeChild(t.el),t.el=null)}_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,B===this&&(B=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._dropCover(e),this._noteLayerFramed(e,!1)}this._windows.clear(),this._claims.clear(),this._setTrackingState("unknown"),this._displayListeners.clear()}}};function Gn(r){return typeof r=="number"&&Number.isFinite(r)&&r>=0?r:Lt}function Jn(r){return typeof r!="string"?Promise.resolve(r):new Promise((e,t)=>{let i=new Image;i.decoding="async",i.onload=()=>e(i),i.onerror=t,i.src=r})}function Ne(r,e,t,i,n,s,o,a,l,c,f,m){f>0&&r.roundRect?(r.save(),r.beginPath(),r.roundRect(o,a,l,c,f),r.clip(),r.drawImage(e,t,i,n,s,o,a,l,c),r.restore()):r.drawImage(e,t,i,n,s,o,a,l,c),m>0&&Qi(r,o,a,l,c,m)}function Yn(r,e,t,i,n,s,o,a,l){r.save(),a>0&&r.roundRect&&(r.beginPath(),r.roundRect(n,0,n,s,a),r.clip()),r.drawImage(e,0,0,t,i,n,0,n,s),o>0&&(r.globalAlpha=o,r.drawImage(e,t,0,t,i,n,0,n,s)),r.restore(),l>0&&Qi(r,n,0,n,s,l)}function Qi(r,e,t,i,n,s){let o=Math.min(s,Math.floor(Math.min(i,n)/2));if(o<=0)return;r.save(),r.globalCompositeOperation="destination-out";let a=[[e,t,i,o,[e,t],[e,t+o]],[e,t+n-o,i,o,[e,t+n],[e,t+n-o]],[e,t,o,n,[e,t],[e+o,t]],[e+i-o,t,o,n,[e+i,t],[e+i-o,t]]];for(let[l,c,f,m,h,d]of a){let u=r.createLinearGradient(h[0],h[1],d[0],d[1]);u.addColorStop(0,"rgba(0,0,0,1)"),u.addColorStop(1,"rgba(0,0,0,0)"),r.fillStyle=u,r.fillRect(l,c,f,m)}r.restore()}function oe(r,e){return r>0&&e>0&&r/e>2.5}function U(r,e,t,i,n){let s=Math.abs(i||0),o=Math.min(r-2*s,e*t);o=Math.max(1,o);let a=Math.min(e,o/t);o=a*t;let l=(r-o)/2+(n===0?i:-i);return{sx:Math.max(0,Math.min(r-o,l)),sy:(e-a)/2,sw:o,sh:a}}function Se(r,e,t){let i=Math.min(r,e*t),n=i/t;return{w:Math.max(2,Math.round(i/2)*2),h:Math.max(2,Math.round(n/2)*2)}}function ae(r,e){let t=r/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 Pt(r,e,t){let i=new r.constructor(r.length);for(let n of ae(e,t))for(let s=0;s<t;s++)for(let o=0;o<n.dw;o++){let a=n.sx+(n.sw-1-o);i[s*e+n.dx+o]=r[s*e+a]}return i}function er(r,e){return!(r>0)||!(e>0)||e>=180?null:r/2/Math.tan(e/2*Math.PI/180)}function He({eyeWidthPx:r,hfovDeg:e,baselineMm:t,subjectZmm:i}){let n=er(r,e);return n===null||!(t>0)||!(i>0)?0:n*t/(2*i)}function $e(r,e,t=.2){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,r||0))}function Ue(r,e,t=.2){let i=r+t*(e-r);return Math.abs(e-i)<.05?e:i}function Me(){let r={hello:null,subjectZmm:null,measuredPx:null,depth:0,current:0,target(e){let t=r.measuredPx!==null?r.measuredPx/2:r.hello&&r.subjectZmm?He({eyeWidthPx:e,hfovDeg:r.hello.hfovDeg,baselineMm:r.hello.baselineMm,subjectZmm:r.subjectZmm}):0;return $e(t+r.depth*.05*e,e)},step(e){return r.current=Ue(r.current,r.target(e)),r.current}};return r}var Ve=1,It="inline3d-call/1",tr=Object.freeze(["sbs","mono"]),le=4,ir=4,Ft=5,Kn=150,Zn=5e3,Qn=/^[A-Za-z0-9_-]{16,64}$/,es=16;function Wt(r){let e=new Uint8Array(es);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),nr(e)}function rr(r){let e=new Uint8Array(8);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),nr(e)}function nr(r){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",t="",i=0;for(;i+2<r.length;i+=3){let s=r[i]<<16|r[i+1]<<8|r[i+2];t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]+e[s&63]}let n=r.length-i;if(n===1){let s=r[i]<<16;t+=e[s>>18&63]+e[s>>12&63]}else if(n===2){let s=r[i]<<16|r[i+1]<<8;t+=e[s>>18&63]+e[s>>12&63]+e[s>>6&63]}return t}function ce(r){return typeof r=="string"&&Qn.test(r)}function Ee(r){if(!r)return null;let e="";if(typeof r=="object")e=r.hash||r.href&&String(r.href).split("#")[1]||"";else{let t=String(r),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 n=decodeURIComponent(t.slice(i+1));return ce(n)?n:null}return null}function Be(r,e){if(!ce(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(r||"").split("#")[0]}#room=${e}`}function jt(r){if(!r||typeof r!="object"||r.type!=="hello")return null;let e=(t,i,n)=>typeof t=="number"&&Number.isFinite(t)&&t>=i&&t<=n?t:null;return{type:"hello",v:typeof r.v=="number"?r.v:Ve,format:tr.includes(r.format)?r.format:"mono",width:e(r.width,1,16384),height:e(r.height,1,16384),baselineMm:e(r.baselineMm,1,1e3),hfovDeg:e(r.hfovDeg,5,170),rectified:r.rectified===!0,sdk:typeof r.sdk=="string"?r.sdk.slice(0,64):null}}function Nt({format:r,width:e,height:t,baselineMm:i,hfovDeg:n,rectified:s}={}){let o={type:"hello",v:Ve,format:tr.includes(r)?r:"mono",width:e||0,height:t||0,rectified:!!s,sdk:It};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(n)&&(o.hfovDeg=n),o}function zt(r){if(!r||r.type!=="hint")return null;let e=r.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=Kn&&e<=Zn?{type:"hint",subjectZmm:e}:null}function sr(r){return!r||r.type!=="state"?null:{type:"state",muted:r.muted===!0,cameraOff:r.cameraOff===!0,speaking:r.speaking===!0}}function Ht(r){let e=1e3/r,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function $t({format:r,woven:e,mono3D:t="auto",lift:i=!1,overBudget:n=!1,failed:s=!1}){return(r==="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"}:n?{route:"flat",mono3d:"budget"}:{route:"lifted",mono3d:"lifted"}:{route:"flat",mono3d:"unavailable"}:{route:"flat"}}function Ut(r){return r==="woven-sbs"?"3D":r==="lifted"?"2D\u21923D":"2D"}function Vt({need:r=10,needNoPose:e=30}={}){let t=0,i=0,n=!1;return{feed(s){return n?!0:(i++,s===null?n=i>=e:(t=s>=1?t+1:0,n=t>=r),n)},get live(){return n}}}function qe(r,e){let t=Math.max(1,e|0),n=r==="sbs"?[6e3,4e3,3e3]:[2500,1800,1400];return n[Math.min(t,n.length)-1]}function q(r,{baseMs:e=1e3,maxMs:t=3e4,rand:i=Math.random}={}){let n=Math.min(t,e*Math.pow(2,Math.max(0,r)));return Math.round(n*(.8+.4*i()))}var Re=Object.freeze(["VP9","VP8","AV1"]);function is(r,e=Re){let t=e.indexOf(String(r||"").toUpperCase());return t<0?e.length:t}function Xe(r,e=Re){let t=i=>is(String(i.mimeType||"").split("/")[1],e);return r.map((i,n)=>({c:i,i:n,r:t(i)})).sort((i,n)=>i.r-n.r||i.i-n.i).map(i=>i.c)}function Ce(r,e=Re){if(!r)return r;let t=r.includes(`\r
|
|
3
3
|
`)?`\r
|
|
4
4
|
`:`
|
|
5
|
-
`,i=r.split(t),n=i.findIndex(d=>d.startsWith("m=video"));if(n<0)return r;let s=i.findIndex((d,u)=>u>n&&d.startsWith("m="));s<0&&(s=i.length);let o=i.slice(n,s),a=new Map,l=new Map;for(let d of o){let u=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);u&&a.set(u[1],u[2].toUpperCase());let f=d.match(/^a=fmtp:(\d+) apt=(\d+)/);f&&(l.has(f[2])||l.set(f[2],[]),l.get(f[2]).push(f[1]))}let c=i[n].split(" "),p=c.slice(3),m=[];for(let d of e)for(let u of p)if(a.get(u)===d&&!m.includes(u)){m.push(u);for(let f of l.get(u)||[])p.includes(f)&&!m.includes(f)&&m.push(f)}if(!m.length)return r;let h=p.filter(d=>!m.includes(d));return i[n]=[...c.slice(0,3),...m,...h].join(" "),i.join(t)}var sr=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),Qn=4e3,es=1e4,ts=2e4,is=8e3,rs=1e4;function ke(r){let e=Number.isInteger(r)?r:le;return Math.max(2,Math.min(tr,e))}function or(r,e){return r<e}var Ce=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:n,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:rs,this.signaling=e,this.id=t,this.maxPeers=ke(i),this.pageIce=n||null,this.iceServers=n||sr,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:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:m}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:p,onGhost:m};let h=f=>(...y)=>this.ready?f(...y):this._pending.push(()=>f(...y));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(f=>this._onPeerJoined(f)),onPeerLeft:h(f=>this._onPeerLeftSignaling(f)),onSignal:h((f,y)=>this._onSignal(f,y)),onDisconnect:f=>p?.(f?"closed":"reconnecting",f),onPeerUnreachable:h(f=>m?.(f,!0)),onPeerReachable:h(f=>m?.(f,!1)),onReconnect:h(f=>{p?.("connected");for(let y of f)this._onPeerJoined(y)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...sr,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let f=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw f.code="room-full",f}this.ready=!0;for(let f of d)this._onPeerJoined(f);let u=this._pending;this._pending=[];for(let f of u)f();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"&&or(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),is)}_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:or(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 n=i.createDataChannel("dxr-call",{negotiated:!0,id:0,ordered:!0});if(this._wireDc(e,n),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,ts,()=>{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,n=await i.createOffer(t?{iceRestart:!0}:void 0);this._canPreferCodecs||(n.sdp=Re(n.sdp)),await i.setLocalDescription(n),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 n=t.gen|0;try{switch(t.kind){case"offer":{if(i.offerer||(clearTimeout(i.waitTimer),n<i.gen))return;i.offerAt=Date.now(),(n>i.gen||!i.pc)&&this._build(i,n);let s=i.pc;await s.setRemoteDescription({type:"offer",sdp:t.sdp}),this._attachAnswererTracks(i);let o=await s.createAnswer();this._canPreferCodecs||(o.sdp=Re(o.sdp)),await s.setLocalDescription(o),this._signal(i,{kind:"answer",sdp:s.localDescription.sdp}),this._flushCandidates(i);break}case"answer":if(!i.offerer||n!==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(n!==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 n of t.getTransceivers()){let s=n.receiver&&n.receiver.track?n.receiver.track.kind:null;if(!s||n.sender.track)continue;let o=i.find(a=>a.kind===s);o&&(n.sender.replaceTrack(o).catch(()=>{}),this.localStream&&n.sender.setStreams&&n.sender.setStreams(this.localStream)),n.direction="sendrecv",s==="video"&&this._preferCodecs(n)}}_preferCodecs(e){let t=globalThis.RTCRtpReceiver&&RTCRtpReceiver.getCapabilities&&RTCRtpReceiver.getCapabilities("video");if(this._canPreferCodecs=!!(e&&e.setCodecPreferences&&t),!!this._canPreferCodecs)try{e.setCodecPreferences(Xe(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,Qn,()=>{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,es,()=>{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=q(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,q(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 n=setTimeout(()=>{e.timers.delete(n),i()},t);e.timers.add(n)}_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 n;try{n=JSON.parse(i.data)}catch{return}if(n&&n.type==="bye")return this._drop(e,"left");this.cb.onMessage?.(e.id,n)}}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 n of this.peers.values())if(n.pc)for(let s of n.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=qe(this.sendFormat,e);for(let i of this.peers.values())if(i.pc){for(let n of i.pc.getSenders())if(!(!n.track||n.track.kind!=="video"))try{let s=n.getParameters();s.degradationPreference="maintain-resolution",(!s.encodings||!s.encodings.length)&&(s.encodings=[{}]),s.encodings[0].maxBitrate=t*1e3,await n.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 ar={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},Bt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},ns=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function ss(r){return!!r&&(r.name==="NotReadableError"||r.name==="TrackStartError"||/in use|busy/i.test(r.message||""))}function os(r){return!!r&&(r.name==="NotAllowedError"||r.name==="PermissionDeniedError"||r.name==="SecurityError")}function lr(r){return r.length&&r.every(e=>e.busy)?"camera-busy":r.some(e=>e.denied)?"permission-denied":"no-camera"}function qt(r){return/stereo|\b3d\b|\bsbs\b|dual/i.test(r||"")}async function cr(r="auto",e={}){let t=e.mediaDevices||globalThis.navigator&&navigator.mediaDevices,i=e.log||(()=>{}),n=[],s=e.calibration||{};if(r&&typeof r=="object"&&typeof r.getVideoTracks=="function"){let u=r.getVideoTracks()[0],f=u?u.getSettings():{},y=e.format==="sbs"?"sbs":"mono";return{stream:r,format:y,width:f.width||0,height:f.height||0,deviceId:f.deviceId||null,label:u?u.label:"",owned:!1,skipped:n,calibration:s}}if(!t||!t.getUserMedia)throw Object.assign(new Error("getUserMedia is not available (insecure context?)"),{code:"no-camera"});let o=async u=>{let f=await t.getUserMedia({video:u,audio:!1}),y=f.getVideoTracks()[0],v=y?y.getSettings():{};if(!y||y.readyState==="ended"||!(v.width>0)||!(v.height>0))throw f.getTracks().forEach(k=>k.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=v.displayxrStereo&&v.displayxrStereo.layout==="side-by-side"?v.displayxrStereo:null;return{stream:f,track:y,width:v.width,height:v.height,deviceId:v.deviceId||null,label:y.label||"",stereo:b}},a=(u,f)=>{n.push({label:u,error:`${f.name}: ${f.message}`,busy:ss(f),denied:os(f)}),i("camera-skip",{label:u,error:f.name})},l=u=>u&&u.stream.getTracks().forEach(f=>f.stop()),c=(u,f)=>({stream:u.stream,format:f,width:u.width,height:u.height,deviceId:u.deviceId,label:u.label,owned:!0,skipped:n,calibration:{rectified:!1,...f==="sbs"&&u.stereo?{rectified:!!u.stereo.rectified,...u.stereo.baselineMm>0?{baselineMm:u.stereo.baselineMm}:{},...u.stereo.horizontalFovDeg>0?{hfovDeg:u.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof r=="string"&&!["auto","stereo","mono"].includes(r)){let u;try{u=await o({deviceId:{exact:r},...Bt})}catch(f){throw a(r,f),Object.assign(new Error(`camera unavailable: ${f.message}`),{code:lr(n),skipped:n})}return oe(u.width,u.height)?c(u,"sbs"):(l(u),c(await o({deviceId:{exact:r},...ar}),"mono"))}let p=new Set;if(r!=="mono"){let u=[];try{u=(await t.enumerateDevices()).filter(f=>f.kind==="videoinput"&&f.deviceId&&qt(f.label))}catch{}for(let f of u){p.add(f.deviceId);let y=null;try{y=await o({deviceId:{exact:f.deviceId},...Bt})}catch(v){a(f.label,v);continue}if(oe(y.width,y.height))return i("camera-sbs",{label:y.label,width:y.width,height:y.height,direct:!0}),c(y,"sbs");l(y)}}let m=null;try{m=await o(ar)}catch(u){a("default",u)}if(r==="mono"&&m)return c(m,"mono");if(m&&oe(m.width,m.height))return c(m,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput")}catch{}h.sort((u,f)=>Number(qt(f.label))-Number(qt(u.label)));for(let u of h){if(!u.deviceId||m&&u.deviceId===m.deviceId||p.has(u.deviceId))continue;let f=null;try{f=await o({deviceId:{exact:u.deviceId},...Bt})}catch(y){a(u.label,y);continue}if(oe(f.width,f.height))return l(m),i("camera-sbs",{label:f.label,width:f.width,height:f.height}),c(f,"sbs");l(f)}if(m)return r==="stereo"&&i("camera-no-stereo",{fallback:m.label}),c(m,"mono");let d=lr(n);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:n})}async function hr(r={}){let e=r.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...ns},video:!1})).getAudioTracks()[0]||null}catch(t){return(r.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Gt();Jt();var gr="http://displayxr.org/ns/stereo/1.0/",Ze="http://ns.adobe.com/xap/1.0/\0";function et(r={}){let e=i=>typeof i=="number"&&Number.isFinite(i)?i:null,t=r.layout==="sbs"||r.layout==="side-by-side"?"sbs":"mono";return{layout:t,columns:t==="sbs"?2:1,rows:1,convergencePx:e(r.convergencePx),baselineMm:e(r.baselineMm),horizontalFovDeg:e(r.horizontalFovDeg),rectified:r.rectified===!0?!0:r.rectified===!1?!1:null,eyeWidth:e(r.eyeWidth),eyeHeight:e(r.eyeHeight),software:typeof r.software=="string"&&r.software?r.software:null}}var fs=r=>String(r).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),de=r=>Math.round(r*1e3)/1e3;function _r(r){let e=et(r),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:de(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:de(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:de(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,n])=>` dxr:${i}="${fs(n)}"`).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="${gr}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Kt(r){if(typeof r!="string"||!r.includes(gr))return null;let e=o=>{let a=new RegExp(`\\bdxr:${o}="([^"]*)"`).exec(r);if(a)return a[1];let l=new RegExp(`<dxr:${o}>([^<]*)</dxr:${o}>`).exec(r);return l?l[1]:null},t=o=>{let a=e(o);return a===null||a===""||!Number.isFinite(+a)?null:+a},i=e("Rectified"),n=e("Layout"),s=e("Software");return et({layout:n==="side-by-side"||n==="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(/"/g,'"').replace(/</g,"<").replace(/&/g,"&")})}var Qe=r=>new TextEncoder().encode(r),Yt=r=>new TextDecoder().decode(r),yr=r=>r.length>4&&r[0]===255&&r[1]===216;function*vr(r){let e=2;for(;e+4<=r.length;){if(r[e]!==255)return;let t=r[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=r[e+2]<<8|r[e+3];if(i<2||e+2+i>r.length)return;yield{marker:t,start:e,end:e+2+i,data:r.subarray(e+4,e+2+i)},e+=2+i}}function wr(r,e){if(r.length<e.length)return!1;for(let t=0;t<e.length;t++)if(r[t]!==e.charCodeAt(t))return!1;return!0}function br(r,e){if(!yr(r))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Qe(Ze),...Qe(e)]),i=t.length+2;if(i>65535)throw new RangeError("jpegWithXmp: XMP packet too large for one APP1 segment");let n=new Uint8Array(4+t.length);n[0]=255,n[1]=225,n[2]=i>>8,n[3]=i&255,n.set(t,4);let s=2,o=null;for(let p of vr(r)){if(p.marker===225&&wr(p.data,Ze)){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(r.length-(l-a)+n.length);return c.set(r.subarray(0,a),0),c.set(n,a),c.set(r.subarray(l),a+n.length),c}function Zt(r){if(!yr(r))return null;for(let e of vr(r))if(e.marker===225&&wr(e.data,Ze))return Yt(e.data.subarray(Ze.length));return null}var xr=r=>Kt(Zt(r)),$={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},ps=r=>r.length>4&&r[0]===26&&r[1]===69&&r[2]===223&&r[3]===163;function Sr(r){let e=[];for(let t=r;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function Mr(r,e=0){let t=e;if(!t)for(t=1;t<8&&r>2**(7*t)-2;t++);let i=new Array(t).fill(0),n=r;for(let s=t-1;s>=1;s--)i[s]=n%256,n=Math.floor(n/256);return i[0]=128>>t-1|n,i}function Qt(r,e){let t=r[e],i=t>=128?1:t>=64?2:t>=32?3:t>=16?4:0;if(!i||e+i>r.length)return null;let n=0;for(let s=0;s<i;s++)n=n*256+r[e+s];return{id:n,width:i}}function Le(r,e){let t=r[e],i=1;for(;i<=8&&!(t&128>>i-1);)i++;if(i>8||e+i>r.length)return null;let n=t&255>>i,s=n===127>>i-1;for(let o=1;o<i;o++)n=n*256+r[e+o],r[e+o]!==255&&(s=!1);return{size:n,width:i,unknown:s}}function he(r,e){return[...Sr(r),...Mr(e.length),...e]}function ms(r){let e=[];for(let[i,n]of Object.entries(r))n!=null&&e.push(...he($.SimpleTag,[...he($.TagName,[...Qe(String(i))]),...he($.TagString,[...Qe(String(n))])]));let t=he($.Tag,[...he($.Targets,[]),...e]);return new Uint8Array(he($.Tags,t))}function Er(r){let e=et(r);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(de(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(de(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(de(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 gs(r){if(!r||!("DXR_LAYOUT"in r))return null;let e=t=>r[t]===void 0||r[t]===""||!Number.isFinite(+r[t])?null:+r[t];return et({layout:r.DXR_LAYOUT==="side-by-side"?"sbs":"mono",convergencePx:e("DXR_CONVERGENCE_PX"),baselineMm:e("DXR_BASELINE_MM"),horizontalFovDeg:e("DXR_HFOV_DEG"),rectified:r.DXR_RECTIFIED===void 0?null:r.DXR_RECTIFIED==="true",eyeWidth:e("DXR_EYE_WIDTH"),eyeHeight:e("DXR_EYE_HEIGHT"),software:r.DXR_SOFTWARE??null})}function Rr(r){if(!ps(r))return null;let e=Le(r,4);if(!e)return null;let t=4+e.width+e.size;for(;t<r.length;){let i=Qt(r,t);if(!i)return null;let n=Le(r,t+i.width);if(!n)return null;let s=t+i.width+n.width;if(i.id===$.Segment)return{sizeAt:t+i.width,sizeWidth:n.width,unknown:n.unknown,dataStart:s,size:n.size};if(n.unknown)return null;t=s+n.size}return null}function Cr(r,e){let t=Rr(r);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=ms(e);if(t.unknown){let p=new Uint8Array(r.length+i.length);return p.set(r,0),p.set(i,r.length),p}let n=Math.min(r.length,t.dataStart+t.size),s=n-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=Mr(s,o?t.sizeWidth:8),l=new Uint8Array(t.sizeAt+a.length+(n-t.dataStart)+i.length+(r.length-n));l.set(r.subarray(0,t.sizeAt),0),l.set(a,t.sizeAt);let c=t.sizeAt+a.length;return l.set(r.subarray(t.dataStart,n),c),c+=n-t.dataStart,l.set(i,c),c+=i.length,l.set(r.subarray(n),c),l}function kr(r,e,t){let i={},n=(s,o,a)=>{let l=s;for(;l<o;){let c=Qt(r,l);if(!c)return;let p=Le(r,l+c.width);if(!p||p.unknown)return;let m=l+c.width+p.width;a(c.id,m,Math.min(o,m+p.size)),l=m+p.size}};return n(e,t,(s,o,a)=>{s===$.Tag&&n(o,a,(l,c,p)=>{if(l!==$.SimpleTag)return;let m=null,h=null;n(c,p,(d,u,f)=>{d===$.TagName?m=Yt(r.subarray(u,f)):d===$.TagString&&(h=Yt(r.subarray(u,f)))}),m!==null&&(i[m]=h??"")})}),i}function _s(r){let e=Rr(r);if(!e)return null;let t=e.unknown?r.length:Math.min(r.length,e.dataStart+e.size),i=null,n=e.dataStart;for(;n<t;){let s=Qt(r,n);if(!s)break;let o=Le(r,n+s.width);if(!o)break;let a=n+s.width+o.width;if(s.id===$.Tags&&!o.unknown&&(i={...i||{},...kr(r,a,Math.min(t,a+o.size))}),o.unknown){i=i||ys(r,t);break}n=a+o.size}return i}function ys(r,e){let t=Sr($.Tags);for(let i=e-t.length-1;i>=0;i--){if(r[i]!==t[0]||r[i+1]!==t[1]||r[i+2]!==t[2]||r[i+3]!==t[3])continue;let n=Le(r,i+4);if(n&&!n.unknown&&i+4+n.width+n.size===e)return kr(r,i+4+n.width,e)}return null}var Tr=r=>gs(_s(r));var ee="[inline3d/camera]",Vr="inline3d-camera/1",Ts=200,Ds=240,Ls=66,As=4e3,Os=4,Ps=1500,Is=2e4,Fs=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],st=()=>typeof document<"u"&&document&&typeof document.createElement=="function",Hr=()=>{let r=new Date,e=t=>String(t).padStart(2,"0");return`${r.getFullYear()}${e(r.getMonth()+1)}${e(r.getDate())}-${e(r.getHours())}${e(r.getMinutes())}${e(r.getSeconds())}`},Ws=r=>/jpe?g/.test(r)?"jpg":/png/.test(r)?"png":/webp/.test(r)?"webp":/mp4/.test(r)?"mp4":/webm/.test(r)?"webm":"bin";function ot(r,e,t){return`${String(r||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${Ws(t)}`}var Y=(r,e,t={})=>Object.assign(new Error(`${ee} ${r}`),{code:e,...t});function $r(r,e=As){return r?(r.readyState||0)>=2&&r.videoWidth?Promise.resolve():new Promise((t,i)=>{let n=!1,s=()=>{n||(r.readyState||0)<2||!r.videoWidth||(n=!0,clearTimeout(o),r.removeEventListener("loadeddata",s),r.removeEventListener("playing",s),r.removeEventListener("resize",s),t())},o=setTimeout(()=>{n||(n=!0,i(Y("the camera delivered no frame in time","no-frame")))},e);r.addEventListener("loadeddata",s),r.addEventListener("playing",s),r.addEventListener("resize",s),r.play?.().catch(()=>{})}):Promise.reject(Y("no video element (no document?)","no-frame"))}function Ur(r,e,t=Ds){let i=r.videoWidth,n=r.videoHeight;if(!i||!n||(r.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(n*s));(e.width!==o||e.height!==a)&&(e.width=o,e.height=a);let l=e.getContext("2d",{willReadFrequently:!0});try{return l.drawImage(r,0,0,o,a),{img:Je(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var ai=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,st()&&(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 n of this.stream.getVideoTracks())n.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(`${ee} 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(n){console.error(`${ee} '${e}' listener threw`,n)}}_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||!st())return null;try{await $r(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=Ur(this.video,this._scratch);if(!e)return null;let t=De().measure(e.img,e.w,e.h,0);return t?t.d/e.scale:null}_meta(e,t=this.width,i=this.height){let n=this.stereo;return{layout:this.format,convergencePx:e,baselineMm:n?n.baselineMm:null,horizontalFovDeg:n?n.horizontalFovDeg:null,rectified:n?n.rectified:null,eyeWidth:this.format==="sbs"?t/2:t,eyeHeight:i,software:Vr}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:n}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(!this.video||!st())throw Y("capturePhoto needs a document","no-frame");await $r(this.video);let s=this.video.videoWidth,o=this.video.videoHeight,a=typeof n=="number"&&Number.isFinite(n)?n: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,u)=>l.toBlob(f=>f?d(f):u(Y("toBlob produced nothing","encode-failed")),e,t)),p=this._meta(a,s,o),m=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(m=_r(p),c=new Blob([br(new Uint8Array(await c.arrayBuffer()),m)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:ot(i||`photo-${Hr()}`,this.format,c.type||e),xmp:m};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:n,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(typeof MediaRecorder!="function")throw Y("MediaRecorder is not available here","unsupported");let l=e||Fs.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw Y(`${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 m=new MediaStream(c),h={...l?{mimeType:l}:{},...n?{videoBitsPerSecond:n}:{}},d=new MediaRecorder(m,h),u=[];d.ondataavailable=g=>g.data&&g.data.size&&u.push(g.data);let f=null,y=[],v=null,b=0,k=!!t&&this.format==="sbs"&&st()&&this.video;if(k){v=document.createElement("canvas");let g=()=>{b=requestAnimationFrame(g);let _=this.video,M=_.videoWidth,O=_.videoHeight;!M||!O||(_.readyState||0)<2||((v.width!==M/2||v.height!==O)&&(v.width=M/2,v.height=O),v.getContext("2d").drawImage(_,0,0,M/2,O,0,0,M/2,O))};g();let w=v.captureStream(a);for(let _ of p)w.addTrack(_);f=new MediaRecorder(w,h),f.ondataavailable=_=>_.data&&_.data.size&&y.push(_.data)}let x=performance.now(),P=[],R=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&P.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&P.push(g)),d.start(s),f?.start(s),this.log("record-start",{mimeType:l,mono:k,audio:p.length});let L=(g,w)=>new Promise(_=>{if(!g||g.state==="inactive")return _(w);g.onstop=()=>_(w),g.stop()}),I=o||`clip-${Hr()}`,A=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),f&&f.state==="recording"&&f.pause()},resume(){d.state==="paused"&&d.resume(),f&&f.state==="paused"&&f.resume()},async stop(){clearInterval(R),b&&cancelAnimationFrame(b);let[g,w]=await Promise.all([L(d,u),L(f,y)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",M=[...P].sort((me,U)=>me-U),O=M.length?M[Math.floor(M.length/2)]:null,S=A._meta(O),F=/webm|matroska/.test(_),H=async(me,U)=>{let Z=new Blob(me,{type:_});if(F&&Z.size)try{Z=new Blob([Cr(new Uint8Array(await Z.arrayBuffer()),Er({...S,layout:U}))],{type:_})}catch(Mi){A.log("record-tag-failed",{message:String(Mi&&Mi.message)})}return Z},C=await H(g,A.format),W={blob:C,type:_,layout:A.format,durationMs:Math.round(performance.now()-x),convergencePx:O,stereo:A.stereo,suggestedName:ot(I,A.format,_),tagged:F&&C.size>0};return f&&(W.mono=await H(w,"mono"),W.monoSuggestedName=ot(I,"mono",_)),A.log("record-stop",{bytes:C.size,mono:W.mono?W.mono.size:null,ms:W.durationMs,convergencePx:O,name:W.suggestedName}),W}}}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 ci(r={}){let e=typeof r=="string"||r&&typeof r.getVideoTracks=="function"?{prefer:r}:r||{},t=e.prefer===void 0||e.prefer===null?"auto":e.prefer,i=typeof e.log=="function"?e.log:e.debug?(a,l)=>console.log(`${ee} ${a} ${JSON.stringify(l)}`):null,n=e.calibration&&typeof e.calibration=="object"?{...e.calibration}:{};n.horizontalFovDeg>0&&!(n.hfovDeg>0)&&(n.hfovDeg=n.horizontalFovDeg),delete n.horizontalFovDeg;let s=await cr(t,{format:e.format,calibration:n,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 ai(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 at=r=>!!r&&typeof r=="object"&&typeof r.capturePhoto=="function"&&typeof r.record=="function"&&r.stream&&typeof r.stream.getVideoTracks=="function";function js(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function hi(r,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${ee} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!at(t))throw new TypeError(`${ee} addCameraView: cam must be a StereoCamera from openCamera()`);let n=new li(r,e,t,i);return t._views?.add(n),n}var li=class{constructor(e,t,i,n){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=n.mirror===void 0?!0:!!n.mirror,this.aspect=typeof n.aspect=="number"&&n.aspect>.3&&n.aspect<4?n.aspect:16/9,this.autoConverge=!!n.autoConverge,this.conv=Se(),this.conv.depth=0,this.setDepth(n.depth),this.route=null,this.handle=null,this.fallbackReason=null,this._fw=null,this._onRouteChange=typeof n.onRouteChange=="function"?n.onRouteChange:null,this._layerFails=0,this._layerTimer=0,this.buffer=null,this.removed=!1,this._raf=0,this._loop=n._loop!==!1,this._autoAt=0,this._track=Ye(),this._focus=De(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=Ke(n.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(oi(),si)).then(s=>{this.removed||(this.cursor=new s.PairCursor(this.canvas,this._cursorOpt))}),this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}weaveState(){return{route:this.route,woven:this.woven,reason:this.fallbackReason,firstWoven:this.route==="woven-sbs"?this._fw?{...this._fw}:"pending":null,layerRetries:this._layerFails}}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;e&&this.fallbackReason&&(this.fallbackReason=null,clearTimeout(this._layerTimer),this._layerTimer=0);let i=this.cam,n=i.state==="live"&&i.video,o=i.format==="sbs"&&n&&this.wall&&this.wall.supported&&!this.fallbackReason?"woven-sbs":i.format==="sbs"?"flat-left":"flat";if(!e&&o===this.route)return;let a=this.route;this._unregister(),this.route=o,o==="woven-sbs"&&this._registerWoven(),o!==a&&this._routeChanged()}_registerWoven(){this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven();let e=this.wall.addImage(this.canvas,this.buffer);this.handle=e,this._fw=null;let t=e&&e.firstWoven;!t||typeof t.then!="function"||t.then(i=>{this.handle!==e||this.removed||!i||(this._fw={woven:!!i.woven,confirmed:!!i.confirmed,reason:i.reason||null,ms:i.ms},this.cam.log?.("view-first-woven",{woven:!!i.woven,reason:i.reason||null}),i.woven?(this._layerFails=0,this._routeChanged()):i.reason!=="removed"&&this._layerLost(i.reason||"layer-failed"))})}_layerLost(e){if(this.fallbackReason=e,this._reroute(!1),e!=="layer-failed"||this._layerFails>=Os)return;let t=Math.min(Is,Ps*Math.pow(2,this._layerFails++));this.cam.log?.("view-layer-retry",{attempt:this._layerFails,inMs:t}),clearTimeout(this._layerTimer),this._layerTimer=setTimeout(()=>{this._layerTimer=0,!(this.removed||this.fallbackReason!==e)&&this._reroute(!0)},t)}_routeChanged(){if(this._onRouteChange)try{this._onRouteChange(this.route,this.weaveState())}catch(e){console.error(`${ee} onRouteChange threw`,e)}}_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(this.cursor?.idle(),!js(this.canvas))return;let t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2)return;let n=this.canvas.getContext("2d"),s=this.route==="flat-left"?t/2:t,o=V(s,i,this.canvas.width/this.canvas.height,0,0);n.save(),this.mirror&&(n.translate(this.canvas.width,0),n.scale(-1,1)),n.drawImage(e,o.sx,o.sy,o.sw,o.sh,0,0,this.canvas.width,this.canvas.height),n.restore()}_paintWoven(){let e=this.cam.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.buffer)return;let n=t/2,s=this.aspect,{w:o,h:a}=xe(n,i,s),l=this.buffer;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.autoConverge||c)&&this._sample(e,c);let p=this.conv.step(n),m=l.getContext("2d");if(this.mirror)for(let h of ae(t,i)){let d=h.src==="L"?0:1,u=V(n,i,s,p,d),f=h.dx===0?0:o;m.save(),m.translate(f+o,0),m.scale(-1,1),m.drawImage(e,h.sx+u.sx,u.sy,u.sw,u.sh,0,0,o,a),m.restore()}else for(let h of[0,1]){let d=V(n,i,s,p,h);m.drawImage(e,h*n+d.sx,d.sy,d.sw,d.sh,h*o,0,o,a)}if(this.cursor){let h={rL:V(n,i,s,p,0),rR:V(n,i,s,p,1),outW:o,outH:a,mirror:this.mirror,handle:this.handle};this.cursor.draw(m,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?Ls:Ts))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let n=Ur(e,this._scratch);if(n&&(this._luma=n),!this.autoConverge)return;let s=n?this._focus.measure(n.img,n.w,n.h,i):null,o=this._track.push(s?s.d/n.scale:null);this.conv.measuredPx=o,this.disparityPx=o}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,clearTimeout(this._layerTimer),this._layerTimer=0,this._unregister(),this.cursor?.dispose(),this.cursor=null,this.cam._views?.delete(this))}};var qr=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],Xr=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Ns=[1,0],di=10;function Gr(r){let e=(16*r+128)*r+64;if(r>=2){let t=Math.floor(r/7)+2;e-=(25*t-10)*t-55,r>=7&&(e-=36)}return e}var Br=(r,e)=>Math.floor(Gr(r)/8)-qr[e][r]*Xr[e][r];function ui(r,e){let t=0;for(let i=7;i>=0;i--)t=t<<1^(t>>>7)*285,t^=(e>>>i&1)*r;return t}function zs(r){let e=new Array(r-1).fill(0);e.push(1);let t=1;for(let i=0;i<r;i++){for(let n=0;n<e.length;n++)e[n]=ui(e[n],t),n+1<e.length&&(e[n]^=e[n+1]);t=ui(t,2)}return e}function Hs(r,e){let t=e.map(()=>0);for(let i of r){let n=i^t.shift();t.push(0),e.forEach((s,o)=>t[o]^=ui(s,n))}return t}function fi(r,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(r))],n=1;for(;n<=di&&!(4+(n<=9?8:16)+i.length*8<=Br(n,t)*8);n++);if(n>di)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${di} code`);let s=[],o=(g,w)=>{for(let _=w-1;_>=0;_--)s.push(g>>>_&1)};o(4,4),o(i.length,n<=9?8:16);for(let g of i)o(g,8);let a=Br(n,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=Xr[t][n],p=qr[t][n],m=Math.floor(Gr(n)/8),h=c-m%c,d=Math.floor(m/c),u=zs(p),f=[];for(let g=0,w=0;g<c;g++){let _=l.slice(w,w+d-p+(g<h?0:1));w+=_.length;let M=Hs(_,u);g<h&&_.push(0),f.push(_.concat(M))}let y=[];for(let g=0;g<f[0].length;g++)for(let w=0;w<f.length;w++)(g!==d-p||w>=h)&&y.push(f[w][g]);let v=n*4+17,b=Array.from({length:v},()=>new Array(v).fill(!1)),k=Array.from({length:v},()=>new Array(v).fill(!1)),x=(g,w,_)=>{b[w][g]=_,k[w][g]=!0};for(let g=0;g<v;g++)x(6,g,g%2===0),x(g,6,g%2===0);let P=(g,w)=>{for(let _=-4;_<=4;_++)for(let M=-4;M<=4;M++){let O=Math.max(Math.abs(M),Math.abs(_)),S=g+M,F=w+_;S>=0&&S<v&&F>=0&&F<v&&x(S,F,O!==2&&O!==4)}};P(3,3),P(v-4,3),P(3,v-4);let R=[];if(n>1){let g=Math.floor(n/7)+2,w=Math.ceil((n*4+4)/(g*2-2))*2;R.push(6);for(let _=v-7;R.length<g;_-=w)R.splice(1,0,_)}for(let g=0;g<R.length;g++)for(let w=0;w<R.length;w++)if(!(g===0&&w===0||g===0&&w===R.length-1||g===R.length-1&&w===0))for(let _=-2;_<=2;_++)for(let M=-2;M<=2;M++)x(R[g]+M,R[w]+_,Math.max(Math.abs(M),Math.abs(_))!==1);let L=g=>{let w=Ns[t]<<3|g,_=w;for(let S=0;S<10;S++)_=_<<1^(_>>>9)*1335;let M=(w<<10|_)^21522,O=S=>(M>>>S&1)!==0;for(let S=0;S<=5;S++)x(8,S,O(S));x(8,7,O(6)),x(8,8,O(7)),x(7,8,O(8));for(let S=9;S<15;S++)x(14-S,8,O(S));for(let S=0;S<8;S++)x(v-1-S,8,O(S));for(let S=8;S<15;S++)x(8,v-15+S,O(S));x(8,v-8,!0)};if(L(0),n>=7){let g=n;for(let _=0;_<12;_++)g=g<<1^(g>>>11)*7973;let w=n<<12|g;for(let _=0;_<18;_++){let M=(w>>>_&1)!==0,O=v-11+_%3,S=Math.floor(_/3);x(O,S,M),x(S,O,M)}}let I=0;for(let g=v-1;g>=1;g-=2){g===6&&(g=5);for(let w=0;w<v;w++)for(let _=0;_<2;_++){let M=g-_,S=(g+1&2)===0?v-1-w:w;!k[S][M]&&I<y.length*8&&(b[S][M]=(y[I>>>3]>>>7-(I&7)&1)!==0,I++)}}let A=g=>{for(let w=0;w<v;w++)for(let _=0;_<v;_++){if(k[w][_])continue;let M;switch(g){case 0:M=(_+w)%2===0;break;case 1:M=w%2===0;break;case 2:M=_%3===0;break;case 3:M=(_+w)%3===0;break;case 4:M=(Math.floor(_/3)+Math.floor(w/2))%2===0;break;case 5:M=_*w%2+_*w%3===0;break;case 6:M=(_*w%2+_*w%3)%2===0;break;default:M=((_+w)%2+_*w%3)%2===0}M&&(b[w][_]=!b[w][_])}},T=Number.isInteger(e.mask)?e.mask:-1;if(T<0){let g=1/0;for(let w=0;w<8;w++){A(w),L(w);let _=$s(b,v);_<g&&(g=_,T=w),A(w)}}return A(T),L(T),{version:n,size:v,mask:T,modules:b}}function $s(r,e){let t=0,i=[];for(let o=0;o<e;o++)i.push(r[o]);for(let o=0;o<e;o++)i.push(r.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 n=0;for(let o=0;o<e;o++)for(let a=0;a<e;a++)if(r[o][a]&&n++,a<e-1&&o<e-1){let l=r[o][a];l===r[o][a+1]&&l===r[o+1][a]&&l===r[o+1][a+1]&&(t+=3)}let s=e*e;return t+=Math.floor(Math.abs(n*20-s*10)/s)*10,t}function Jr(r,e,{px:t=4,dark:i="#000",light:n="#fff",ecl:s="M"}={}){let o=fi(e,{ecl:s}),a=o.size+8;r.width=r.height=a*t;let l=r.getContext("2d");l.fillStyle=n,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 K(r,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=r,t}async function pi(r){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(String(r)));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}var lt="wss://signal.displayxr.org",Yr=Object.freeze([lt,"wss://dxr-signal.displayxr.workers.dev"]),Kr=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function ue(r=lt,e={}){if(!r||typeof r!="string")throw K("no-signaling-url","dxrSignaling(url): url must be a ws:// or wss:// string (omit it for the hosted DisplayXR server)");let t=c=>String(c).replace(/\/+$/,""),i=t(r),n=e.WebSocket||globalThis.WebSocket,s=e.pingMs||2e4,o=Array.isArray(e.aliases)?e.aliases.filter(c=>typeof c=="string"&&c).map(t):Yr.includes(i)?[...Yr]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,p){let h=`k=${await pi(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=A=>`${a[A]}/v1/connect?${h}`,u=null,f=!1,y=0,v=null,b=new Set,k=[],x=A=>P(A,a.length),P=(A,T)=>new Promise((g,w)=>{let _=!1,M=!1,O=!1,S=new n(d(l));u=S;let F=H=>{if(!_){_=!0;try{S.close()}catch{}w(H)}};S.onopen=()=>{O=!0,S.send(JSON.stringify({t:"join",v:1,room:c,id:p.id,max:p.maxPeers}))},S.onmessage=H=>{let C;try{C=JSON.parse(typeof H.data=="string"?H.data:String(H.data))}catch{return}switch(C.t){case"welcome":{y=0;let W=Array.isArray(C.peers)?C.peers.filter(U=>typeof U=="string"):[];clearInterval(v),v=setInterval(()=>R({t:"ping"}),s);let me=k;k=[];for(let U of me)R(U);if(A){let U=new Set(W);for(let Z of b)U.has(Z)||p.onPeerLeft?.(Z);b=U,p.onReconnect?.(W)}else b=new Set(W);_=!0,M=!0,g({id:C.id,peers:W,iceServers:Array.isArray(C.iceServers)?C.iceServers:void 0,max:C.max,tier:C.tier==="key"?"key":"anon",key:typeof C.key=="string"?C.key:void 0,turn:C.turn&&typeof C.turn=="object"?C.turn:void 0});break}case"full":f=!0,F(K("room-full",`this call is full (${C.max} participants)`));break;case"expired":{f=!0,clearInterval(v);let W=K("expired","this room has reached its lifetime on the signalling server");_?p.onDisconnect?.(W):F(W);break}case"error":if(!_&&Kr.includes(C.code))f=!0,F(K(C.code,C.message||C.code));else if(!_&&(C.code==="rate-limited"||C.code==="quota")){let W=K(C.code,C.message||C.code);W.retryMs=C.retryMs>0?C.retryMs:0,F(W)}else!_&&C.code==="id-taken"&&F(K("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof C.id=="string"&&!b.has(C.id)&&(b.add(C.id),p.onPeerJoined?.(C.id));break;case"peer-left":typeof C.id=="string"&&(b.delete(C.id),p.onPeerLeft?.(C.id));break;case"signal":typeof C.from=="string"&&p.onSignal?.(C.from,C.data);break}},S.onerror=()=>{if(!O&&!_&&T>1){_=!0,l=(l+1)%a.length,P(A,T-1).then(g,w);return}F(K("signaling-unreachable",`cannot reach ${a[l]}`))},S.onclose=()=>{clearInterval(v),F(K("signaling-closed","signalling closed before joining")),M&&!f&&u===S&&L()}}),R=A=>{u&&u.readyState===1?u.send(JSON.stringify(A)):f||k.push(A)},L=()=>{p.onDisconnect?.();let A=()=>{f||x(!0).catch(T=>{if(f||T&&(T.code==="room-full"||Kr.includes(T.code))){p.onDisconnect?.(T);return}setTimeout(A,Math.max(q(y++,{baseMs:500,maxMs:15e3}),T&&T.retryMs||0))})};setTimeout(A,q(y++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(A,T)=>R({t:"signal",to:A,data:T}),leave:()=>{if(!f){f=!0,clearInterval(v);try{u&&u.readyState===1&&u.send(JSON.stringify({t:"leave"})),u&&u.close(1e3,"leave")}catch{}}}}}}}var mi=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),Qr=r=>typeof r=="string"&&mi[r.toLowerCase()]||r,en=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),Ae=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 tn(r){let e={...Ae,...r&&typeof r=="object"?r:{}};return(t,i)=>{let n=typeof e[t]=="string"?e[t]:Ae[t]||t;if(i)for(let[s,o]of Object.entries(i))n=n.split(`{${s}}`).join(String(o));return n}}var Zr="dxr-call-style",Bs=`
|
|
5
|
+
`,i=r.split(t),n=i.findIndex(d=>d.startsWith("m=video"));if(n<0)return r;let s=i.findIndex((d,u)=>u>n&&d.startsWith("m="));s<0&&(s=i.length);let o=i.slice(n,s),a=new Map,l=new Map;for(let d of o){let u=d.match(/^a=rtpmap:(\d+) ([\w-]+)\//);u&&a.set(u[1],u[2].toUpperCase());let p=d.match(/^a=fmtp:(\d+) apt=(\d+)/);p&&(l.has(p[2])||l.set(p[2],[]),l.get(p[2]).push(p[1]))}let c=i[n].split(" "),f=c.slice(3),m=[];for(let d of e)for(let u of f)if(a.get(u)===d&&!m.includes(u)){m.push(u);for(let p of l.get(u)||[])f.includes(p)&&!m.includes(p)&&m.push(p)}if(!m.length)return r;let h=f.filter(d=>!m.includes(d));return i[n]=[...c.slice(0,3),...m,...h].join(" "),i.join(t)}var or=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),ns=4e3,ss=1e4,os=2e4,as=8e3,ls=1e4;function Te(r){let e=Number.isInteger(r)?r:le;return Math.max(2,Math.min(ir,e))}function ar(r,e){return r<e}var ke=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:n,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:ls,this.signaling=e,this.id=t,this.maxPeers=Te(i),this.pageIce=n||null,this.iceServers=n||or,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:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:f,onGhost:m}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:f,onGhost:m};let h=p=>(...y)=>this.ready?p(...y):this._pending.push(()=>p(...y));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(p=>this._onPeerJoined(p)),onPeerLeft:h(p=>this._onPeerLeftSignaling(p)),onSignal:h((p,y)=>this._onSignal(p,y)),onDisconnect:p=>f?.(p?"closed":"reconnecting",p),onPeerUnreachable:h(p=>m?.(p,!0)),onPeerReachable:h(p=>m?.(p,!1)),onReconnect:h(p=>{f?.("connected");for(let y of p)this._onPeerJoined(y)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...or,...this.session.iceServers]);let d=this.session.peers||[];if(d.length>=this.maxPeers){this.session.leave();let p=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw p.code="room-full",p}this.ready=!0;for(let p of d)this._onPeerJoined(p);let u=this._pending;this._pending=[];for(let p of u)p();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"&&ar(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),as)}_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:ar(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 n=i.createDataChannel("dxr-call",{negotiated:!0,id:0,ordered:!0});if(this._wireDc(e,n),e.offerer){let s=this.localStream?this.localStream.getTracks():[],o=s.find(f=>f.kind==="audio"),a=s.find(f=>f.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,os,()=>{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,n=await i.createOffer(t?{iceRestart:!0}:void 0);this._canPreferCodecs||(n.sdp=Ce(n.sdp)),await i.setLocalDescription(n),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 n=t.gen|0;try{switch(t.kind){case"offer":{if(i.offerer||(clearTimeout(i.waitTimer),n<i.gen))return;i.offerAt=Date.now(),(n>i.gen||!i.pc)&&this._build(i,n);let s=i.pc;await s.setRemoteDescription({type:"offer",sdp:t.sdp}),this._attachAnswererTracks(i);let o=await s.createAnswer();this._canPreferCodecs||(o.sdp=Ce(o.sdp)),await s.setLocalDescription(o),this._signal(i,{kind:"answer",sdp:s.localDescription.sdp}),this._flushCandidates(i);break}case"answer":if(!i.offerer||n!==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(n!==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 n of t.getTransceivers()){let s=n.receiver&&n.receiver.track?n.receiver.track.kind:null;if(!s||n.sender.track)continue;let o=i.find(a=>a.kind===s);o&&(n.sender.replaceTrack(o).catch(()=>{}),this.localStream&&n.sender.setStreams&&n.sender.setStreams(this.localStream)),n.direction="sendrecv",s==="video"&&this._preferCodecs(n)}}_preferCodecs(e){let t=globalThis.RTCRtpReceiver&&RTCRtpReceiver.getCapabilities&&RTCRtpReceiver.getCapabilities("video");if(this._canPreferCodecs=!!(e&&e.setCodecPreferences&&t),!!this._canPreferCodecs)try{e.setCodecPreferences(Xe(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,ns,()=>{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,ss,()=>{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=q(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,q(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 n=setTimeout(()=>{e.timers.delete(n),i()},t);e.timers.add(n)}_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 n;try{n=JSON.parse(i.data)}catch{return}if(n&&n.type==="bye")return this._drop(e,"left");this.cb.onMessage?.(e.id,n)}}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 n of this.peers.values())if(n.pc)for(let s of n.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=qe(this.sendFormat,e);for(let i of this.peers.values())if(i.pc){for(let n of i.pc.getSenders())if(!(!n.track||n.track.kind!=="video"))try{let s=n.getParameters();s.degradationPreference="maintain-resolution",(!s.encodings||!s.encodings.length)&&(s.encodings=[{}]),s.encodings[0].maxBitrate=t*1e3,await n.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 lr={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},Bt={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},cs=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function hs(r){return!!r&&(r.name==="NotReadableError"||r.name==="TrackStartError"||/in use|busy/i.test(r.message||""))}function ds(r){return!!r&&(r.name==="NotAllowedError"||r.name==="PermissionDeniedError"||r.name==="SecurityError")}function cr(r){return r.length&&r.every(e=>e.busy)?"camera-busy":r.some(e=>e.denied)?"permission-denied":"no-camera"}function qt(r){return/stereo|\b3d\b|\bsbs\b|dual/i.test(r||"")}async function hr(r="auto",e={}){let t=e.mediaDevices||globalThis.navigator&&navigator.mediaDevices,i=e.log||(()=>{}),n=[],s=e.calibration||{};if(r&&typeof r=="object"&&typeof r.getVideoTracks=="function"){let u=r.getVideoTracks()[0],p=u?u.getSettings():{},y=e.format==="sbs"?"sbs":"mono";return{stream:r,format:y,width:p.width||0,height:p.height||0,deviceId:p.deviceId||null,label:u?u.label:"",owned:!1,skipped:n,calibration:s}}if(!t||!t.getUserMedia)throw Object.assign(new Error("getUserMedia is not available (insecure context?)"),{code:"no-camera"});let o=async u=>{let p=await t.getUserMedia({video:u,audio:!1}),y=p.getVideoTracks()[0],w=y?y.getSettings():{};if(!y||y.readyState==="ended"||!(w.width>0)||!(w.height>0))throw p.getTracks().forEach(T=>T.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=w.displayxrStereo&&w.displayxrStereo.layout==="side-by-side"?w.displayxrStereo:null;return{stream:p,track:y,width:w.width,height:w.height,deviceId:w.deviceId||null,label:y.label||"",stereo:b}},a=(u,p)=>{n.push({label:u,error:`${p.name}: ${p.message}`,busy:hs(p),denied:ds(p)}),i("camera-skip",{label:u,error:p.name})},l=u=>u&&u.stream.getTracks().forEach(p=>p.stop()),c=(u,p)=>({stream:u.stream,format:p,width:u.width,height:u.height,deviceId:u.deviceId,label:u.label,owned:!0,skipped:n,calibration:{rectified:!1,...p==="sbs"&&u.stereo?{rectified:!!u.stereo.rectified,...u.stereo.baselineMm>0?{baselineMm:u.stereo.baselineMm}:{},...u.stereo.horizontalFovDeg>0?{hfovDeg:u.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof r=="string"&&!["auto","stereo","mono"].includes(r)){let u;try{u=await o({deviceId:{exact:r},...Bt})}catch(p){throw a(r,p),Object.assign(new Error(`camera unavailable: ${p.message}`),{code:cr(n),skipped:n})}return oe(u.width,u.height)?c(u,"sbs"):(l(u),c(await o({deviceId:{exact:r},...lr}),"mono"))}let f=new Set;if(r!=="mono"){let u=[];try{u=(await t.enumerateDevices()).filter(p=>p.kind==="videoinput"&&p.deviceId&&qt(p.label))}catch{}for(let p of u){f.add(p.deviceId);let y=null;try{y=await o({deviceId:{exact:p.deviceId},...Bt})}catch(w){a(p.label,w);continue}if(oe(y.width,y.height))return i("camera-sbs",{label:y.label,width:y.width,height:y.height,direct:!0}),c(y,"sbs");l(y)}}let m=null;try{m=await o(lr)}catch(u){a("default",u)}if(r==="mono"&&m)return c(m,"mono");if(m&&oe(m.width,m.height))return c(m,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(u=>u.kind==="videoinput")}catch{}h.sort((u,p)=>Number(qt(p.label))-Number(qt(u.label)));for(let u of h){if(!u.deviceId||m&&u.deviceId===m.deviceId||f.has(u.deviceId))continue;let p=null;try{p=await o({deviceId:{exact:u.deviceId},...Bt})}catch(y){a(u.label,y);continue}if(oe(p.width,p.height))return l(m),i("camera-sbs",{label:p.label,width:p.width,height:p.height}),c(p,"sbs");l(p)}if(m)return r==="stereo"&&i("camera-no-stereo",{fallback:m.label}),c(m,"mono");let d=cr(n);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:n})}async function dr(r={}){let e=r.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...cs},video:!1})).getAudioTracks()[0]||null}catch(t){return(r.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Gt();Jt();var _r="http://displayxr.org/ns/stereo/1.0/",Ze="http://ns.adobe.com/xap/1.0/\0";function et(r={}){let e=i=>typeof i=="number"&&Number.isFinite(i)?i:null,t=r.layout==="sbs"||r.layout==="side-by-side"?"sbs":"mono";return{layout:t,columns:t==="sbs"?2:1,rows:1,convergencePx:e(r.convergencePx),baselineMm:e(r.baselineMm),horizontalFovDeg:e(r.horizontalFovDeg),rectified:r.rectified===!0?!0:r.rectified===!1?!1:null,eyeWidth:e(r.eyeWidth),eyeHeight:e(r.eyeHeight),software:typeof r.software=="string"&&r.software?r.software:null}}var ys=r=>String(r).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<"),ue=r=>Math.round(r*1e3)/1e3;function yr(r){let e=et(r),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:ue(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:ue(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:ue(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,n])=>` dxr:${i}="${ys(n)}"`).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="${_r}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Kt(r){if(typeof r!="string"||!r.includes(_r))return null;let e=o=>{let a=new RegExp(`\\bdxr:${o}="([^"]*)"`).exec(r);if(a)return a[1];let l=new RegExp(`<dxr:${o}>([^<]*)</dxr:${o}>`).exec(r);return l?l[1]:null},t=o=>{let a=e(o);return a===null||a===""||!Number.isFinite(+a)?null:+a},i=e("Rectified"),n=e("Layout"),s=e("Software");return et({layout:n==="side-by-side"||n==="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(/"/g,'"').replace(/</g,"<").replace(/&/g,"&")})}var Qe=r=>new TextEncoder().encode(r),Yt=r=>new TextDecoder().decode(r),vr=r=>r.length>4&&r[0]===255&&r[1]===216;function*wr(r){let e=2;for(;e+4<=r.length;){if(r[e]!==255)return;let t=r[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=r[e+2]<<8|r[e+3];if(i<2||e+2+i>r.length)return;yield{marker:t,start:e,end:e+2+i,data:r.subarray(e+4,e+2+i)},e+=2+i}}function br(r,e){if(r.length<e.length)return!1;for(let t=0;t<e.length;t++)if(r[t]!==e.charCodeAt(t))return!1;return!0}function xr(r,e){if(!vr(r))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...Qe(Ze),...Qe(e)]),i=t.length+2;if(i>65535)throw new RangeError("jpegWithXmp: XMP packet too large for one APP1 segment");let n=new Uint8Array(4+t.length);n[0]=255,n[1]=225,n[2]=i>>8,n[3]=i&255,n.set(t,4);let s=2,o=null;for(let f of wr(r)){if(f.marker===225&&br(f.data,Ze)){o=f;break}if(f.marker===224||f.marker===225)s=f.end;else break}let[a,l]=o?[o.start,o.end]:[s,s],c=new Uint8Array(r.length-(l-a)+n.length);return c.set(r.subarray(0,a),0),c.set(n,a),c.set(r.subarray(l),a+n.length),c}function Zt(r){if(!vr(r))return null;for(let e of wr(r))if(e.marker===225&&br(e.data,Ze))return Yt(e.data.subarray(Ze.length));return null}var Sr=r=>Kt(Zt(r)),$={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},vs=r=>r.length>4&&r[0]===26&&r[1]===69&&r[2]===223&&r[3]===163;function Mr(r){let e=[];for(let t=r;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function Er(r,e=0){let t=e;if(!t)for(t=1;t<8&&r>2**(7*t)-2;t++);let i=new Array(t).fill(0),n=r;for(let s=t-1;s>=1;s--)i[s]=n%256,n=Math.floor(n/256);return i[0]=128>>t-1|n,i}function Qt(r,e){let t=r[e],i=t>=128?1:t>=64?2:t>=32?3:t>=16?4:0;if(!i||e+i>r.length)return null;let n=0;for(let s=0;s<i;s++)n=n*256+r[e+s];return{id:n,width:i}}function Le(r,e){let t=r[e],i=1;for(;i<=8&&!(t&128>>i-1);)i++;if(i>8||e+i>r.length)return null;let n=t&255>>i,s=n===127>>i-1;for(let o=1;o<i;o++)n=n*256+r[e+o],r[e+o]!==255&&(s=!1);return{size:n,width:i,unknown:s}}function de(r,e){return[...Mr(r),...Er(e.length),...e]}function ws(r){let e=[];for(let[i,n]of Object.entries(r))n!=null&&e.push(...de($.SimpleTag,[...de($.TagName,[...Qe(String(i))]),...de($.TagString,[...Qe(String(n))])]));let t=de($.Tag,[...de($.Targets,[]),...e]);return new Uint8Array(de($.Tags,t))}function Rr(r){let e=et(r);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(ue(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(ue(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(ue(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 bs(r){if(!r||!("DXR_LAYOUT"in r))return null;let e=t=>r[t]===void 0||r[t]===""||!Number.isFinite(+r[t])?null:+r[t];return et({layout:r.DXR_LAYOUT==="side-by-side"?"sbs":"mono",convergencePx:e("DXR_CONVERGENCE_PX"),baselineMm:e("DXR_BASELINE_MM"),horizontalFovDeg:e("DXR_HFOV_DEG"),rectified:r.DXR_RECTIFIED===void 0?null:r.DXR_RECTIFIED==="true",eyeWidth:e("DXR_EYE_WIDTH"),eyeHeight:e("DXR_EYE_HEIGHT"),software:r.DXR_SOFTWARE??null})}function Cr(r){if(!vs(r))return null;let e=Le(r,4);if(!e)return null;let t=4+e.width+e.size;for(;t<r.length;){let i=Qt(r,t);if(!i)return null;let n=Le(r,t+i.width);if(!n)return null;let s=t+i.width+n.width;if(i.id===$.Segment)return{sizeAt:t+i.width,sizeWidth:n.width,unknown:n.unknown,dataStart:s,size:n.size};if(n.unknown)return null;t=s+n.size}return null}function kr(r,e){let t=Cr(r);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=ws(e);if(t.unknown){let f=new Uint8Array(r.length+i.length);return f.set(r,0),f.set(i,r.length),f}let n=Math.min(r.length,t.dataStart+t.size),s=n-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=Er(s,o?t.sizeWidth:8),l=new Uint8Array(t.sizeAt+a.length+(n-t.dataStart)+i.length+(r.length-n));l.set(r.subarray(0,t.sizeAt),0),l.set(a,t.sizeAt);let c=t.sizeAt+a.length;return l.set(r.subarray(t.dataStart,n),c),c+=n-t.dataStart,l.set(i,c),c+=i.length,l.set(r.subarray(n),c),l}function Tr(r,e,t){let i={},n=(s,o,a)=>{let l=s;for(;l<o;){let c=Qt(r,l);if(!c)return;let f=Le(r,l+c.width);if(!f||f.unknown)return;let m=l+c.width+f.width;a(c.id,m,Math.min(o,m+f.size)),l=m+f.size}};return n(e,t,(s,o,a)=>{s===$.Tag&&n(o,a,(l,c,f)=>{if(l!==$.SimpleTag)return;let m=null,h=null;n(c,f,(d,u,p)=>{d===$.TagName?m=Yt(r.subarray(u,p)):d===$.TagString&&(h=Yt(r.subarray(u,p)))}),m!==null&&(i[m]=h??"")})}),i}function xs(r){let e=Cr(r);if(!e)return null;let t=e.unknown?r.length:Math.min(r.length,e.dataStart+e.size),i=null,n=e.dataStart;for(;n<t;){let s=Qt(r,n);if(!s)break;let o=Le(r,n+s.width);if(!o)break;let a=n+s.width+o.width;if(s.id===$.Tags&&!o.unknown&&(i={...i||{},...Tr(r,a,Math.min(t,a+o.size))}),o.unknown){i=i||Ss(r,t);break}n=a+o.size}return i}function Ss(r,e){let t=Mr($.Tags);for(let i=e-t.length-1;i>=0;i--){if(r[i]!==t[0]||r[i+1]!==t[1]||r[i+2]!==t[2]||r[i+3]!==t[3])continue;let n=Le(r,i+4);if(n&&!n.unknown&&i+4+n.width+n.size===e)return Tr(r,i+4+n.width,e)}return null}var Dr=r=>bs(xs(r));var ee="[inline3d/camera]",Gr="inline3d-camera/1",Ps=200,Is=240,Fs=66,Ws=4e3,js=4,Ns=1500,zs=2e4,Hs=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],st=()=>typeof document<"u"&&document&&typeof document.createElement=="function",qr=()=>{let r=new Date,e=t=>String(t).padStart(2,"0");return`${r.getFullYear()}${e(r.getMonth()+1)}${e(r.getDate())}-${e(r.getHours())}${e(r.getMinutes())}${e(r.getSeconds())}`},$s=r=>/jpe?g/.test(r)?"jpg":/png/.test(r)?"png":/webp/.test(r)?"webp":/mp4/.test(r)?"mp4":/webm/.test(r)?"webm":"bin";function ot(r,e,t){return`${String(r||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${$s(t)}`}var Y=(r,e,t={})=>Object.assign(new Error(`${ee} ${r}`),{code:e,...t});function Xr(r,e=Ws){return r?(r.readyState||0)>=2&&r.videoWidth?Promise.resolve():new Promise((t,i)=>{let n=!1,s=()=>{n||(r.readyState||0)<2||!r.videoWidth||(n=!0,clearTimeout(o),r.removeEventListener("loadeddata",s),r.removeEventListener("playing",s),r.removeEventListener("resize",s),t())},o=setTimeout(()=>{n||(n=!0,i(Y("the camera delivered no frame in time","no-frame")))},e);r.addEventListener("loadeddata",s),r.addEventListener("playing",s),r.addEventListener("resize",s),r.play?.().catch(()=>{})}):Promise.reject(Y("no video element (no document?)","no-frame"))}function Jr(r,e,t=Is){let i=r.videoWidth,n=r.videoHeight;if(!i||!n||(r.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(n*s));(e.width!==o||e.height!==a)&&(e.width=o,e.height=a);let l=e.getContext("2d",{willReadFrequently:!0});try{return l.drawImage(r,0,0,o,a),{img:Je(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var li=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,st()&&(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 n of this.stream.getVideoTracks())n.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(`${ee} 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(n){console.error(`${ee} '${e}' listener threw`,n)}}_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||!st())return null;try{await Xr(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=Jr(this.video,this._scratch);if(!e)return null;let t=De().measure(e.img,e.w,e.h,0);return t?t.d/e.scale:null}_meta(e,t=this.width,i=this.height){let n=this.stereo;return{layout:this.format,convergencePx:e,baselineMm:n?n.baselineMm:null,horizontalFovDeg:n?n.horizontalFovDeg:null,rectified:n?n.rectified:null,eyeWidth:this.format==="sbs"?t/2:t,eyeHeight:i,software:Gr}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:n}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(!this.video||!st())throw Y("capturePhoto needs a document","no-frame");await Xr(this.video);let s=this.video.videoWidth,o=this.video.videoHeight,a=typeof n=="number"&&Number.isFinite(n)?n: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,u)=>l.toBlob(p=>p?d(p):u(Y("toBlob produced nothing","encode-failed")),e,t)),f=this._meta(a,s,o),m=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(m=yr(f),c=new Blob([xr(new Uint8Array(await c.arrayBuffer()),m)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:ot(i||`photo-${qr()}`,this.format,c.type||e),xmp:m};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:n,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw Y("the camera is closed","closed");if(typeof MediaRecorder!="function")throw Y("MediaRecorder is not available here","unsupported");let l=e||Hs.find(g=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(g))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw Y(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],f=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...f);let m=new MediaStream(c),h={...l?{mimeType:l}:{},...n?{videoBitsPerSecond:n}:{}},d=new MediaRecorder(m,h),u=[];d.ondataavailable=g=>g.data&&g.data.size&&u.push(g.data);let p=null,y=[],w=null,b=0,T=!!t&&this.format==="sbs"&&st()&&this.video;if(T){w=document.createElement("canvas");let g=()=>{b=requestAnimationFrame(g);let _=this.video,S=_.videoWidth,D=_.videoHeight;!S||!D||(_.readyState||0)<2||((w.width!==S/2||w.height!==D)&&(w.width=S/2,w.height=D),w.getContext("2d").drawImage(_,0,0,S/2,D,0,0,S/2,D))};g();let v=w.captureStream(a);for(let _ of f)v.addTrack(_);p=new MediaRecorder(v,h),p.ondataavailable=_=>_.data&&_.data.size&&y.push(_.data)}let x=performance.now(),P=[],C=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(g=>g!==null&&P.push(g)),1500):0;this.measureConvergence().then(g=>g!==null&&P.push(g)),d.start(s),p?.start(s),this.log("record-start",{mimeType:l,mono:T,audio:f.length});let O=(g,v)=>new Promise(_=>{if(!g||g.state==="inactive")return _(v);g.onstop=()=>_(v),g.stop()}),I=o||`clip-${qr()}`,L=this;return{get state(){return d.state},get mimeType(){return d.mimeType||l},pause(){d.state==="recording"&&d.pause(),p&&p.state==="recording"&&p.pause()},resume(){d.state==="paused"&&d.resume(),p&&p.state==="paused"&&p.resume()},async stop(){clearInterval(C),b&&cancelAnimationFrame(b);let[g,v]=await Promise.all([O(d,u),O(p,y)]),_=d.mimeType||l||g[0]&&g[0].type||"video/webm",S=[...P].sort((ge,V)=>ge-V),D=S.length?S[Math.floor(S.length/2)]:null,E=L._meta(D),F=/webm|matroska/.test(_),H=async(ge,V)=>{let Z=new Blob(ge,{type:_});if(F&&Z.size)try{Z=new Blob([kr(new Uint8Array(await Z.arrayBuffer()),Rr({...E,layout:V}))],{type:_})}catch(Ei){L.log("record-tag-failed",{message:String(Ei&&Ei.message)})}return Z},k=await H(g,L.format),W={blob:k,type:_,layout:L.format,durationMs:Math.round(performance.now()-x),convergencePx:D,stereo:L.stereo,suggestedName:ot(I,L.format,_),tagged:F&&k.size>0};return p&&(W.mono=await H(v,"mono"),W.monoSuggestedName=ot(I,"mono",_)),L.log("record-stop",{bytes:k.size,mono:W.mono?W.mono.size:null,ms:W.durationMs,convergencePx:D,name:W.suggestedName}),W}}}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 hi(r={}){let e=typeof r=="string"||r&&typeof r.getVideoTracks=="function"?{prefer:r}:r||{},t=e.prefer===void 0||e.prefer===null?"auto":e.prefer,i=typeof e.log=="function"?e.log:e.debug?(a,l)=>console.log(`${ee} ${a} ${JSON.stringify(l)}`):null,n=e.calibration&&typeof e.calibration=="object"?{...e.calibration}:{};n.horizontalFovDeg>0&&!(n.hfovDeg>0)&&(n.hfovDeg=n.horizontalFovDeg),delete n.horizontalFovDeg;let s=await hr(t,{format:e.format,calibration:n,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 li(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 at=r=>!!r&&typeof r=="object"&&typeof r.capturePhoto=="function"&&typeof r.record=="function"&&r.stream&&typeof r.stream.getVideoTracks=="function";function Us(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function di(r,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${ee} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!at(t))throw new TypeError(`${ee} addCameraView: cam must be a StereoCamera from openCamera()`);let n=new ci(r,e,t,i);return t._views?.add(n),n}var ci=class{constructor(e,t,i,n){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=n.mirror===void 0?!0:!!n.mirror,this.aspect=typeof n.aspect=="number"&&n.aspect>.3&&n.aspect<4?n.aspect:16/9,this.autoConverge=!!n.autoConverge,this.conv=Me(),this.conv.depth=0,this.setDepth(n.depth),this.route=null,this.handle=null,this.fallbackReason=null,this._fw=null,this._onRouteChange=typeof n.onRouteChange=="function"?n.onRouteChange:null,this._layerFails=0,this._layerTimer=0,this.buffer=null,this.removed=!1,this._raf=0,this._loop=n._loop!==!1,this._autoAt=0,this._track=Ye(),this._focus=De(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=Ke(n.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(ai(),oi)).then(s=>{this.removed||(this.cursor=new s.PairCursor(this.canvas,this._cursorOpt))}),this._reroute(!1),this._loop&&this._start()}get woven(){return this.route==="woven-sbs"}weaveState(){return{route:this.route,woven:this.woven,reason:this.fallbackReason,firstWoven:this.route==="woven-sbs"?this._fw?{...this._fw}:"pending":null,layerRetries:this._layerFails}}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;e&&this.fallbackReason&&(this.fallbackReason=null,clearTimeout(this._layerTimer),this._layerTimer=0);let i=this.cam,n=i.state==="live"&&i.video,o=i.format==="sbs"&&n&&this.wall&&this.wall.supported&&!this.fallbackReason?"woven-sbs":i.format==="sbs"?"flat-left":"flat";if(!e&&o===this.route)return;let a=this.route;this._unregister(),this.route=o,o==="woven-sbs"&&this._registerWoven(),o!==a&&this._routeChanged()}_registerWoven(){this.buffer||(this.buffer=document.createElement("canvas")),this._paintWoven();let e=this.wall.addImage(this.canvas,this.buffer);this.handle=e,this._fw=null;let t=e&&e.firstWoven;!t||typeof t.then!="function"||t.then(i=>{this.handle!==e||this.removed||!i||(this._fw={woven:!!i.woven,confirmed:!!i.confirmed,reason:i.reason||null,ms:i.ms},this.cam.log?.("view-first-woven",{woven:!!i.woven,reason:i.reason||null}),i.woven?(this._layerFails=0,this._routeChanged()):i.reason!=="removed"&&this._layerLost(i.reason||"layer-failed"))})}_layerLost(e){if(this.fallbackReason=e,this._reroute(!1),e!=="layer-failed"||this._layerFails>=js)return;let t=Math.min(zs,Ns*Math.pow(2,this._layerFails++));this.cam.log?.("view-layer-retry",{attempt:this._layerFails,inMs:t}),clearTimeout(this._layerTimer),this._layerTimer=setTimeout(()=>{this._layerTimer=0,!(this.removed||this.fallbackReason!==e)&&this._reroute(!0)},t)}_routeChanged(){if(this._onRouteChange)try{this._onRouteChange(this.route,this.weaveState())}catch(e){console.error(`${ee} onRouteChange threw`,e)}}_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(this.cursor?.idle(),!Us(this.canvas))return;let t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2)return;let n=this.canvas.getContext("2d"),s=this.route==="flat-left"?t/2:t,o=U(s,i,this.canvas.width/this.canvas.height,0,0);n.save(),this.mirror&&(n.translate(this.canvas.width,0),n.scale(-1,1)),n.drawImage(e,o.sx,o.sy,o.sw,o.sh,0,0,this.canvas.width,this.canvas.height),n.restore()}_paintWoven(){let e=this.cam.video,t=e.videoWidth,i=e.videoHeight;if(!t||!i||(e.readyState||0)<2||!this.buffer)return;let n=t/2,s=this.aspect,{w:o,h:a}=Se(n,i,s),l=this.buffer;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.autoConverge||c)&&this._sample(e,c);let f=this.conv.step(n),m=l.getContext("2d");if(this.mirror)for(let h of ae(t,i)){let d=h.src==="L"?0:1,u=U(n,i,s,f,d),p=h.dx===0?0:o;m.save(),m.translate(p+o,0),m.scale(-1,1),m.drawImage(e,h.sx+u.sx,u.sy,u.sw,u.sh,0,0,o,a),m.restore()}else for(let h of[0,1]){let d=U(n,i,s,f,h);m.drawImage(e,h*n+d.sx,d.sy,d.sw,d.sh,h*o,0,o,a)}if(this.cursor){let h={rL:U(n,i,s,f,0),rR:U(n,i,s,f,1),outW:o,outH:a,mirror:this.mirror,handle:this.handle};this.cursor.draw(m,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?Fs:Ps))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let n=Jr(e,this._scratch);if(n&&(this._luma=n),!this.autoConverge)return;let s=n?this._focus.measure(n.img,n.w,n.h,i):null,o=this._track.push(s?s.d/n.scale:null);this.conv.measuredPx=o,this.disparityPx=o}remove(){this.removed||(this.removed=!0,this._raf&&cancelAnimationFrame(this._raf),this._raf=0,clearTimeout(this._layerTimer),this._layerTimer=0,this._unregister(),this.cursor?.dispose(),this.cursor=null,this.cam._views?.delete(this))}};var Kr=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],Zr=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],Vs=[1,0],ui=10;function Qr(r){let e=(16*r+128)*r+64;if(r>=2){let t=Math.floor(r/7)+2;e-=(25*t-10)*t-55,r>=7&&(e-=36)}return e}var Yr=(r,e)=>Math.floor(Qr(r)/8)-Kr[e][r]*Zr[e][r];function fi(r,e){let t=0;for(let i=7;i>=0;i--)t=t<<1^(t>>>7)*285,t^=(e>>>i&1)*r;return t}function Bs(r){let e=new Array(r-1).fill(0);e.push(1);let t=1;for(let i=0;i<r;i++){for(let n=0;n<e.length;n++)e[n]=fi(e[n],t),n+1<e.length&&(e[n]^=e[n+1]);t=fi(t,2)}return e}function qs(r,e){let t=e.map(()=>0);for(let i of r){let n=i^t.shift();t.push(0),e.forEach((s,o)=>t[o]^=fi(s,n))}return t}function pi(r,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(r))],n=1;for(;n<=ui&&!(4+(n<=9?8:16)+i.length*8<=Yr(n,t)*8);n++);if(n>ui)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${ui} code`);let s=[],o=(g,v)=>{for(let _=v-1;_>=0;_--)s.push(g>>>_&1)};o(4,4),o(i.length,n<=9?8:16);for(let g of i)o(g,8);let a=Yr(n,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((v,_)=>v<<1|_,0));let c=Zr[t][n],f=Kr[t][n],m=Math.floor(Qr(n)/8),h=c-m%c,d=Math.floor(m/c),u=Bs(f),p=[];for(let g=0,v=0;g<c;g++){let _=l.slice(v,v+d-f+(g<h?0:1));v+=_.length;let S=qs(_,u);g<h&&_.push(0),p.push(_.concat(S))}let y=[];for(let g=0;g<p[0].length;g++)for(let v=0;v<p.length;v++)(g!==d-f||v>=h)&&y.push(p[v][g]);let w=n*4+17,b=Array.from({length:w},()=>new Array(w).fill(!1)),T=Array.from({length:w},()=>new Array(w).fill(!1)),x=(g,v,_)=>{b[v][g]=_,T[v][g]=!0};for(let g=0;g<w;g++)x(6,g,g%2===0),x(g,6,g%2===0);let P=(g,v)=>{for(let _=-4;_<=4;_++)for(let S=-4;S<=4;S++){let D=Math.max(Math.abs(S),Math.abs(_)),E=g+S,F=v+_;E>=0&&E<w&&F>=0&&F<w&&x(E,F,D!==2&&D!==4)}};P(3,3),P(w-4,3),P(3,w-4);let C=[];if(n>1){let g=Math.floor(n/7)+2,v=Math.ceil((n*4+4)/(g*2-2))*2;C.push(6);for(let _=w-7;C.length<g;_-=v)C.splice(1,0,_)}for(let g=0;g<C.length;g++)for(let v=0;v<C.length;v++)if(!(g===0&&v===0||g===0&&v===C.length-1||g===C.length-1&&v===0))for(let _=-2;_<=2;_++)for(let S=-2;S<=2;S++)x(C[g]+S,C[v]+_,Math.max(Math.abs(S),Math.abs(_))!==1);let O=g=>{let v=Vs[t]<<3|g,_=v;for(let E=0;E<10;E++)_=_<<1^(_>>>9)*1335;let S=(v<<10|_)^21522,D=E=>(S>>>E&1)!==0;for(let E=0;E<=5;E++)x(8,E,D(E));x(8,7,D(6)),x(8,8,D(7)),x(7,8,D(8));for(let E=9;E<15;E++)x(14-E,8,D(E));for(let E=0;E<8;E++)x(w-1-E,8,D(E));for(let E=8;E<15;E++)x(8,w-15+E,D(E));x(8,w-8,!0)};if(O(0),n>=7){let g=n;for(let _=0;_<12;_++)g=g<<1^(g>>>11)*7973;let v=n<<12|g;for(let _=0;_<18;_++){let S=(v>>>_&1)!==0,D=w-11+_%3,E=Math.floor(_/3);x(D,E,S),x(E,D,S)}}let I=0;for(let g=w-1;g>=1;g-=2){g===6&&(g=5);for(let v=0;v<w;v++)for(let _=0;_<2;_++){let S=g-_,E=(g+1&2)===0?w-1-v:v;!T[E][S]&&I<y.length*8&&(b[E][S]=(y[I>>>3]>>>7-(I&7)&1)!==0,I++)}}let L=g=>{for(let v=0;v<w;v++)for(let _=0;_<w;_++){if(T[v][_])continue;let S;switch(g){case 0:S=(_+v)%2===0;break;case 1:S=v%2===0;break;case 2:S=_%3===0;break;case 3:S=(_+v)%3===0;break;case 4:S=(Math.floor(_/3)+Math.floor(v/2))%2===0;break;case 5:S=_*v%2+_*v%3===0;break;case 6:S=(_*v%2+_*v%3)%2===0;break;default:S=((_+v)%2+_*v%3)%2===0}S&&(b[v][_]=!b[v][_])}},M=Number.isInteger(e.mask)?e.mask:-1;if(M<0){let g=1/0;for(let v=0;v<8;v++){L(v),O(v);let _=Xs(b,w);_<g&&(g=_,M=v),L(v)}}return L(M),O(M),{version:n,size:w,mask:M,modules:b}}function Xs(r,e){let t=0,i=[];for(let o=0;o<e;o++)i.push(r[o]);for(let o=0;o<e;o++)i.push(r.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 f=l.indexOf(c);f>=0;f=l.indexOf(c,f+1))t+=40}let n=0;for(let o=0;o<e;o++)for(let a=0;a<e;a++)if(r[o][a]&&n++,a<e-1&&o<e-1){let l=r[o][a];l===r[o][a+1]&&l===r[o+1][a]&&l===r[o+1][a+1]&&(t+=3)}let s=e*e;return t+=Math.floor(Math.abs(n*20-s*10)/s)*10,t}function en(r,e,{px:t=4,dark:i="#000",light:n="#fff",ecl:s="M"}={}){let o=pi(e,{ecl:s}),a=o.size+8;r.width=r.height=a*t;let l=r.getContext("2d");l.fillStyle=n,l.fillRect(0,0,a*t,a*t),l.fillStyle=i;for(let c=0;c<o.size;c++)for(let f=0;f<o.size;f++)o.modules[c][f]&&l.fillRect((f+4)*t,(c+4)*t,t,t);return o}function K(r,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=r,t}async function mi(r){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(String(r)));return[...new Uint8Array(e)].map(t=>t.toString(16).padStart(2,"0")).join("")}var lt="wss://signal.displayxr.org",tn=Object.freeze([lt,"wss://dxr-signal.displayxr.workers.dev"]),rn=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function fe(r=lt,e={}){if(!r||typeof r!="string")throw K("no-signaling-url","dxrSignaling(url): url must be a ws:// or wss:// string (omit it for the hosted DisplayXR server)");let t=c=>String(c).replace(/\/+$/,""),i=t(r),n=e.WebSocket||globalThis.WebSocket,s=e.pingMs||2e4,o=Array.isArray(e.aliases)?e.aliases.filter(c=>typeof c=="string"&&c).map(t):tn.includes(i)?[...tn]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,f){let h=`k=${await mi(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,d=L=>`${a[L]}/v1/connect?${h}`,u=null,p=!1,y=0,w=null,b=new Set,T=[],x=L=>P(L,a.length),P=(L,M)=>new Promise((g,v)=>{let _=!1,S=!1,D=!1,E=new n(d(l));u=E;let F=H=>{if(!_){_=!0;try{E.close()}catch{}v(H)}};E.onopen=()=>{D=!0,E.send(JSON.stringify({t:"join",v:1,room:c,id:f.id,max:f.maxPeers}))},E.onmessage=H=>{let k;try{k=JSON.parse(typeof H.data=="string"?H.data:String(H.data))}catch{return}switch(k.t){case"welcome":{y=0;let W=Array.isArray(k.peers)?k.peers.filter(V=>typeof V=="string"):[];clearInterval(w),w=setInterval(()=>C({t:"ping"}),s);let ge=T;T=[];for(let V of ge)C(V);if(L){let V=new Set(W);for(let Z of b)V.has(Z)||f.onPeerLeft?.(Z);b=V,f.onReconnect?.(W)}else b=new Set(W);_=!0,S=!0,g({id:k.id,peers:W,iceServers:Array.isArray(k.iceServers)?k.iceServers:void 0,max:k.max,tier:k.tier==="key"?"key":"anon",key:typeof k.key=="string"?k.key:void 0,turn:k.turn&&typeof k.turn=="object"?k.turn:void 0});break}case"full":p=!0,F(K("room-full",`this call is full (${k.max} participants)`));break;case"expired":{p=!0,clearInterval(w);let W=K("expired","this room has reached its lifetime on the signalling server");_?f.onDisconnect?.(W):F(W);break}case"error":if(!_&&rn.includes(k.code))p=!0,F(K(k.code,k.message||k.code));else if(!_&&(k.code==="rate-limited"||k.code==="quota")){let W=K(k.code,k.message||k.code);W.retryMs=k.retryMs>0?k.retryMs:0,F(W)}else!_&&k.code==="id-taken"&&F(K("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof k.id=="string"&&!b.has(k.id)&&(b.add(k.id),f.onPeerJoined?.(k.id));break;case"peer-left":typeof k.id=="string"&&(b.delete(k.id),f.onPeerLeft?.(k.id));break;case"signal":typeof k.from=="string"&&f.onSignal?.(k.from,k.data);break}},E.onerror=()=>{if(!D&&!_&&M>1){_=!0,l=(l+1)%a.length,P(L,M-1).then(g,v);return}F(K("signaling-unreachable",`cannot reach ${a[l]}`))},E.onclose=()=>{clearInterval(w),F(K("signaling-closed","signalling closed before joining")),S&&!p&&u===E&&O()}}),C=L=>{u&&u.readyState===1?u.send(JSON.stringify(L)):p||T.push(L)},O=()=>{f.onDisconnect?.();let L=()=>{p||x(!0).catch(M=>{if(p||M&&(M.code==="room-full"||rn.includes(M.code))){f.onDisconnect?.(M);return}setTimeout(L,Math.max(q(y++,{baseMs:500,maxMs:15e3}),M&&M.retryMs||0))})};setTimeout(L,q(y++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(L,M)=>C({t:"signal",to:L,data:M}),leave:()=>{if(!p){p=!0,clearInterval(w);try{u&&u.readyState===1&&u.send(JSON.stringify({t:"leave"})),u&&u.close(1e3,"leave")}catch{}}}}}}}var gi=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),sn=r=>typeof r=="string"&&gi[r.toLowerCase()]||r,on=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),Ae=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 an(r){let e={...Ae,...r&&typeof r=="object"?r:{}};return(t,i)=>{let n=typeof e[t]=="string"?e[t]:Ae[t]||t;if(i)for(let[s,o]of Object.entries(i))n=n.split(`{${s}}`).join(String(o));return n}}var nn="dxr-call-style",Ys=`
|
|
6
6
|
.dxr-call-host{--dxr-accent:#4da3ff;--dxr-ink:#fff;--dxr-shell:rgba(16,17,22,.92);--dxr-danger:#ff5a5f;--dxr-radius:12px;
|
|
7
7
|
--dxr-font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
|
|
8
8
|
display:flex;flex-direction:column;gap:12px;color:var(--dxr-ink);
|
|
@@ -83,4 +83,4 @@ var un=Object.defineProperty;var ge=(r,e)=>()=>(r&&(e=r(r=0)),e);var fn=(r,e)=>{
|
|
|
83
83
|
.dxr-call-depth{display:flex;align-items:center;gap:6px;padding:0 8px;font-size:12px;opacity:.9;}
|
|
84
84
|
.dxr-call-depth input{width:110px;accent-color:var(--dxr-accent);}
|
|
85
85
|
.dxr-call-note{font-size:12px;opacity:.65;}
|
|
86
|
-
`;function rn(r=document){if(r.getElementById(Zr))return;let e=r.createElement("style");e.id=Zr,e.textContent=Bs,(r.head||r.documentElement).appendChild(e)}var te=r=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${r}"/></svg>`,X={mic:te("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:te("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:te("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:te("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:te("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:te("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:te("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 E(r,e={},t=[]){let i=document.createElement(r);for(let[n,s]of Object.entries(e))s!=null&&(n==="class"?i.className=s:n==="html"?i.innerHTML=s:n==="text"?i.textContent=s:n.startsWith("on")&&typeof s=="function"?i.addEventListener(n.slice(2),s):n in i&&typeof s!="string"?i[n]=s:i.setAttribute(n,s));for(let n of[].concat(t))n&&i.appendChild(typeof n=="string"?document.createTextNode(n):n);return i}var j=(r,e)=>r&&r.classList.toggle("dxr-call-hidden",!e);Jt();var sn="[inline3d/call]",qs="https://github.com/DisplayXR/displayxr-browser",on=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"}),nn=new Set;function Xs(r){nn.has(r)||(nn.add(r),console.warn(`${sn} option \`${r}\` is deprecated (removed in 1.31) \u2014 use ${on[r]}`))}function gi(r={}){for(let y of Object.keys(on))r[y]!==void 0&&Xs(y);let e=r.theme&&typeof r.theme=="object"?r.theme:{},t=r.invite&&typeof r.invite=="object"?r.invite:{},i=r.landing&&typeof r.landing=="object"?r.landing:{},n=r.ui===void 0?!0:r.ui==="tiles"?"tiles":!!r.ui,s=n===!0,o=e.tileAspect!==void 0?e.tileAspect:r.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=r.room===void 0||r.room===null?"auto":r.room;if(l!=="auto"&&!ce(l)){let y=Me(l);if(!y)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=y}let c=r.liftOptions&&typeof r.liftOptions=="object"?{...r.liftOptions}:null,p=c&&c.max!==void 0?c.max:r.maxLifted;c&&delete c.max;let m=e.accent!==void 0?e.accent:r.accent,h={};for(let[y,v]of Object.entries(en)){let b=y==="accent"?m:e[y];typeof b=="string"&&b?h[v]=y==="accent"?Qr(b):b:typeof b=="number"&&y==="radius"&&(h[v]=`${b}px`)}let d=t.base!==void 0?t.base:r.inviteBase,u=t.updateUrl!==void 0?t.updateUrl:r.updateUrl,f=i.browserUrl!==void 0?i.browserUrl:r.browserUrl;return{room:l,signaling:r.signaling||ue(void 0,typeof r.key=="string"&&r.key?{key:r.key}:{}),iceServers:Array.isArray(r.iceServers)?r.iceServers:void 0,camera:r.camera===void 0?"auto":r.camera,format:r.format==="sbs"?"sbs":r.format==="mono"?"mono":void 0,calibration:r.calibration&&typeof r.calibration=="object"?{...r.calibration}:{},rectify:typeof r.rectify=="function"?r.rectify:null,audio:r.audio===void 0?!0:!!r.audio,autoConverge:r.autoConverge===void 0?!0:!!r.autoConverge,cursor:Ke(r.cursor,"@displayxr/inline3d/call"),mono3D:we(r.mono3D),maxPeers:ke(r.maxPeers===void 0?le:r.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+p)&&p!==null&&p!==void 0?Math.max(0,Math.min(le,Math.floor(+p))):le,layout:r.layout==="speaker"?"speaker":r.layout==="none"?"none":"grid",ui:n,chrome:s,autoJoin:r.autoJoin===void 0?!s:!!r.autoJoin,selfView:r.selfView===void 0?!0:!!r.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:u===void 0?s:!!u},landing:{browserUrl:typeof f=="string"?f:qs,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!r.debug,log:typeof r.log=="function"?r.log:r.debug?(y,v)=>console.log(`${sn} ${y} ${JSON.stringify(v)}`):null,_liftImporter:typeof r._liftImporter=="function"?r._liftImporter:void 0}}var sa=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 yi="dxr-call:",Gs=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],_i="[inline3d/call] <dxr-call>",fe=r=>r!=null&&!/^(false|0|off|no)$/i.test(String(r).trim()),an=r=>{if(r==null||String(r).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(r)),t=e?+e[1]/+e[2]:+r;return Number.isFinite(t)?t:void 0},z=r=>r==null||String(r).trim()===""?void 0:String(r).trim();function vi(r){let e=typeof r=="function"?r:l=>r&&typeof r.getAttribute=="function"?r.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",z(e("room")));let n=z(e("signaling"));n&&(t.signaling=ue(n,z(e("key"))?{key:z(e("key"))}:{})),i("key",z(e("key"))),i("camera",z(e("camera"))),i("layout",z(e("layout"))),i("maxPeers",an(e("max-peers")));let s=z(e("ui"));fe(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),fe(e("auto-join"))&&(t.autoJoin=!0);let o=z(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),fe(e("no-audio"))&&(t.audio=!1),fe(e("no-self-view"))&&(t.selfView=!1),fe(e("no-auto-converge"))&&(t.autoConverge=!1),z(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:z(e("accent")),tileAspect:an(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),z(e("invite-base"))&&(t.invite={base:z(e("invite-base"))}),z(e("browser-url"))&&(t.landing={browserUrl:z(e("browser-url"))}),fe(e("debug"))&&(t.debug=!0),t}var Js=typeof HTMLElement=="function"?HTMLElement:class{},pe=class r extends Js{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={...vi(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||r.mount||wi;this._pending=new Promise(n=>n(i(this,t))).then(n=>{if(this._pending=null,e!==this._gen)return n.leave(),null;if(this.call=n,this._off=Gs.map(s=>n.on(s,o=>this._dispatch(s,o))),this._off.push(n.on("error",s=>console.warn(`${_i} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:n}),n.state==="in-call"){this._dispatch("joined",{room:n.room,id:n.id});for(let s of n.peers)this._dispatch("peer",{id:s.id})}return n},n=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(n&&n.message||n),error:n||null}),console.warn(`${_i} mount failed: ${String(n&&n.message||n)}`),n}),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(yi+e,{detail:t,bubbles:!0,composed:!0}))}};function ct(r="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(r);return t?(t!==pe&&console.warn(`${_i} <${r}> is already defined by another class; leaving it`),!1):(e.define(r,pe),!0)}var G="[inline3d/call]",Ys=2e3,Ks=2500,Zs=500,bi=.02,Qs=4,eo=2,to=200,ln=240,io=66,ro=new Set(["I420","I420A","I422","I444","NV12"]);async function dn(r,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=gi(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 n=new xi(r,e,i);return await n._init(),n.handle}async function wi(r,e={}){if(!r||typeof r.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,n=t||await ze(i.wallOptions);return dn(n,r,i)}var xi=class{constructor(e,t,i){this.o=i,this.t=tn(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=ir(),this.room=i.room==="auto"?Me(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=Ht(Ft),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=pt(),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 n of[...i])try{n(t)}catch(s){console.error(`${G} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${G} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${G} ${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 n=(h,d)=>this.log(h,d),s=null,o=null,a=at(e)?e:null;try{if(s=a||await ci({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:n}),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 hr({log:n})),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)),m=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!==m?.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}),m&&m.owned&&m.cam&&m.cam!==s&&m.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return Nt({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=Wt(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",Be(location.href,this.room))}catch{}this._setState("joining");let e=new Ce({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(i,n)=>this.log(i,n)});this.transport=e;let t=null;try{t=await e.start({room:this.room,localStream:this.local.stream,sendFormat:this.local.format,onPeer:i=>this._onPeer(i),onPeerLeft:(i,n)=>this._onPeerLeft(i,n),onStream:(i,n)=>this.tiles.get(i)?.setStream(n),onMessage:(i,n)=>this._onMessage(i,n),onPeerState:(i,n)=>{this.tiles.get(i)?.setConn(n),this.emit("state",{id:i,state:n})},onRefused:i=>this.log("refused-peer",{id:i}),onGhost:(i,n)=>this._onGhost(i,n),onSignalingState:(i,n)=>{this.log("signaling",{state:i}),i==="closed"&&n&&this.error(n.code||"signaling-closed",n.message,n)}})}catch(i){throw this.transport=null,i&&i.code==="room-full"?(this._setState("full"),this.error("room-full",i.message,i)):(this._setState("lobby"),this.error(i.code||"join-failed",`could not join: ${i.message}`,i)),i}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}),setTimeout(()=>{this.transport===e&&this._reportTurn(t)},0),this.handle}_reportTurn(e){let t=e&&e.turn;!t||typeof t!="object"||(t.status==="off"&&t.reason==="cap"?this.error("turn-cap","relay (TURN) capacity for this month is used up; direct connections still work, but a participant behind a strict NAT may be unreachable",null):(t.reason==="budget"||t.reason==="rate")&&this.warning("turn-shed",t.reason==="rate"?"no relay (TURN) for this session: too many credential requests from this address this hour":"no relay (TURN) for this anonymous session: the hosted service is near its monthly relay budget (a publishable key keeps TURN)"))}_onPeer(e){if(this.tiles.has(e))return;let t=new ht(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 n=new ht(this,e);n.ghost=!0,this.tiles.set(e,n),n.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()},Ks))}_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 n=jt(t);if(n)return i.setHello(n);let s=zt(t);if(s)return i.setHint(s);let o=nr(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return Be(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,n=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",n.videoTrack,n.stream),await this.transport.setSendFormat(n.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==n.format&&this.log("send-format",{format:n.format}),{format:n.format,width:n.width,height:n.height,label:n.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=zt({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=(...n)=>(i.pageClosed=!0,t.apply(e,n)),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=Ut(),n=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()-n)});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 ze()}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)},q(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let n of this.tiles.values())n.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(`${G} 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=(n,s)=>this.log(n,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=ut(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(n=>(this.liftApi=n,n.lift?(this.liftPool=mt({lift:n.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!n.caps&&n.capabilities&&Promise.resolve().then(()=>n.capabilities(i)).then(s=>{n.caps=s||null,this._refreshLobby()}).catch(()=>{})):n.reason==="import-failed"||n.reason==="no-lift-export"?this.liftMissing=!0:n.reason!=="off"&&console.info(`${G} mono\u21923D unavailable (${n.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),n))}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),Zs)}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 m={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 u=a._prevIn;m.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:u?Math.round((d.bytesReceived-u.bytes)*8/(d.timestamp-u.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 u=a._prevOut;m.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:p[d.codecId]||null,kbps:u?Math.round((d.bytesSent-u.bytes)*8/(d.timestamp-u.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(m.in||m.out)&&(a.quality=m,this.emit("quality",{id:o,...m}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>bi||a.remote.speaking),h>bi&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let n=t?t.id:null;n&&n!==this.speakerId?(this._challengeTicks=this._challenger===n?(this._challengeTicks||0)+1:1,this._challenger=n,this._challengeTicks>=2&&this._setSpeaker(n)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>bi;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 n=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(n-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${n}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;rn(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[n,s]of Object.entries(this.o.cssVars))e.style.setProperty(n,s);let i=this.ui={};i.banner=E("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[E("span",{text:t("banner2D")}),E("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=E("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=E("div",{class:"dxr-call-self",part:"self"}),i.bar=E("div",{class:"dxr-call-bar",part:"bar"}),i.foot=E("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=E("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||j(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new Si(this,i.selfSlot):j(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(n,s,o,a="")=>E("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":n,title:n,html:s,onclick:o});e.mic=i(t("mute"),X.mic,()=>this.mute()),e.cam=i(t("cameraOff"),X.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=E("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"),X.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),X.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,E("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?X.micOff:X.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?X.camOff:X.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 n=this.inviteLink();if(!n)return;let s=this.t,o=E("input",{type:"text",readOnly:!0,value:n,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:s("copyLink")});a.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(n),a.textContent=s("copied")}catch{o.select(),a.textContent=s("pressCopy")}setTimeout(()=>a.textContent=s("copyLink"),1800)});let l=E("canvas",{"aria-label":s("qrLabel"),role:"img"});try{Jr(l,n,{px:4})}catch{l.style.display="none"}e.append(E("h3",{text:t}),E("p",{text:i}),E("div",{class:"dxr-call-invite"},[E("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,n=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",n),j(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),j(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(n){j(a,!0),a.replaceChildren();let c=this.local,p=!!this.room,m=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),u=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,f=E("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(p?"join":"start")});f.addEventListener("click",()=>this.join().catch(()=>{}));let y=E("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(y),y.addEventListener("change",()=>this.setCamera(y.value).catch(b=>this.error("camera-failed",b.message,b)));let v=!c||!c.videoTrack?E("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;v?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(E("h3",{text:m}),E("p",{text:u}),E("div",{class:"dxr-call-row"},[this.state==="full"?null:f,v,y]))}else this.state==="in-call"&&s===0?(j(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(j(a,!0),a.replaceChildren(E("p",{text:i("joining")}))):j(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),j(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:It,wire:Ue,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()),self:this.self?this.self.diag():null,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(n=>n.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((n,s)=>E("option",{value:n.deviceId,text:n.label||`Camera ${s+1}`}))),i&&(e.value=i),j(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(`${G} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${G} 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)}},n={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(n))Object.defineProperty(i,s,{enumerable:!1,configurable:!0,get(){return e._handleWarned?.has(s)||((e._handleWarned||=new Set).add(s),console.warn(`${G} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function no(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function cn(r,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!no(r))return;let n=r.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=V(a,o,r.width/r.height,0,0);n.save(),i&&(n.translate(r.width,0),n.scale(-1,1)),n.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,r.width,r.height),n.restore()}var ht=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=Se(),this.autoTrack=Ye(),this.autoFocus=De(),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.luma=null,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=Ht(Ft),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=E("canvas"),this.cover=E("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,E("div",{class:"dxr-call-talk"})]),e.o.ui||j(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(oi(),si)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return Vt(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,cursor:this.cursor?this.cursor.last:null,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())},Ys)}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||"",j(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(E("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",X.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,n=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:$t({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=`${n.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=n.route,n.route==="woven-sbs"?this._registerWoven():n.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:n.route,format:this.format,mono3d:n.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:n.route,mono3d:n.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),j(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(j(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 n=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>n(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++>=eo)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},q(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++>=Qs)return;let e=q(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(j(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.cursor?.idle(),this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||cn(this.canvas,this.video):cn(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 n=t/2,s=this.call.o.tileAspect,{w:o,h:a}=xe(n,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.call.o.autoConverge||c)&&this._sampleDisparity(e,t,i,c);let p=this.conv.step(n),m=l.getContext("2d"),h=[];for(let d of[0,1]){let u=h[d]=V(n,i,s,p,d);m.drawImage(e,d*n+u.sx,u.sy,u.sw,u.sh,d*o,0,o,a)}this.cursor&&this.cursor.draw(m,this.luma,{rL:h[0],rR:h[1],outW:o,outH:a,handle:this.handle},performance.now()/1e3)}_sampleDisparity(e,t,i,n=!1){let s=performance.now();if(this.autoPending||s-this.autoAt<(n?io:to))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&ro.has(h.format)){this.autoPending=!0;let d=this.autoGen,u=h.visibleRect?h.visibleRect.width:h.displayWidth,f=h.visibleRect?h.visibleRect.height:h.displayHeight,y=new Uint8Array(h.allocationSize());h.copyTo(y).then(v=>{if(d!==this.autoGen)return;let b=performance.now(),k=Math.max(1,Math.ceil(u/2/ln)),x=ur(y,v[0].offset,v[0].stride,u,f,k);this._applyMeasurement(x.img,x.w,x.h,x.w/u,s,performance.now()-b,"videoframe")}).catch(()=>{d===this.autoGen&&this._applyMeasurement(null,0,0,1,s,0,"videoframe")}).finally(()=>{h.close(),this.autoPending=!1});return}h&&h.close()}let o=Math.min(1,ln/(t/2)),a=Math.max(2,Math.round(t*o/2)*2),l=Math.max(2,Math.round(i*o));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let c=this.autoCanvas;(c.width!==a||c.height!==l)&&(c.width=a,c.height=l);let p=c.getContext("2d",{willReadFrequently:!0}),m=null;try{p.drawImage(e,0,0,a,l),m=Je(p.getImageData(0,0,a,l).data,a*l)}catch{m=null}this._applyMeasurement(m,a,l,a/t,s,performance.now()-s,"canvas")}_applyMeasurement(e,t,i,n,s,o,a){if(this.destroyed||(e&&(this.luma={img:e,w:t,h:i,scale:n}),!this.call.o.autoConverge))return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,p=this.autoTrack.push(c?c.d/n: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/n),y:Math.round(c.y/n)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.luma=null,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,this.cursor?.dispose(),this.cursor=null,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()}},Si=class{constructor(e,t){this.call=e,this.canvas=E("canvas"),this.badge=E("div",{class:"dxr-call-badge",part:"badge"}),this.plate=E("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=E("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=E("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,E("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"):"",j(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,n=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,n):(this.detach(),this.cam=i,this.view=hi(n,this.canvas,i,{mirror:!0,autoConverge:!!this.call.o.autoConverge,cursor:this.call.o.cursor||void 0,aspect:this.call.o.tileAspect,onRouteChange:(s,o)=>{this.cam===i&&(this.call.log("self-route",{route:s,woven:o.woven,reason:o.reason}),this._badge())}})),this._badge()}_badge(){let e=this.call.t,t=!!(this.view&&this.view.woven);this.badge.replaceChildren(E("b",{text:`${e("you")} \xB7 ${e(t?"badge3D":"badge2D")}`})),this.badge.dataset.route=this.route||""}diag(){return this.view?this.view.weaveState():{route:null,woven:!1,reason:"no-camera",firstWoven:null,layerRetries:0}}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)}},so="1.31",hn=new Set;function D(r,e,t){let i=()=>{hn.has(r)||(hn.add(r),console.warn(`${G} \`${r}\` is internal and leaves '@displayxr/inline3d/call' in ${so} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(n,s,o){return i(),Reflect.apply(n,s,o)},construct(n,s){return i(),Reflect.construct(n,s)}}):t&&typeof t=="object"?new Proxy(t,{get(n,s,o){return typeof s=="string"&&i(),Reflect.get(n,s,o)}}):t}var Sa=D("normalizeCallOptions","js/call/options.js",gi),Ma=D("newRoomId","js/call/wire.js",Wt),Ea=D("isValidRoomId","js/call/wire.js",ce),Ra=D("buildInviteLink","js/call/wire.js",Be),Ca=D("normalizeHello","js/call/wire.js",jt),ka=D("makeHello","js/call/wire.js",Nt),Ta=D("routeFor","js/call/wire.js",$t),Da=D("badgeFor","js/call/wire.js",Vt),La=D("createLiveGate","js/call/wire.js",Ut),Aa=D("convergenceShiftPx","js/camera/converge.js",He),Oa=D("lowPass","js/camera/converge.js",Ve),Pa=D("clampShift","js/camera/converge.js",$e),Ia=D("eyeCropRect","js/camera/geometry.js",V),Fa=D("mirrorSwapOps","js/camera/geometry.js",ae),Wa=D("mirrorSwapPixels","js/camera/geometry.js",Pt),ja=D("maxBitrateKbps","js/call/wire.js",qe),Na=D("measureFocusDisparity","js/camera/disparity.js",Xt),za=D("preferVideoCodecs","js/call/sdp.js",Re),Ha=D("sortCodecCapabilities","js/call/sdp.js",Xe),$a=D("VIDEO_CODEC_ORDER","js/call/sdp.js",Ee),Va=D("MeshTransport","js/call/transport.js",Ce),Ua=D("clampMaxPeers","js/call/transport.js",ke),Ba=D("qrEncode","js/call/qr.js",fi),qa=D("roomKey","js/call/signaling.js",pi);var Xa=D("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:Ae.unreachable,cameraBusy:Ae.cameraBusy})),Ga=D("CALL_ACCENTS","js/call/ui.js",mi),Ja=D("normalizeMono3D","js/call/lift.js",we),Ya=D("resolveLift","js/call/lift.js",ut),Ka=D("createLiftPool","js/call/lift.js",mt),Za=D("createFrameWatch","js/call/lift.js",pt),Qa=D("liftConvergenceFor","js/call/lift.js",ve),el=D("liftPriorityFor","js/call/lift.js",Oe),tl=D("setLiftPriority","js/call/lift.js",ft),il=D("defaultLiftSpecifier","js/call/lift.js",dt),rl=D("LIFT_PRIORITY","js/call/lift.js",ye);ct();Ei(()=>new URL("./lift.js",import.meta.url).href);export{yi as CALL_EVENT_PREFIX,Vr as CAMERA_SDK,lt as DXR_SIGNAL_DEFAULT,pe as DxrCallElement,dn as addCall,hi as addCameraView,vi as attrsToOpts,Ki as createInline3D,ct as defineCallElement,ue as dxrSignaling,Ji as inline3DAvailable,at as isStereoCamera,wi as mountCall,ci as openCamera,Me as parseInviteLink,Kt as parseStereoXmp,xr as readJpegStereoMeta,Zt as readJpegXmp,Tr as readWebmStereoMeta,ze as sharedInline3D,ot as suggestedName};
|
|
86
|
+
`;function ln(r=document){if(r.getElementById(nn))return;let e=r.createElement("style");e.id=nn,e.textContent=Ys,(r.head||r.documentElement).appendChild(e)}var te=r=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${r}"/></svg>`,X={mic:te("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:te("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:te("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:te("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:te("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:te("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:te("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 R(r,e={},t=[]){let i=document.createElement(r);for(let[n,s]of Object.entries(e))s!=null&&(n==="class"?i.className=s:n==="html"?i.innerHTML=s:n==="text"?i.textContent=s:n.startsWith("on")&&typeof s=="function"?i.addEventListener(n.slice(2),s):n in i&&typeof s!="string"?i[n]=s:i.setAttribute(n,s));for(let n of[].concat(t))n&&i.appendChild(typeof n=="string"?document.createTextNode(n):n);return i}var j=(r,e)=>r&&r.classList.toggle("dxr-call-hidden",!e);Jt();var hn="[inline3d/call]",Ks="https://github.com/DisplayXR/displayxr-browser",dn=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"}),cn=new Set;function Zs(r){cn.has(r)||(cn.add(r),console.warn(`${hn} option \`${r}\` is deprecated (removed in 1.31) \u2014 use ${dn[r]}`))}function _i(r={}){for(let y of Object.keys(dn))r[y]!==void 0&&Zs(y);let e=r.theme&&typeof r.theme=="object"?r.theme:{},t=r.invite&&typeof r.invite=="object"?r.invite:{},i=r.landing&&typeof r.landing=="object"?r.landing:{},n=r.ui===void 0?!0:r.ui==="tiles"?"tiles":!!r.ui,s=n===!0,o=e.tileAspect!==void 0?e.tileAspect:r.tileAspect,a=typeof o=="number"&&o>.3&&o<4?o:16/9,l=r.room===void 0||r.room===null?"auto":r.room;if(l!=="auto"&&!ce(l)){let y=Ee(l);if(!y)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=y}let c=r.liftOptions&&typeof r.liftOptions=="object"?{...r.liftOptions}:null,f=c&&c.max!==void 0?c.max:r.maxLifted;c&&delete c.max;let m=e.accent!==void 0?e.accent:r.accent,h={};for(let[y,w]of Object.entries(on)){let b=y==="accent"?m:e[y];typeof b=="string"&&b?h[w]=y==="accent"?sn(b):b:typeof b=="number"&&y==="radius"&&(h[w]=`${b}px`)}let d=t.base!==void 0?t.base:r.inviteBase,u=t.updateUrl!==void 0?t.updateUrl:r.updateUrl,p=i.browserUrl!==void 0?i.browserUrl:r.browserUrl;return{room:l,signaling:r.signaling||fe(void 0,typeof r.key=="string"&&r.key?{key:r.key}:{}),iceServers:Array.isArray(r.iceServers)?r.iceServers:void 0,camera:r.camera===void 0?"auto":r.camera,format:r.format==="sbs"?"sbs":r.format==="mono"?"mono":void 0,calibration:r.calibration&&typeof r.calibration=="object"?{...r.calibration}:{},rectify:typeof r.rectify=="function"?r.rectify:null,audio:r.audio===void 0?!0:!!r.audio,autoConverge:r.autoConverge===void 0?!0:!!r.autoConverge,cursor:Ke(r.cursor,"@displayxr/inline3d/call"),mono3D:be(r.mono3D),maxPeers:Te(r.maxPeers===void 0?le:r.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+f)&&f!==null&&f!==void 0?Math.max(0,Math.min(le,Math.floor(+f))):le,layout:r.layout==="speaker"?"speaker":r.layout==="none"?"none":"grid",ui:n,chrome:s,autoJoin:r.autoJoin===void 0?!s:!!r.autoJoin,selfView:r.selfView===void 0?!0:!!r.selfView,tileAspect:a,cssVars:h,strings:e.strings&&typeof e.strings=="object"?{...e.strings}:null,invite:{base:typeof d=="string"?d:null,updateUrl:u===void 0?s:!!u},landing:{browserUrl:typeof p=="string"?p:Ks,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!r.debug,log:typeof r.log=="function"?r.log:r.debug?(y,w)=>console.log(`${hn} ${y} ${JSON.stringify(w)}`):null,_liftImporter:typeof r._liftImporter=="function"?r._liftImporter:void 0}}var ha=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 vi="dxr-call:",Qs=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],yi="[inline3d/call] <dxr-call>",pe=r=>r!=null&&!/^(false|0|off|no)$/i.test(String(r).trim()),un=r=>{if(r==null||String(r).trim()==="")return;let e=/^\s*([0-9.]+)\s*\/\s*([0-9.]+)\s*$/.exec(String(r)),t=e?+e[1]/+e[2]:+r;return Number.isFinite(t)?t:void 0},z=r=>r==null||String(r).trim()===""?void 0:String(r).trim();function wi(r){let e=typeof r=="function"?r:l=>r&&typeof r.getAttribute=="function"?r.getAttribute(l):null,t={},i=(l,c)=>{c!==void 0&&(t[l]=c)};i("room",z(e("room")));let n=z(e("signaling"));n&&(t.signaling=fe(n,z(e("key"))?{key:z(e("key"))}:{})),i("key",z(e("key"))),i("camera",z(e("camera"))),i("layout",z(e("layout"))),i("maxPeers",un(e("max-peers")));let s=z(e("ui"));pe(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),pe(e("auto-join"))&&(t.autoJoin=!0);let o=z(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),pe(e("no-audio"))&&(t.audio=!1),pe(e("no-self-view"))&&(t.selfView=!1),pe(e("no-auto-converge"))&&(t.autoConverge=!1),z(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:z(e("accent")),tileAspect:un(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),z(e("invite-base"))&&(t.invite={base:z(e("invite-base"))}),z(e("browser-url"))&&(t.landing={browserUrl:z(e("browser-url"))}),pe(e("debug"))&&(t.debug=!0),t}var eo=typeof HTMLElement=="function"?HTMLElement:class{},me=class r extends eo{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={...wi(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||r.mount||bi;this._pending=new Promise(n=>n(i(this,t))).then(n=>{if(this._pending=null,e!==this._gen)return n.leave(),null;if(this.call=n,this._off=Qs.map(s=>n.on(s,o=>this._dispatch(s,o))),this._off.push(n.on("error",s=>console.warn(`${yi} ${s.code}: ${s.message}`))),this._dispatch("ready",{call:n}),n.state==="in-call"){this._dispatch("joined",{room:n.room,id:n.id});for(let s of n.peers)this._dispatch("peer",{id:s.id})}return n},n=>{throw this._pending=null,this._dispatch("error",{code:"mount-failed",message:String(n&&n.message||n),error:n||null}),console.warn(`${yi} mount failed: ${String(n&&n.message||n)}`),n}),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(vi+e,{detail:t,bubbles:!0,composed:!0}))}};function ct(r="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(r);return t?(t!==me&&console.warn(`${yi} <${r}> is already defined by another class; leaving it`),!1):(e.define(r,me),!0)}var G="[inline3d/call]",to=2e3,io=2500,ro=500,xi=.02,no=4,so=2,oo=200,fn=240,ao=66,lo=new Set(["I420","I420A","I422","I444","NV12"]);async function gn(r,e,t={}){if(!e||typeof e.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: addCall(wall, container, opts) needs a container element");let i=_i(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 n=new Si(r,e,i);return await n._init(),n.handle}async function bi(r,e={}){if(!r||typeof r.appendChild!="function")throw new TypeError("@displayxr/inline3d/call: mountCall(el, opts) needs a container element");let{wall:t,...i}=e,n=t||await ze(i.wallOptions);return gn(n,r,i)}var Si=class{constructor(e,t,i){this.o=i,this.t=an(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=rr(),this.room=i.room==="auto"?Ee(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=Ht(Ft),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=pt(),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 n of[...i])try{n(t)}catch(s){console.error(`${G} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${G} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${G} ${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 n=(h,d)=>this.log(h,d),s=null,o=null,a=at(e)?e:null;try{if(s=a||await hi({prefer:e,format:t||this.o.format,calibration:this.o.calibration,rectify:this.o.rectify||void 0,log:n}),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 dr({log:n})),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 f=new MediaStream([c,l].filter(Boolean)),m=this.local;return this.local={stream:f,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!==m?.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}),m&&m.owned&&m.cam&&m.cam!==s&&m.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return Nt({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=Wt(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",Be(location.href,this.room))}catch{}this._setState("joining");let e=new ke({signaling:this.o.signaling,id:this.id,maxPeers:this.o.maxPeers,iceServers:this.o.iceServers,log:(i,n)=>this.log(i,n)});this.transport=e;let t=null;try{t=await e.start({room:this.room,localStream:this.local.stream,sendFormat:this.local.format,onPeer:i=>this._onPeer(i),onPeerLeft:(i,n)=>this._onPeerLeft(i,n),onStream:(i,n)=>this.tiles.get(i)?.setStream(n),onMessage:(i,n)=>this._onMessage(i,n),onPeerState:(i,n)=>{this.tiles.get(i)?.setConn(n),this.emit("state",{id:i,state:n})},onRefused:i=>this.log("refused-peer",{id:i}),onGhost:(i,n)=>this._onGhost(i,n),onSignalingState:(i,n)=>{this.log("signaling",{state:i}),i==="closed"&&n&&this.error(n.code||"signaling-closed",n.message,n)}})}catch(i){throw this.transport=null,i&&i.code==="room-full"?(this._setState("full"),this.error("room-full",i.message,i)):(this._setState("lobby"),this.error(i.code||"join-failed",`could not join: ${i.message}`,i)),i}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}),setTimeout(()=>{this.transport===e&&this._reportTurn(t)},0),this.handle}_reportTurn(e){let t=e&&e.turn;!t||typeof t!="object"||(t.status==="off"&&t.reason==="cap"?this.error("turn-cap","relay (TURN) capacity for this month is used up; direct connections still work, but a participant behind a strict NAT may be unreachable",null):(t.reason==="budget"||t.reason==="rate")&&this.warning("turn-shed",t.reason==="rate"?"no relay (TURN) for this session: too many credential requests from this address this hour":"no relay (TURN) for this anonymous session: the hosted service is near its monthly relay budget (a publishable key keeps TURN)"))}_onPeer(e){if(this.tiles.has(e))return;let t=new ht(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 n=new ht(this,e);n.ghost=!0,this.tiles.set(e,n),n.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()},io))}_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 n=jt(t);if(n)return i.setHello(n);let s=zt(t);if(s)return i.setHint(s);let o=sr(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return Be(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,n=await this._openMedia(e,t,{keepOnFail:!0});return this.transport&&(await this.transport.replaceTrack("video",n.videoTrack,n.stream),await this.transport.setSendFormat(n.format),this.transport.broadcast(this.hello()),this.transport.broadcast(this.stateMsg())),i!==n.format&&this.log("send-format",{format:n.format}),{format:n.format,width:n.width,height:n.height,label:n.label}}retryCamera(){return this.setCamera(this.o.camera,{format:this.o.format})}sendHint(e){if(!this._hintGate(performance.now()))return!1;let t=zt({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=(...n)=>(i.pageClosed=!0,t.apply(e,n)),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=Vt(),n=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()-n)});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 ze()}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)},q(e,{baseMs:1e3,maxMs:15e3}))}_startLoop(){let e=0,t=i=>{this._raf=requestAnimationFrame(t);for(let n of this.tiles.values())n.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(`${G} 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=(n,s)=>this.log(n,s),t=this.o.liftOptions,i={webFallback:!0,...t&&t.models?{models:t.models}:{}};this._liftP=ut(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(n=>(this.liftApi=n,n.lift?(this.liftPool=mt({lift:n.lift,max:this.o.maxLifted,log:e,options:this.o.liftOptions}),this.liftPool.setDepth(this.depth),this.liftPool.setSpeaker(this.speakerId),!n.caps&&n.capabilities&&Promise.resolve().then(()=>n.capabilities(i)).then(s=>{n.caps=s||null,this._refreshLobby()}).catch(()=>{})):n.reason==="import-failed"||n.reason==="no-lift-export"?this.liftMissing=!0:n.reason!=="off"&&console.info(`${G} mono\u21923D unavailable (${n.reason}) \u2014 mono participants are shown flat`),this._rerouteMono(),this._refreshLobby(),n))}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),ro)}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 f={};c.forEach(d=>{d.type==="codec"&&(f[d.id]=d.mimeType)});let m={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 u=a._prevIn;m.in={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:f[d.codecId]||null,kbps:u?Math.round((d.bytesReceived-u.bytes)*8/(d.timestamp-u.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 u=a._prevOut;m.out={width:d.frameWidth||0,height:d.frameHeight||0,fps:d.framesPerSecond||0,codec:f[d.codecId]||null,kbps:u?Math.round((d.bytesSent-u.bytes)*8/(d.timestamp-u.t)):null,limitation:d.qualityLimitationReason||null,encoder:d.encoderImplementation||null},a._prevOut={bytes:d.bytesSent,t:d.timestamp}}}}),e&&(m.in||m.out)&&(a.quality=m,this.emit("quality",{id:o,...m}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>xi||a.remote.speaking),h>xi&&(!t||h>t.lvl)&&(t={id:o,lvl:h})}let n=t?t.id:null;n&&n!==this.speakerId?(this._challengeTicks=this._challenger===n?(this._challengeTicks||0)+1:1,this._challenger=n,this._challengeTicks>=2&&this._setSpeaker(n)):(this._challenger=null,this._challengeTicks=0);let s=!this.muted&&i>xi;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 n=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(n-s)>2&&this.container.style.setProperty("--dxr-call-fit",`${n}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;ln(e.ownerDocument||document),e.classList.add("dxr-call-host");for(let[n,s]of Object.entries(this.o.cssVars))e.style.setProperty(n,s);let i=this.ui={};i.banner=R("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[R("span",{text:t("banner2D")}),R("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=R("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=R("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=R("div",{class:"dxr-call-self",part:"self"}),i.bar=R("div",{class:"dxr-call-bar",part:"bar"}),i.foot=R("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=R("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||j(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new Mi(this,i.selfSlot):j(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(n,s,o,a="")=>R("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":n,title:n,html:s,onclick:o});e.mic=i(t("mute"),X.mic,()=>this.mute()),e.cam=i(t("cameraOff"),X.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=R("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"),X.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),X.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,R("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?X.micOff:X.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?X.camOff:X.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 n=this.inviteLink();if(!n)return;let s=this.t,o=R("input",{type:"text",readOnly:!0,value:n,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=R("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:s("copyLink")});a.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(n),a.textContent=s("copied")}catch{o.select(),a.textContent=s("pressCopy")}setTimeout(()=>a.textContent=s("copyLink"),1800)});let l=R("canvas",{"aria-label":s("qrLabel"),role:"img"});try{en(l,n,{px:4})}catch{l.style.display="none"}e.append(R("h3",{text:t}),R("p",{text:i}),R("div",{class:"dxr-call-invite"},[R("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,n=this.o.chrome&&(this.state==="lobby"||this.state==="idle"||this.state==="full"||this.state==="left");t.classList.toggle("dxr-call-host--lobby",n),j(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),j(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,f]of this.tiles)f.el.classList.toggle("dxr-call-tile--main",c===o);if(!this.o.chrome)return;this._refreshBar(),queueMicrotask(()=>this._fitGrid());let a=e.panel;if(n){j(a,!0),a.replaceChildren();let c=this.local,f=!!this.room,m=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(f?"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),u=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:d})}${this._liftHint()?` ${this._liftHint()}`:""}`,p=R("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(f?"join":"start")});p.addEventListener("click",()=>this.join().catch(()=>{}));let y=R("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(y),y.addEventListener("change",()=>this.setCamera(y.value).catch(b=>this.error("camera-failed",b.message,b)));let w=!c||!c.videoTrack?R("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;w?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(R("h3",{text:m}),R("p",{text:u}),R("div",{class:"dxr-call-row"},[this.state==="full"?null:p,w,y]))}else this.state==="in-call"&&s===0?(j(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(j(a,!0),a.replaceChildren(R("p",{text:i("joining")}))):j(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),j(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:It,wire:Ve,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()),self:this.self?this.self.diag():null,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(n=>n.kind==="videoinput")}catch{}let i=this.local?.videoTrack?.getSettings?.().deviceId;e.replaceChildren(...t.map((n,s)=>R("option",{value:n.deviceId,text:n.label||`Camera ${s+1}`}))),i&&(e.value=i),j(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(`${G} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${G} 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)}},n={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(n))Object.defineProperty(i,s,{enumerable:!1,configurable:!0,get(){return e._handleWarned?.has(s)||((e._handleWarned||=new Set).add(s),console.warn(`${G} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function co(r){let e=Math.min(globalThis.devicePixelRatio||1,2),t=Math.round((r.clientWidth||0)*e),i=Math.round((r.clientHeight||0)*e);return!t||!i?!1:((r.width!==t||r.height!==i)&&(r.width=t,r.height=i),!0)}function pn(r,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!co(r))return;let n=r.getContext("2d"),s=e.videoWidth,o=e.videoHeight;if(!s||!o||(e.readyState||0)<2)return;let a=t===null?s:s/2,l=U(a,o,r.width/r.height,0,0);n.save(),i&&(n.translate(r.width,0),n.scale(-1,1)),n.drawImage(e,(t||0)*a+l.sx,l.sy,l.sw,l.sh,0,0,r.width,r.height),n.restore()}var ht=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=Me(),this.autoTrack=Ye(),this.autoFocus=De(),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.luma=null,this.destroyed=!1,this.conv.depth=e.depth,this.hintGate=Ht(Ft),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=R("canvas"),this.cover=R("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=R("div",{class:"dxr-call-badge",part:"badge"}),this.plate=R("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=R("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=R("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,R("div",{class:"dxr-call-talk"})]),e.o.ui||j(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(ai(),oi)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return Ut(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,cursor:this.cursor?this.cursor.last:null,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())},to)}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||"",j(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(R("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",X.mutedSmall)}_maybeRoute(){!this.format||(this.video.readyState||0)<2||!this.video.videoWidth||this.reroute(!1)}reroute(e){let t=this.call,i=t.liftPool,n=this.forceFlat&&this.format==="sbs"?{route:"flat-left"}:$t({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=`${n.route}|${this.format}`;!e&&s===this.routedKey||(this.routedKey=s,this._unregister(),this.route=n.route,n.route==="woven-sbs"?this._registerWoven():n.route==="lifted"&&this._registerLifted(),t.log("route",{peer:this.id,route:n.route,format:this.format,mono3d:n.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:n.route,mono3d:n.mono3d||null,hello:this.hello}),this._renderBadge())}_registerWoven(){let e=this.call;this.convCanvas||(this.convCanvas=document.createElement("canvas")),this._paintConv(),j(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(j(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 n=s=>{s==="live"?this._liftShowing(!0):(s==="error"||s==="disposed")&&this._liftShowing(!1)};this._liftOff=[i.on?.("statechange",s=>n(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++>=so)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},q(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++>=no)return;let e=q(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(j(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.cursor?.idle(),this.route==="woven-sbs"?this._paintConv():this.route==="lifted"?this.liftLive||pn(this.canvas,this.video):pn(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 n=t/2,s=this.call.o.tileAspect,{w:o,h:a}=Se(n,i,s),l=this.convCanvas;(l.width!==2*o||l.height!==a)&&(l.width=2*o,l.height=a);let c=!!(this.cursor&&this.cursor.hovering);(this.call.o.autoConverge||c)&&this._sampleDisparity(e,t,i,c);let f=this.conv.step(n),m=l.getContext("2d"),h=[];for(let d of[0,1]){let u=h[d]=U(n,i,s,f,d);m.drawImage(e,d*n+u.sx,u.sy,u.sw,u.sh,d*o,0,o,a)}this.cursor&&this.cursor.draw(m,this.luma,{rL:h[0],rR:h[1],outW:o,outH:a,handle:this.handle},performance.now()/1e3)}_sampleDisparity(e,t,i,n=!1){let s=performance.now();if(this.autoPending||s-this.autoAt<(n?ao:oo))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&lo.has(h.format)){this.autoPending=!0;let d=this.autoGen,u=h.visibleRect?h.visibleRect.width:h.displayWidth,p=h.visibleRect?h.visibleRect.height:h.displayHeight,y=new Uint8Array(h.allocationSize());h.copyTo(y).then(w=>{if(d!==this.autoGen)return;let b=performance.now(),T=Math.max(1,Math.ceil(u/2/fn)),x=fr(y,w[0].offset,w[0].stride,u,p,T);this._applyMeasurement(x.img,x.w,x.h,x.w/u,s,performance.now()-b,"videoframe")}).catch(()=>{d===this.autoGen&&this._applyMeasurement(null,0,0,1,s,0,"videoframe")}).finally(()=>{h.close(),this.autoPending=!1});return}h&&h.close()}let o=Math.min(1,fn/(t/2)),a=Math.max(2,Math.round(t*o/2)*2),l=Math.max(2,Math.round(i*o));this.autoCanvas||(this.autoCanvas=document.createElement("canvas"));let c=this.autoCanvas;(c.width!==a||c.height!==l)&&(c.width=a,c.height=l);let f=c.getContext("2d",{willReadFrequently:!0}),m=null;try{f.drawImage(e,0,0,a,l),m=Je(f.getImageData(0,0,a,l).data,a*l)}catch{m=null}this._applyMeasurement(m,a,l,a/t,s,performance.now()-s,"canvas")}_applyMeasurement(e,t,i,n,s,o,a){if(this.destroyed||(e&&(this.luma={img:e,w:t,h:i,scale:n}),!this.call.o.autoConverge))return;let l=performance.now(),c=e?this.autoFocus.measure(e,t,i,s):null,f=this.autoTrack.push(c?c.d/n:null);this.conv.measuredPx=f,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(f*10)/10,at:{x:Math.round(c.x/n),y:Math.round(c.y/n)},ncc:Math.round(c.c*100)/100,method:c.method,via:a,ms:Math.round(o+(performance.now()-l))}))}_resetAutoConverge(){this.autoGen++,this.luma=null,this.autoTrack.reset(),this.autoFocus.reset(),this.conv.measuredPx=null,this.autoLocked=!1}destroy(){this.destroyed=!0,this.autoGen++,this.cursor?.dispose(),this.cursor=null,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()}},Mi=class{constructor(e,t){this.call=e,this.canvas=R("canvas"),this.badge=R("div",{class:"dxr-call-badge",part:"badge"}),this.plate=R("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=R("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=R("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,R("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"):"",j(this.plate,i||this.call.camOff),this.reroute(!1)}reroute(e){let t=this.call.local,i=t&&t.videoTrack?t.cam:null,n=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,n):(this.detach(),this.cam=i,this.view=di(n,this.canvas,i,{mirror:!0,autoConverge:!!this.call.o.autoConverge,cursor:this.call.o.cursor||void 0,aspect:this.call.o.tileAspect,onRouteChange:(s,o)=>{this.cam===i&&(this.call.log("self-route",{route:s,woven:o.woven,reason:o.reason}),this._badge())}})),this._badge()}_badge(){let e=this.call.t,t=!!(this.view&&this.view.woven);this.badge.replaceChildren(R("b",{text:`${e("you")} \xB7 ${e(t?"badge3D":"badge2D")}`})),this.badge.dataset.route=this.route||""}diag(){return this.view?this.view.weaveState():{route:null,woven:!1,reason:"no-camera",firstWoven:null,layerRetries:0}}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)}},ho="1.31",mn=new Set;function A(r,e,t){let i=()=>{mn.has(r)||(mn.add(r),console.warn(`${G} \`${r}\` is internal and leaves '@displayxr/inline3d/call' in ${ho} \u2014 import it from ${e} if you must, or stop depending on it`))};return typeof t=="function"?new Proxy(t,{apply(n,s,o){return i(),Reflect.apply(n,s,o)},construct(n,s){return i(),Reflect.construct(n,s)}}):t&&typeof t=="object"?new Proxy(t,{get(n,s,o){return typeof s=="string"&&i(),Reflect.get(n,s,o)}}):t}var ka=A("normalizeCallOptions","js/call/options.js",_i),Ta=A("newRoomId","js/call/wire.js",Wt),Da=A("isValidRoomId","js/call/wire.js",ce),La=A("buildInviteLink","js/call/wire.js",Be),Aa=A("normalizeHello","js/call/wire.js",jt),Oa=A("makeHello","js/call/wire.js",Nt),Pa=A("routeFor","js/call/wire.js",$t),Ia=A("badgeFor","js/call/wire.js",Ut),Fa=A("createLiveGate","js/call/wire.js",Vt),Wa=A("convergenceShiftPx","js/camera/converge.js",He),ja=A("lowPass","js/camera/converge.js",Ue),Na=A("clampShift","js/camera/converge.js",$e),za=A("eyeCropRect","js/camera/geometry.js",U),Ha=A("mirrorSwapOps","js/camera/geometry.js",ae),$a=A("mirrorSwapPixels","js/camera/geometry.js",Pt),Ua=A("maxBitrateKbps","js/call/wire.js",qe),Va=A("measureFocusDisparity","js/camera/disparity.js",Xt),Ba=A("preferVideoCodecs","js/call/sdp.js",Ce),qa=A("sortCodecCapabilities","js/call/sdp.js",Xe),Xa=A("VIDEO_CODEC_ORDER","js/call/sdp.js",Re),Ga=A("MeshTransport","js/call/transport.js",ke),Ja=A("clampMaxPeers","js/call/transport.js",Te),Ya=A("qrEncode","js/call/qr.js",pi),Ka=A("roomKey","js/call/signaling.js",mi);var Za=A("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:Ae.unreachable,cameraBusy:Ae.cameraBusy})),Qa=A("CALL_ACCENTS","js/call/ui.js",gi),el=A("normalizeMono3D","js/call/lift.js",be),tl=A("resolveLift","js/call/lift.js",ut),il=A("createLiftPool","js/call/lift.js",mt),rl=A("createFrameWatch","js/call/lift.js",pt),nl=A("liftConvergenceFor","js/call/lift.js",we),sl=A("liftPriorityFor","js/call/lift.js",Oe),ol=A("setLiftPriority","js/call/lift.js",ft),al=A("defaultLiftSpecifier","js/call/lift.js",dt),ll=A("LIFT_PRIORITY","js/call/lift.js",ve);ct();Ri(()=>new URL("./lift.js",import.meta.url).href);export{vi as CALL_EVENT_PREFIX,Gr as CAMERA_SDK,lt as DXR_SIGNAL_DEFAULT,me as DxrCallElement,gn as addCall,di as addCameraView,wi as attrsToOpts,Zi as createInline3D,ct as defineCallElement,fe as dxrSignaling,Yi as inline3DAvailable,at as isStereoCamera,bi as mountCall,hi as openCamera,Ee as parseInviteLink,Kt as parseStereoXmp,Sr as readJpegStereoMeta,Zt as readJpegXmp,Dr as readWebmStereoMeta,ze as sharedInline3D,ot as suggestedName};
|
package/js/camera/converge.js
CHANGED
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
/** Low-pass factor for the convergence shift (RFC §3): next = prev + α·(target − prev). */
|
|
8
8
|
export const CONVERGENCE_ALPHA = 0.2;
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The convergence shift never exceeds this fraction of the per-eye width, either way. 0.2: a
|
|
12
|
+
* 120 mm-baseline camera (the SR laptop's) sees a face at 0.6 m at ~22% of the eye width, so it
|
|
13
|
+
* needs ~11% per eye — 0.12 left no room to lean in.
|
|
14
|
+
*/
|
|
15
|
+
export const CONVERGENCE_MAX_FRACTION = 0.2;
|
|
12
16
|
|
|
13
17
|
/** `setDepth(v)`: v in [-1, 1] adds v times this fraction of the per-eye width to the shift. */
|
|
14
18
|
export const DEPTH_RANGE_FRACTION = 0.05;
|
package/js/camera/disparity.js
CHANGED
|
@@ -144,7 +144,11 @@ export function matchBlock(img, W, H, x0, y0, bw, bh, { dMin, dMax, dyMax = 2, u
|
|
|
144
144
|
export function blockDisparities(img, W, H, o = {}) {
|
|
145
145
|
const E = W / 2;
|
|
146
146
|
const b = o.block || Math.max(8, Math.round(E / 20));
|
|
147
|
-
|
|
147
|
+
// One block per block width. A sparser grid (1.5 b) left a dim, grayscale SR-camera frame with
|
|
148
|
+
// ~9 matched blocks, 3-4 of them on the face — too few to form a mode — so the background won
|
|
149
|
+
// and auto-convergence flipped between the two. At 1 b: ~36 blocks, the face every frame, and a
|
|
150
|
+
// steadier value (±1 px instead of ±4); ~13 ms per full search at 240 px per eye.
|
|
151
|
+
const step = o.step || b;
|
|
148
152
|
const dMax = o.dMax ?? Math.round(E * 0.3);
|
|
149
153
|
const dMin = o.dMin ?? -Math.round(E * 0.05);
|
|
150
154
|
const x0 = Math.round(E * (o.roiX0 ?? 0.15));
|
|
@@ -165,12 +169,17 @@ export function blockDisparities(img, W, H, o = {}) {
|
|
|
165
169
|
* The subject = the NEAREST strong disparity mode: the largest `d` whose ±`tol` bin holds at least
|
|
166
170
|
* `minFrac` of the matched blocks (and `minBlocks`). Returns its members, or null.
|
|
167
171
|
*/
|
|
168
|
-
export function nearestMode(blocks, { tol = 2, minFrac = 0.12, minBlocks = 3 } = {}) {
|
|
172
|
+
export function nearestMode(blocks, { tol = 2, relTol = 0.1, minFrac = 0.12, minBlocks = 3 } = {}) {
|
|
169
173
|
if (!blocks.length) return null;
|
|
170
174
|
const need = Math.max(minBlocks, Math.ceil(blocks.length * minFrac));
|
|
171
175
|
const ds = blocks.map((b) => b.d).sort((a, b) => b - a); // descending: nearest first
|
|
172
176
|
for (const d of ds) {
|
|
173
|
-
|
|
177
|
+
// The bin widens with the disparity: a near subject's own relief spreads its blocks over
|
|
178
|
+
// ~relTol of its disparity (the spread scales with baseline / distance, as d does), so a
|
|
179
|
+
// fixed +-2 px split a face from a wide-baseline (120 mm) camera into groups too small to
|
|
180
|
+
// count, and the flat background won.
|
|
181
|
+
const t = Math.max(tol, relTol * Math.abs(d));
|
|
182
|
+
const members = blocks.filter((b) => Math.abs(b.d - d) <= t);
|
|
174
183
|
if (members.length >= need) {
|
|
175
184
|
const md = members.map((b) => b.d).sort((a, b) => a - b);
|
|
176
185
|
return { d: md[md.length >> 1], members };
|
package/js/camera/pair-cursor.js
CHANGED
|
@@ -72,21 +72,116 @@ export function pairFootprintDisparity(luma, geo, u, v, height, aspect) {
|
|
|
72
72
|
const dMin = -Math.round(E * 0.05);
|
|
73
73
|
const { rL, rR } = geo;
|
|
74
74
|
const k = geo.outW / rL.sw; // output px per source px
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const swp = swappedHalves(luma);
|
|
76
|
+
const found = []; // { d, x, y, eye }: a consistent match and WHERE it was taken
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
const sample = (su, pv) => {
|
|
79
|
+
const y = Math.round((rL.sy + pv * rL.sh) * scale - b / 2);
|
|
80
|
+
if (y < 0 || y + b > h) return;
|
|
81
|
+
const xl = Math.round((rL.sx + su * rL.sw) * scale - b / 2);
|
|
82
|
+
const xr = Math.round((rR.sx + su * rR.sw) * scale - b / 2);
|
|
83
|
+
// The arrow is far smaller than a block (~6 vs 12 copy px at the OS arrow's size), so
|
|
84
|
+
// neighbouring footprint points land on the SAME block: match each block once.
|
|
85
|
+
if (!seen.has(`L${xl},${y}`)) {
|
|
86
|
+
seen.add(`L${xl},${y}`);
|
|
87
|
+
const dl = consistentMatch(img, swp, w, h, xl, y, b, dMin, dMax);
|
|
88
|
+
if (dl !== null) found.push({ d: dl, x: xl, y, eye: 0 });
|
|
89
|
+
}
|
|
90
|
+
if (!seen.has(`R${xr},${y}`)) {
|
|
91
|
+
seen.add(`R${xr},${y}`);
|
|
92
|
+
const dr = consistentMatch(swp, img, w, h, xr, y, b, -dMax, -dMin); // right-anchored: d' = -d
|
|
93
|
+
if (dr !== null) found.push({ d: -dr, x: xr, y, eye: 1 });
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
// The tip, then a ring centred on the arrow's body: that is what content must not overlap. Each
|
|
97
|
+
// point is sampled from BOTH eyes' images (the pointer's spot in the left eye matched into the
|
|
98
|
+
// right, and the same spot in the right eye matched into the left), so neither eye is favoured:
|
|
99
|
+
// at a foreground edge one eye's block can sit on the subject and the other's on the background.
|
|
100
|
+
// Every match must also pass the left-right consistency check (consistentMatch).
|
|
101
|
+
let cu = 0, cv = 0, n = 0;
|
|
77
102
|
for (const [pu, pv] of cursorArrowFootprint(u, v, height, aspect)) {
|
|
78
103
|
if (!(pu >= 0 && pu <= 1 && pv >= 0 && pv <= 1)) continue;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
104
|
+
sample(geo.mirror ? 1 - pu : pu, pv);
|
|
105
|
+
cu += pu; cv += pv; n++;
|
|
106
|
+
}
|
|
107
|
+
if (!n) return null;
|
|
108
|
+
// ...plus four blocks half a block around the footprint's centre, so that real content under
|
|
109
|
+
// the arrow is seen by more than one distinct block (pairNearestSupported needs that).
|
|
110
|
+
const du = (b / 2 / scale) / rL.sw, dv = (b / 2 / scale) / rL.sh;
|
|
111
|
+
for (const [ou, ov] of [[-du, 0], [du, 0], [0, -dv], [0, dv]]) {
|
|
112
|
+
const pu = cu / n + ou, pv = cv / n + ov;
|
|
113
|
+
if (pu >= 0 && pu <= 1 && pv >= 0 && pv <= 1) sample(geo.mirror ? 1 - pu : pu, pv);
|
|
114
|
+
}
|
|
115
|
+
// Source disparity → displayed: each eye's crop moved its half by its own offset.
|
|
116
|
+
for (const f of found) f.d = (f.d / scale - (rL.sx - rR.sx)) * k;
|
|
117
|
+
return pairNearestSupported(found, (PAIR_SUPPORT_COPY_PX / scale) * k, b / 2);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Two consistent footprint matches must agree (within this many px of the grayscale copy) before
|
|
122
|
+
* the nearest is believed: content that comes out of the screen covers several blocks, a lone
|
|
123
|
+
* block claiming something nearer than the rest is noise.
|
|
124
|
+
*/
|
|
125
|
+
export const PAIR_SUPPORT_COPY_PX = 1.5;
|
|
126
|
+
|
|
127
|
+
/** The SBS copy with its halves swapped (cached per copy): matching it is matching right → left. */
|
|
128
|
+
const _swapped = new WeakMap();
|
|
129
|
+
function swappedHalves(luma) {
|
|
130
|
+
let s = _swapped.get(luma);
|
|
131
|
+
if (s) return s;
|
|
132
|
+
const { img, w, h } = luma;
|
|
133
|
+
const E = w / 2;
|
|
134
|
+
s = new Uint8Array(w * h);
|
|
135
|
+
for (let y = 0; y < h; y++) {
|
|
136
|
+
const o = y * w;
|
|
137
|
+
for (let x = 0; x < E; x++) {
|
|
138
|
+
s[o + x] = img[o + E + x];
|
|
139
|
+
s[o + E + x] = img[o + x];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
_swapped.set(luma, s);
|
|
143
|
+
return s;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* A block of image A's left half matched into its right half, kept only if the matched block,
|
|
148
|
+
* matched BACK (in B = A with its halves swapped), lands within 1 px of where it started — the
|
|
149
|
+
* classic left-right consistency check. A block straddling a depth edge (half subject, half
|
|
150
|
+
* background, each eye seeing a different half) fails it instead of returning a random depth.
|
|
151
|
+
* @returns {number|null} disparity in A's convention (left x − right x), copy px
|
|
152
|
+
*/
|
|
153
|
+
export function consistentMatch(A, B, w, h, x, y, b, dMin, dMax) {
|
|
154
|
+
const E = w / 2;
|
|
155
|
+
if (x < 0 || x + b > E) return null;
|
|
156
|
+
const m = matchBlock(A, w, h, x, y, b, b, { dMin, dMax, dyMax: 2 });
|
|
157
|
+
if (!m || m.c < MIN_NCC) return null;
|
|
158
|
+
const xb = Math.round(x - m.d);
|
|
159
|
+
const yb = y + m.dy;
|
|
160
|
+
if (xb < 0 || xb + b > E || yb < 0 || yb + b > h) return null;
|
|
161
|
+
const back = matchBlock(B, w, h, xb, yb, b, b, { dMin: -Math.ceil(m.d) - 2, dMax: -Math.floor(m.d) + 2, dyMax: 1 });
|
|
162
|
+
if (!back || back.c < MIN_NCC || Math.abs(-back.d - m.d) > 1) return null;
|
|
163
|
+
return m.d;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* The nearest disparity that an INDEPENDENT second sample corroborates (within `tol`), else null.
|
|
168
|
+
* Independent = taken from the other eye's image, or from a block at least `minSep` copy px away:
|
|
169
|
+
* two footprint points inside one block are one witness, not two. (A block straddling a face edge
|
|
170
|
+
* and a bright window matched at a bogus +49 px, consistently, and its twin counted as support.)
|
|
171
|
+
* @param {Array<{d:number, x?:number, y?:number, eye?:number}|number>} samples output px, + = in front
|
|
172
|
+
* @returns {number|null}
|
|
173
|
+
*/
|
|
174
|
+
export function pairNearestSupported(samples, tol, minSep = 0) {
|
|
175
|
+
const S = samples.map((s) => (typeof s === 'number' ? { d: s, x: 0, y: 0, eye: -1 } : s));
|
|
176
|
+
if (S.length < 2) return null;
|
|
177
|
+
const sorted = [...S].sort((p, q) => q.d - p.d); // nearest first
|
|
178
|
+
const independent = (p, q) => p.eye === -1 || p.eye !== q.eye || Math.abs(p.x - q.x) + Math.abs(p.y - q.y) >= minSep;
|
|
179
|
+
for (const p of sorted) {
|
|
180
|
+
for (const q of sorted) {
|
|
181
|
+
if (q !== p && Math.abs(p.d - q.d) <= tol && independent(p, q)) return p.d;
|
|
182
|
+
}
|
|
88
183
|
}
|
|
89
|
-
return
|
|
184
|
+
return null;
|
|
90
185
|
}
|
|
91
186
|
|
|
92
187
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.42.
|
|
3
|
+
"version": "1.42.1",
|
|
4
4
|
"description": "Turn any HTML <canvas> into a 3D window on a spatial display, inside an ordinary web page, for the DisplayXR Browser. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|