@displayxr/inline3d 1.47.1 → 1.47.3

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 CHANGED
@@ -5,6 +5,39 @@ 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.47.3 — 2026-10-31
9
+
10
+ ### Fixed — a rear 3D camera's view was mirrored (`./camera`, `./call`)
11
+
12
+ Touches `./camera` (`addCameraView`, new read-only `StereoCamera.facing`) and `./call` (its self
13
+ tile). Front cameras and webcams behave exactly as before.
14
+
15
+ - `addCameraView`'s `mirror` now defaults to true **unless the track faces the environment**
16
+ (`getSettings().facingMode === 'environment'`, a rear camera). Mirroring is right for a self view
17
+ and wrong for a camera pointed at the world: on a tablet's rear 3D camera the scene came out
18
+ mirrored (each half flipped and the eyes swapped). An unknown facing (most desktop webcams) still
19
+ mirrors; an explicit `mirror` still wins.
20
+ - `StereoCamera.facing`: the track's `facingMode` (`'user'`, `'environment'`, `'left'`, `'right'`)
21
+ or null when the browser does not say.
22
+ - `./call`'s self tile uses the same default (it passed `mirror: true`), and `samples/camera`
23
+ initialises its Mirror checkbox from the view.
24
+
25
+ ## 1.47.2 — 2026-10-30
26
+
27
+ ### Docs only — two more panel findings in the shipped guide
28
+
29
+ No code change. `docs/making-3d-look-right.md` and `docs/woven-canvas-rules.md` (both in the
30
+ package):
31
+
32
+ - **Rule 9:** a `firstWoven` of `woven: false` is not "no 3D here". Drop the cover and keep drawing
33
+ both eyes, since the layer can still join, and go flat only on `onLayerLost` or with no session.
34
+ Never draw one full-width flat picture into a canvas the browser is still weaving: each eye
35
+ would see a different half of it. To show a flat picture on purpose, remove the scene, or call
36
+ `setStereoEnabled(false)` and keep drawing every view.
37
+ - **Rule 5:** in front of the glass, contrast matters more than the depth number. Keep bright
38
+ subjects off near-black backgrounds, above all the ones that come closest; dark grey is the
39
+ minimum, not the target.
40
+
8
41
  ## 1.47.1 — 2026-10-29
9
42
 
10
43
  ### Fixed — a splat on a camera rig briefly declared convergence at infinity (`./splat`, PlayCanvas)
package/camera.d.ts CHANGED
@@ -157,6 +157,8 @@ export interface StereoCamera {
157
157
  readonly eyeWidth: number;
158
158
  readonly deviceId: string | null;
159
159
  readonly label: string;
160
+ /** The track's `facingMode`: 'user', 'environment', 'left', 'right', or null when the browser does not say. */
161
+ readonly facing: 'user' | 'environment' | 'left' | 'right' | (string & {}) | null;
160
162
  /** True when this module opened the device (and `close()` stops it); false for a page-supplied stream. */
161
163
  readonly owned: boolean;
162
164
  /** Devices tried and not used (busy, denied, not a pair) — the clue a `'camera-busy'` report carries. */
@@ -203,7 +205,10 @@ export interface PairCursorOptions {
203
205
  }
204
206
 
205
207
  export interface CameraViewOptions {
206
- /** Selfie mirroring, done right for a pair (each half mirrored AND swapped). Default true. */
208
+ /**
209
+ * Selfie mirroring, done right for a pair (each half mirrored AND swapped). Default: true unless
210
+ * the camera faces the environment ({@link StereoCamera.facing} `'environment'`, a rear camera).
211
+ */
207
212
  mirror?: boolean;
208
213
  /** Measure the face's disparity ~5×/s and converge on it (the face at the display plane). Default false. */
209
214
  autoConverge?: boolean;
package/dist/call.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @displayxr/inline3d 1.47.1 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
1
+ /* @displayxr/inline3d 1.47.3 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
2
2
  var Ds=Object.defineProperty;var le=(r,e)=>()=>(r&&(e=r(r=0)),e);var Ps=(r,e)=>{for(var t in e)Ds(r,t,{get:e[t],enumerable:!0})};function vr(r,e,t=1){let i=Je,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])),d=r?.nominalViewerPosition?.z,f=Number.isFinite(d)&&d>.1;return{canvasSizeM:[(e?.width||0)*c,(e?.height||0)*c],metersPerCssPx:c,displaySizeM:s,nominalViewerM:f?d:i.nominalViewerM,eyeSeparationM:i.eyeSeparationM,source:{size:n?"display":"default",viewer:f?"display":"default",eyeSeparation:"default"}}}var Je,Bt=le(()=>{"use strict";Je=Object.freeze({displaySizeM:Object.freeze([.3456,.1944]),displayPixels:Object.freeze([1920,1080]),nominalViewerM:.65,eyeSeparationM:.063})});function ut(r,e,t,i,n,s,o,a,l,c,d){if(s<0||s+a>t||o<0)return-1;let f=0,h=0,u=0,p=a*l;for(let _=0;_<l;_++){let b=(n+_)*e+i,S=(o+_)*e+t+s;for(let x=0;x<a;x++){let O=r[S+x];f+=O,h+=O*O,u+=r[b+x]*O}}let m=f/p,g=h/p-m*m;return g<1?-1:(u/p-c*m)/(d*Math.sqrt(g))}function Oo(r,e,t,i,n,s){let o=0,a=0;for(let d=0;d<s;d++){let f=(i+d)*e+t;for(let h=0;h<n;h++){let u=r[f+h];o+=u,a+=u*u}}let l=n*s,c=o/l;return{mean:c,std:Math.sqrt(Math.max(0,a/l-c*c))}}function _e(r,e,t,i,n,s,o,{dMin:a,dMax:l,dyMax:c=2,uniq:d}={}){let f=e/2,{mean:h,std:u}=Oo(r,e,i,n,s,o);if(u<6)return null;let p=-2,m=0,g=0,_=new Map,b=(k,v,w,y,M)=>{for(let I=y;I<=M;I++){let T=n+I;if(!(T<0||T+o>t))for(let N=k;N<=v;N+=w){let $=ut(r,e,f,i,n,i-N,T,s,o,h,u);$>(_.get(N)??-2)&&_.set(N,$),$>p&&(p=$,m=N,g=I)}}},S=l-a>8;if(b(a,l,S?2:1,-c,c),S&&p>-1){let k=m,v=g;b(Math.max(a,k-2),Math.min(l,k+2),1,Math.max(-c,v-1),Math.min(c,v+1))}if(p<-1)return null;let x=-2,O=k=>{let v=-2;for(let w=-c;w<=c;w++){let y=n+w;if(!(y<0||y+o>t))for(let M=k-1;M<=k+1;M++)v=Math.max(v,ut(r,e,f,i,n,i-M,y,s,o,h,u))}return v};for(let[k,v]of _){if(Math.abs(k-m)<3||v<=x)continue;let y=v>=(_.get(k-2)??-2)&&v>=(_.get(k+2)??-2)&&v>0?O(k):v;y>x&&(x=y)}if(l-a>12&&x>-2&&p-x<(d??.08))return null;let E=ut(r,e,f,i,n,i-(m-1),n+g,s,o,h,u),C=ut(r,e,f,i,n,i-(m+1),n+g,s,o,h,u),P=0,D=E-2*p+C;return E>-1&&C>-1&&D<0&&(P=Math.max(-.5,Math.min(.5,.5*(E-C)/D))),{d:m+P,dy:g,c:p}}function Do(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)),d=Math.round(n*(i.roiX1??.85))-s,f=Math.round(t*(i.roiY0??.05)),h=Math.round(t*(i.roiY1??.85))-s,u=[];for(let p=f;p<=h;p+=o)for(let m=c;m<=d;m+=o){let g=_e(r,e,t,m,p,s,s,{dMin:l,dMax:a,dyMax:i.dyMax??2,uniq:i.uniq});g&&g.c>=(i.minNcc??.8)&&u.push({x:m,y:p,...g})}return u}function Po(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(d=>Math.abs(d.d-a)<=l);if(c.length>=s){let d=c.map(f=>f.d).sort((f,h)=>f-h);return{d:d[d.length>>1],members:c}}}return null}function Ao(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 Si(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",d=0,f=null;if(!l){let S=Do(r,e,t,{...i,block:s,dMax:o,dMin:a});d=S.length;let x=Po(S,i);if(!x)return null;l=Ao(x.members,s),f=x.d,c="mode"}let h=Math.round(s*(i.refineW??3)),u=Math.round(s*(i.refineH??1.5)),p=Math.round(Math.max(0,Math.min(n-h,l.x-h/2))),m=Math.round(Math.max(0,Math.min(t-u,l.y-u/2))),g=f===null?a:Math.max(a,Math.floor(f)-4),_=f===null?o:Math.min(o,Math.ceil(f)+4),b=_e(r,e,t,p,m,h,u,{dMin:g,dMax:_,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:d}:f!==null?{d:f,x:l.x,y:l.y,c:0,method:c,blocks:d}:null}function dt(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 ft({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 rn(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 Lo(r,e,t,i,n,s,o,a,l,c){let d=e/2,f=n*s,h=0,u=0;for(let b=0;b<f;b++)h+=i[b],u+=i[b]*i[b];h/=f;let p=Math.sqrt(Math.max(1e-6,u/f-h*h)),m=-2,g=o,_=a;for(let b=Math.max(0,a-c);b<=Math.min(t-s,a+c);b++)for(let S=Math.max(0,o-l);S<=Math.min(d-n,o+l);S++){let x=0,O=0,E=0;for(let k=0;k<s;k++){let v=(b+k)*e+S;for(let w=0;w<n;w++){let y=r[v+w];x+=y,O+=y*y,E+=y*i[k*n+w]}}let C=x/f,P=O/f-C*C;if(P<1)continue;let D=(E/f-C*h)/(Math.sqrt(P)*p);D>m&&(m=D,g=S,_=b)}return{x:g,y:_,c:m}}function Ue({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,d,f,h,u={}){let p=d/2,m=u.block||Math.max(8,Math.round(p/20)),g=Math.round(m*3),_=Math.round(m*1.5),b=null;if(o&&o.w===g&&o.h===_){let C=Lo(c,d,f,o.tpl,g,_,o.x,o.y,t,i);if(C.c>=n){let P=_e(c,d,f,C.x,C.y,g,_,{dMin:Math.floor(o.d)-e,dMax:Math.ceil(o.d)+e,dyMax:2});P&&P.c>=.8&&(b={m:P,f:C})}}let S=({m:C,f:P})=>(o={...o,x:P.x,y:P.y,d:C.d,tpl:rn(c,d,P.x,P.y,g,_)},{d:C.d,x:P.x+g/2,y:P.y+_/2,c:C.c,method:"track",blocks:0});if(b&&h-o.at<r)return S(b);let x=Si(c,d,f,u);if(b&&(!x||Math.abs(x.d-b.m.d)>s)){let C=x&&a&&Math.abs(a.d-x.d)<=3;if(a=x&&!C?{d:x.d}:null,!C)return o.at=h,S(b)}else a=null;if(!x)return o=null,null;let O=Math.round(Math.max(0,Math.min(p-g,x.x-g/2))),E=Math.round(Math.max(0,Math.min(f-_,x.y-_/2)));return o={x:O,y:E,d:x.d,tpl:rn(c,d,O,E,g,_),w:g,h:_,at:h},x},reset(){o=null,a=null}}}function nn(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 u=0;u<l;u++)for(let p=0;p<a;p++){let m=0;for(let g=0;g<o;g++){let _=e+(u*o+g)*t+p*o;for(let b=0;b<o;b++)m+=r[_+b]}c[u*a+p]=m/h|0}return{img:c,w:a,h:l}}let d=o>>2,f=3*o>>2;for(let h=0;h<l;h++){let u=e+(h*o+d)*t,p=e+(h*o+f)*t;for(let m=0;m<a;m++){let g=m*o+d,_=m*o+f;c[h*a+m]=r[u+g]+r[u+_]+r[p+g]+r[p+_]>>2}}return{img:c,w:a,h:l}}var Mi=le(()=>{"use strict"});function vt(r,e="@displayxr/inline3d"){if(r==null||r===!0)return{...ve};r===!1&&(r="off");let t=()=>new Error(`${e}: cursor.soften ${JSON.stringify(r)} \u2014 expected ${mt.map(s=>`'${s}'`).join(" | ")} or { ${gt.join(", ")} }.`);if(typeof r=="string"){if(!mt.includes(r))throw t();return{...ve,...sn(r)}}if(typeof r!="object"||Array.isArray(r))throw t();let i=Object.keys(r).filter(s=>!gt.includes(s));if(i.length)throw new Error(`${e}: cursor.soften \u2014 unknown option(s) ${i.join(", ")}; expected ${gt.join(", ")}.`);if(r.mode!==void 0&&!mt.includes(r.mode))throw t();let n={...ve,...sn(r.mode??"both")};for(let s of Object.keys(_t)){if(r[s]===void 0)continue;let[o,a,l]=_t[s];if(!Io(s,r[s]))throw new Error(`${e}: cursor.soften.${s} must be a number in ${l?"(":"["}${o}, ${a}].`);n[s]=r[s]}return n}function an(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 { ${pt.join(", ")} }.`);let t=Object.keys(r).filter(i=>!pt.includes(i));if(t.length)throw new Error(`${e}: cursor \u2014 unknown option(s) ${t.join(", ")}; expected ${pt.join(", ")}.`);if(r.anchor!==void 0&&!Ei.includes(r.anchor))throw new Error(`${e}: cursor.anchor "${r.anchor}" \u2014 expected ${Ei.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'.`);if(r.debug!==void 0&&typeof r.debug!="boolean"&&r.debug!=="both")throw new Error(`${e}: cursor.debug ${JSON.stringify(r.debug)} \u2014 expected true, false or 'both'.`);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.`);if(r.soften!==void 0&&vt(r.soften,e),r.shape!==void 0&&!ye.includes(r.shape))throw new Error(`${e}: cursor.shape ${JSON.stringify(r.shape)} \u2014 expected ${ye.map(i=>`'${i}'`).join(" | ")}.`);if(r.shapeFor!==void 0&&r.shapeFor!==null&&typeof r.shapeFor!="function")throw new Error(`${e}: cursor.shapeFor must be a function (hit) => shape.`);return{...r}}function yt(r,e="@displayxr/inline3d"){let t=an(r,e);if(!t)return null;let i=Object.keys(t).filter(n=>!on.includes(n));if(i.length)throw new Error(`${e}: cursor \u2014 ${i.join(", ")} not supported on a stereo pair; expected ${on.join(", ")}.`);return t}var Ei,pt,we,ye,mt,ve,_t,gt,Io,sn,on,be=le(()=>{"use strict";Ei=Object.freeze(["hybrid","screen","world"]),pt=Object.freeze(["height","margin","anchor","pointerScope","debug","soften","shape","shapeFor"]),we=Object.freeze(["arrow","pointer","grab","grabbing","move","text","vertical-text","crosshair","not-allowed","help","wait","progress","copy","alias","context-menu","cell","ns-resize","ew-resize","nesw-resize","nwse-resize","col-resize","row-resize","zoom-in","zoom-out"]),ye=Object.freeze(["auto","none",...we]),mt=Object.freeze(["both","off","alpha","blur"]),ve=Object.freeze({blur:!0,alpha:!0,blurK:.1,blurMaxPx:8,blurMaxFrac:.06,alphaMin:.5,fullD:.03}),_t=Object.freeze({blurK:[0,1e3,!1],blurMaxPx:[0,8,!1],blurMaxFrac:[0,.5,!1],alphaMin:[0,1,!1],fullD:[0,1e3,!0]}),gt=Object.freeze(["mode",...Object.keys(_t)]),Io=(r,e)=>{let[t,i,n]=_t[r];return typeof e=="number"&&Number.isFinite(e)&&e>=t&&e<=i&&!(n&&e<=t)},sn=r=>({blur:r==="both"||r==="blur",alpha:r==="both"||r==="alpha"});on=Object.freeze(["height","pointerScope","soften","shape","shapeFor"])});function Pi(r){return typeof r=="string"&&kn[r.trim().toLowerCase()]||"arrow"}function Uo(r){let e=[],t=0,i="",n="";for(let s=0;s<r.length;s++){let o=r[s];if(i){if(o==="\\"&&s+1<r.length){n+=o+r[++s];continue}o===i&&(i="")}else if(o==='"'||o==="'")i=o;else if(o==="(")t++;else if(o===")")t=Math.max(0,t-1);else if(o===","&&t===0){e.push(n.trim()),n="";continue}n+=o}return n.trim()&&e.push(n.trim()),e}function Ai(r){if(typeof r!="string")return{images:[],keyword:"auto"};let e=St.get(r);if(e)return e;let t=[],i="auto";for(let n of Uo(r)){let s=/^url\(\s*(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)'|([^)\s]*))\s*\)\s*(.*)$/is.exec(n);if(s){let o=(s[1]??s[2]??s[3]??"").replace(/\\(.)/g,"$1"),a=(s[4]||"").trim().split(/\s+/).filter(Boolean).map(Number),l=a.length===2&&a.every(Number.isFinite)?[a[0],a[1]]:null;o&&t.push({url:o,hotspot:l});continue}/^(-webkit-)?image-set\(/i.test(n)||(i=n.trim().toLowerCase())}return e=Object.freeze({images:Object.freeze(t),keyword:i}),St.size>64&&St.clear(),St.set(r,e),e}function Tn(r){return Pi(Ai(r).keyword)}function On(r,e=0){if(!r||r.byteLength<22)return null;let t=new DataView(r);if(t.getUint16(0,!0)!==0||t.getUint16(2,!0)!==2)return null;let i=t.getUint16(4,!0),n=-1;for(let o=0;o<i&&6+16*o+16<=r.byteLength;o++){let a=t.getUint8(6+16*o)||256;if((n<0||a===e)&&(n=o),a===e)break}if(n<0)return null;let s=6+16*n;return[t.getUint16(s+4,!0),t.getUint16(s+6,!0)]}function Dn(r,e=Li){let t=Ai(r);for(let i of t.images){let n=e.get(i.url);if(n.state==="failed")continue;if(n.state!=="ready")break;let s=Math.min(1,Cn/Math.max(n.width,n.height)),o=i.hotspot||n.curHotspot||[0,0],a=n.width*s,l=n.height*s,c=[Math.min(a,Math.max(0,o[0]*s)),Math.min(l,Math.max(0,o[1]*s))];return{kind:"image",key:i.url,entry:n,width:a,height:l,hotspot:c}}return Me(Pi(t.keyword))}function Me(r){if(r==="none")return{kind:"none"};let e=we.includes(r)?r:"arrow";return{kind:"shape",name:e,key:`shape:${e}`}}function R(r,e,t,i,[n=0,s=0,o=0,a=0]=[]){let l=[],c=(d,f)=>{let h=l[l.length-1];(!h||Math.abs(h[0]-d)>1e-9||Math.abs(h[1]-f)>1e-9)&&l.push([d,f])};return c(r+n,e),c(t-s,e),c(t,e+s),c(t,i-o),c(t-o,i),c(r+a,i),c(r,i-a),c(r,e+n),l.length>1&&Math.abs(l[0][0]-l[l.length-1][0])<1e-9&&Math.abs(l[0][1]-l[l.length-1][1])<1e-9&&l.pop(),l}function Et(r,e,t,i,n,s=n/3.5){let o=t-r,a=i-e,l=Math.hypot(o,a),c=o/l,d=a/l,f=-d*(n/2),h=c*(n/2),u=t-c*s,p=i-d*s,m=1-2*s/n;return Ee([[r+f,e+h],[u+f,p+h],[t+f*m,i+h*m],[t-f*m,i-h*m],[u-f,p-h],[r-f,e-h]])}function xn(r,e,t,i,n){let s=t-r,o=i-e,a=Math.hypot(s,o),l=-o/a*(n/2),c=s/a*(n/2);return Ee([[r+l,e+c],[t+l,i+c],[t-l,i-c],[r-l,e-c]])}function Pn(r,e,t,i=20){return Ee(Array.from({length:i},(n,s)=>[r+t*Math.cos(2*Math.PI*s/i),e+t*Math.sin(2*Math.PI*s/i)]))}function Bo(r,e,t,i,n=24){let s=[],o=(a,l)=>[r+a*Math.cos(l),e+a*Math.sin(l)];for(let a=0;a<n;a++){let l=[0,1,2,3].map(c=>2*Math.PI*(a+c)/n);s.push(Ee([...l.map(c=>o(i,c)),...l.reverse().map(c=>o(t,c))]))}return s}function qo(){return{pointer:{hot:[6.8,0],parts:[R(5,0,8.6,14,[1.2,1.2,0,0]),R(7.6,5.4,10.9,14,[1.1,1.1,0,0]),R(9.9,6.4,13.2,14,[1.1,1.1,0,0]),R(12.2,7.6,15.2,14,[.9,.9,0,0]),R(4.2,10.8,15.2,19,[0,0,3,2.2]),Et(7.4,15,1,9,3.6)]},grab:{hot:[8.6,12.5],parts:[R(3,2.6,6.6,12.4,[1.2,1.2,0,0]),R(5.6,.6,9.2,12.4,[1.2,1.2,0,0]),R(8.2,1.4,11.8,12.4,[1.2,1.2,0,0]),R(10.8,3.6,14.2,12.4,[1.1,1.1,0,0]),R(3,9.4,14.2,18,[0,0,2.6,2.6]),Et(6.2,14.4,.4,7,3.6)]},grabbing:{hot:[8.6,13],parts:[R(3,5.6,6.6,12.4,[1.2,1.2,0,0]),R(5.6,5,9.2,12.4,[1.2,1.2,0,0]),R(8.2,5.2,11.8,12.4,[1.2,1.2,0,0]),R(10.8,6,14.2,12.4,[1.1,1.1,0,0]),R(3,9.4,14.2,18,[0,0,2.6,2.6]),Et(6,14.2,1.2,9,3.6)]},move:{hot:[9.5,9.5],parts:[R(3,7.8,16,11.2),R(7.8,3,11.2,16),V([9.5,0],[14,4.6],[5,4.6]),V([9.5,19],[5,14.4],[14,14.4]),V([0,9.5],[4.6,5],[4.6,14]),V([19,9.5],[14.4,14],[14.4,5])]},text:{hot:[9.5,9.5],parts:[R(8,.5,11,18.5),R(4.5,0,14.5,3),R(4.5,16,14.5,19)]},"vertical-text":{hot:[9.5,9.5],parts:Be([R(8,.5,11,18.5),R(4.5,0,14.5,3),R(4.5,16,14.5,19)],90,9.5,9.5)},crosshair:{hot:[9.5,9.5],parts:[R(0,8,19,11),R(8,0,11,19)]},cell:{hot:[9.5,9.5],parts:[R(1.5,6.3,17.5,12.7),R(6.3,1.5,12.7,17.5)]},"not-allowed":{hot:[9.5,9.5],parts:[...Bo(9.5,9.5,5.4,8.8),xn(4.6,4.6,14.4,14.4,3.4)]},help:{hot:[0,0],parts:[...se(Xe(),.8),Pn(13.6,12.4,5.4)],detail:[R(11.6,9,15.4,10.2),R(14.4,9,15.6,12.6),R(12.9,11.6,15.6,12.8),R(12.9,11.6,14.1,13.8),R(12.9,14.8,14.1,16)]},wait:{hot:[9.5,9.5],parts:Xo()},progress:{hot:[0,0],parts:[...se(Xe(),.8),R(10.6,9,18.8,11.6),R(10.6,16.4,18.8,19),V([11.4,10.2],[18,10.2],[14.7,14.4]),V([14.7,13.6],[18,17.8],[11.4,17.8])]},copy:{hot:[0,0],parts:[...se(Xe(),.8),R(9.6,9.8,18.8,19,[1.2,1.2,1.2,1.2])],detail:[R(13.6,11.8,14.8,17),R(11.6,13.8,16.8,15)]},alias:{hot:[0,0],parts:[...se(Xe(),.8),R(9.6,9.8,18.8,19,[1.2,1.2,1.2,1.2])],detail:[xn(11.8,16.8,15.6,13,1.3),V([16.8,11.8],[16.8,15.4],[13.2,11.8])]},"context-menu":{hot:[0,0],parts:[...se(Xe(),.8),R(9.2,8.6,18.8,19)],detail:[R(11,10.8,17,11.8),R(11,13.3,17,14.3),R(11,15.8,17,16.8)]},"ns-resize":{hot:[9.5,9.5],parts:Mt()},"ew-resize":{hot:[9.5,9.5],parts:Be(Mt(),90,9.5,9.5)},"nesw-resize":{hot:[9.5,9.5],parts:se(Be(Mt(),45,9.5,9.5),1.2,-1.9,-1.9)},"nwse-resize":{hot:[9.5,9.5],parts:se(Be(Mt(),-45,9.5,9.5),1.2,-1.9,-1.9)},"col-resize":{hot:[9.5,9.5],parts:Sn()},"row-resize":{hot:[9.5,9.5],parts:Be(Sn(),90,9.5,9.5)},"zoom-in":{hot:[7.5,7.5],parts:Mn(),detail:[R(4.4,6.9,10.6,8.1),R(6.9,4.4,8.1,10.6)]},"zoom-out":{hot:[7.5,7.5],parts:Mn(),detail:[R(4.4,6.9,10.6,8.1)]}}}function Ii(r){let e=we.includes(r)?r:"arrow",t=En.get(e);if(t)return t;let i=c=>Object.freeze(c.map(d=>Object.freeze(d.map(f=>Object.freeze(f))))),n,s,o;if(e==="arrow")n=[ee],s=[Nn],o=[];else{let c=(Go||=qo())[e],d=f=>f.map(h=>h.map(([u,p])=>[(u-c.hot[0])/19,(p-c.hot[1])/19]));n=i(d(c.parts)),s=i(n.map(f=>Tt(1/19,f))),o=i(d(c.detail||[]))}let a=n.flat().map(c=>c[0]),l=n.flat().map(c=>c[1]);return t=Object.freeze({name:e,parts:Object.freeze(n),fill:Object.freeze(s),detail:Object.freeze(o),box:Object.freeze([Math.min(...a),Math.min(...l),Math.max(...a),Math.max(...l)])}),En.set(e,t),t}function Re(r,e=1/19){let t=Ii(r);return Math.abs(e-1/19)<1e-12?{outline:t.parts,fill:t.fill,detail:t.detail}:{outline:t.parts,fill:t.parts.map(i=>Tt(e,i)),detail:t.detail}}function An(r,e,t=0){let i=Ii(r).box,n=(e>0&&Number.isFinite(e)?e:0)+(t>0&&Number.isFinite(t)?t:0);return[i[0]-n,i[1]-n,i[2]+n,i[3]+n]}function Ln(r,e,t,i,n,s=Wi,o=Hi,a=Re(r)){let l=0,c=0,d=0,f=0,h=0,u=i>0?Ge:Ge.slice(0,1),p=a.detail&&a.detail.length?a.detail:null;for(let[m,g,_]of u){let b=e+m*i,S=t+g*i,x=Di(Oi(a.outline,b,S),n),O=x>0?Di(Oi(a.fill,b,S),n):0;p&&O>0&&(O*=1-Di(Oi(p,b,S),n)),l+=_*(o[0]*x+(s[0]-o[0])*O),c+=_*(o[1]*x+(s[1]-o[1])*O),d+=_*(o[2]*x+(s[2]-o[2])*O),f+=_*x,h+=_}return f/=h,f>1e-5?[l/h/f,c/h/f,d/h/f,f]:[0,0,0,0]}function Fi(r,e,t,i,n,s,o=Wi,a=Hi,l=Re(r)){let c=i>0&&Number.isFinite(i)?i:1,d=1/c,[f,h,u,p]=An(r,n,d),m=Math.floor(e+f*c),g=Math.floor(t+h*c),_=Math.max(1,Math.ceil(e+u*c)-m),b=Math.max(1,Math.ceil(t+p*c)-g),S=new Uint8ClampedArray(_*b*4),x=s>=0&&s<=1?s:1;for(let O=0;O<b;O++){let E=(g+O+.5-t)/c;for(let C=0;C<_;C++){let P=Ln(r,(m+C+.5-e)/c,E,n,d,o,a,l);if(!(P[3]>0))continue;let D=(O*_+C)*4;S[D]=Math.round(P[0]*255),S[D+1]=Math.round(P[1]*255),S[D+2]=Math.round(P[2]*255),S[D+3]=Math.round(P[3]*x*255)}}return{x0:m,y0:g,width:_,height:b,data:S}}function Ni(r,e,t,i,n,s=Re(e),o="#fff",a="#000"){for(let[l,c]of[[s.outline,a],[s.fill,o],[s.detail||[],a]]){r.fillStyle=c;for(let d of l)r.beginPath(),d.forEach(([f,h],u)=>(u?r.lineTo:r.moveTo).call(r,t+f*n,i+h*n)),r.closePath(),r.fill()}}function ji(r,e,t,i,n){let s=i>0&&Number.isFinite(i)?Math.ceil(i)+1:0,o=e+2*s,a=t+2*s,l=new Uint8ClampedArray(o*a*4),c=n>=0&&n<=1?n:1,d=s?Ge:Ge.slice(0,1);for(let f=0;f<a;f++)for(let h=0;h<o;h++){let u=0,p=0,m=0,g=0,_=0;for(let[S,x,O]of d){_+=O;let E=Math.round(h-s+S*i),C=Math.round(f-s+x*i);if(E<0||C<0||E>=e||C>=t)continue;let P=(C*e+E)*4,D=r[P+3]/255*O;u+=r[P]*D,p+=r[P+1]*D,m+=r[P+2]*D,g+=D}if(!(g>1e-5))continue;let b=(f*o+h)*4;l[b]=u/g,l[b+1]=p/g,l[b+2]=m/g,l[b+3]=g/_*c*255}return{pad:s,width:o,height:a,data:l}}function kt(r=globalThis.document){if(!r||!r.createElement)return!1;let e="inline3d-cursor-style";if(r.getElementById&&r.getElementById(e))return!0;let t=r.createElement("style");return t.id=e,t.textContent=Rn,(r.head||r.documentElement)?.appendChild(t),!0}function Fn(r,e){let t=globalThis.getComputedStyle;if(!r||typeof t!="function")return null;let i=[];for(let n of e)n&&n.hasAttribute&&n.hasAttribute(B)&&(i.push([n,n.getAttribute(B)]),n.removeAttribute(B));try{let n=t(r).cursor;return typeof n=="string"?n:null}catch{return null}finally{for(let[n,s]of i)n.setAttribute(B,s??"")}}var B,Rn,Cn,kn,$o,St,Vo,Rt,Li,Ee,V,Be,se,Xe,Mt,Sn,Xo,Mn,Go,En,Oi,Di,In,Ct,qe,zi=le(()=>{"use strict";$i();be();B="data-inline3d-cursor-hidden",Rn=`[${B}],[${B}] *{cursor:none!important}`,Cn=128,kn=Object.freeze({auto:"arrow",default:"arrow",none:"none",pointer:"pointer",grab:"grab","-webkit-grab":"grab",grabbing:"grabbing","-webkit-grabbing":"grabbing",move:"move","all-scroll":"move",text:"text","vertical-text":"vertical-text",crosshair:"crosshair","not-allowed":"not-allowed","no-drop":"not-allowed",help:"help",wait:"wait",progress:"progress",copy:"copy",alias:"alias","context-menu":"context-menu",cell:"cell","n-resize":"ns-resize","s-resize":"ns-resize","ns-resize":"ns-resize","e-resize":"ew-resize","w-resize":"ew-resize","ew-resize":"ew-resize","ne-resize":"nesw-resize","sw-resize":"nesw-resize","nesw-resize":"nesw-resize","nw-resize":"nwse-resize","se-resize":"nwse-resize","nwse-resize":"nwse-resize","col-resize":"col-resize","row-resize":"row-resize","zoom-in":"zoom-in","-webkit-zoom-in":"zoom-in","zoom-out":"zoom-out","-webkit-zoom-out":"zoom-out"}),$o=Object.freeze(Object.keys(kn));St=new Map;Vo=r=>/\.cur(?:[?#]|$)/i.test(r)||/^data:image\/(?:x-win-bitmap|x-icon|vnd\.microsoft\.icon)/i.test(r),Rt=class{constructor({ImageCtor:e=globalThis.Image,fetchFn:t=globalThis.fetch}={}){this._Image=e,this._fetch=t,this._m=new Map}get(e){let t=this._m.get(e);if(t)return t;if(t={url:e,state:"loading",image:null,width:0,height:0,curHotspot:null},this._m.set(e,t),typeof this._Image!="function")return t.state="failed",t;let i=new this._Image;i.crossOrigin="anonymous";let n=1,s=()=>{--n>0||t.state==="failed"||(t.state="ready")};return i.onload=()=>{let o=i.naturalWidth||i.width,a=i.naturalHeight||i.height;if(!(o>0&&a>0))return void(t.state="failed");t.image=i,t.width=o,t.height=a,s()},i.onerror=()=>{t.state="failed"},Vo(e)&&typeof this._fetch=="function"&&(n++,Promise.resolve().then(()=>this._fetch(e,e.startsWith("data:")?void 0:{mode:"cors"})).then(o=>o&&o.ok!==!1?o.arrayBuffer():null).then(o=>{t.curHotspot=o?On(o,t.width):null}).catch(()=>{}).finally(s)),i.src=e,t}},Li=new Rt;Ee=r=>{let e=0;for(let t=0;t<r.length;t++){let[i,n]=r[t],[s,o]=r[(t+1)%r.length];e+=i*o-s*n}return e>0?r:r.reverse()};V=(r,e,t)=>Ee([r,e,t]),Be=(r,e,t,i)=>{let n=e*Math.PI/180,s=Math.cos(n),o=Math.sin(n);return r.map(a=>Ee(a.map(([l,c])=>[t+(l-t)*s-(c-i)*o,i+(l-t)*o+(c-i)*s])))},se=(r,e,t=0,i=0)=>r.map(n=>n.map(([s,o])=>[s*e+t,o*e+i])),Xe=()=>[ee.map(([r,e])=>[r*19,e*19])],Mt=()=>[R(8,3,11,16),V([9.5,0],[14.2,5],[4.8,5]),V([9.5,19],[4.8,14],[14.2,14])],Sn=()=>[R(8,1,11,18),R(3.4,8,7.4,11),V([0,9.5],[4.4,5],[4.4,14]),R(11.6,8,15.6,11),V([19,9.5],[14.6,14],[14.6,5])],Xo=()=>[R(3,0,16,3),R(3,16,16,19),V([4.2,.5],[14.8,.5],[9.5,10]),V([9.5,9],[14.8,18.5],[4.2,18.5])],Mn=()=>[Pn(7.5,7.5,7),Et(11.6,11.6,18.4,18.4,3.8,1)];Go=null,En=new Map;Oi=(r,e,t)=>{let i=1/0;for(let n of r)i=Math.min(i,jn(n,e,t));return i},Di=(r,e)=>e>0?Math.min(1,Math.max(0,.5-r/e)):r<0?1:0;In=100;Ct=class{constructor(e,{throttleMs:t=In}={}){this.pointer=e,this.throttleMs=t,this.css=null,this.reads=0,this._el=null,this._stale=!0,this._urgent=!0,this._lastRead=-1/0;let i=n=>s=>{let o=typeof s.composedPath=="function"?s.composedPath():null,a=o&&o.length?o[0]:s.target;a&&a.nodeType===1&&(this._el=a),this._stale=!0,n&&(this._urgent=!0)};this._onMove=i(!1),this._onPress=i(!0),this._target=e.scope==="window"?globalThis:e.canvas,this._target&&this._target.addEventListener&&(this._target.addEventListener("pointermove",this._onMove),this._target.addEventListener("pointerdown",this._onPress),this._target.addEventListener("pointerup",this._onPress),this._target.addEventListener("pointercancel",this._onPress))}value(e=globalThis.performance?globalThis.performance.now():Date.now()){return this._stale&&(this._urgent||this.css===null||e-this._lastRead>=this.throttleMs)&&this.read(e),this.css??"auto"}shape(e){return Tn(this.value(e))}read(e=globalThis.performance?globalThis.performance.now():Date.now()){let t=globalThis.document,i=this.pointer.canvas,n=this._el;n&&n.isConnected===!1&&(n=null);let s=Fn(n||i,[i,t&&t.documentElement]);return this.reads++,this._lastRead=e,this._stale=!1,this._urgent=!1,s!==null&&(this.css=s),this.css??"auto"}dispose(){this._target&&this._target.removeEventListener&&(this._target.removeEventListener("pointermove",this._onMove),this._target.removeEventListener("pointerdown",this._onPress),this._target.removeEventListener("pointerup",this._onPress),this._target.removeEventListener("pointercancel",this._onPress))}},qe=class{constructor(e,{shape:t="auto",shapeFor:i=null,images:n=Li}={}){if(!ye.includes(t))throw new Error(`@displayxr/inline3d: cursor.shape "${t}" \u2014 expected ${ye.join(", ")}.`);this.option=t,this.shapeFor=typeof i=="function"?i:null,this.images=n,this.reader=t==="auto"?new Ct(e):null,this.sprite=Me(t==="auto"?"arrow":t)}get current(){return this.sprite.kind==="shape"?this.sprite.name:this.sprite.kind}pick(e,t){let i=this.reader?this.reader.value(t):null,n=i===null?null:Dn(i,this.images),s=n?n.kind==="shape"?n.name:n.kind:null,o;if(this.shapeFor)try{o=this.shapeFor({...e,css:s,cssValue:i})}catch(l){this._warned||(this._warned=!0,console.warn("[inline3d] cursor.shapeFor threw; using the page cursor.",l))}let a=l=>l==="none"||we.includes(l);return a(o)?this.sprite=Me(o):a(this.option)?this.sprite=Me(this.option):this.sprite=n||Me("arrow"),this.sprite}dispose(){this.reader?.dispose()}}});function $n(r){return r>0&&Number.isFinite(r)?Math.min(.5,Bi/r):Yo}function Un(r,e){return r<=Ko?!(e>0&&Number.isFinite(e))||-r*e>=Jo:!1}function Xi(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 Vn(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 zn(r){let e=r&&r.pointerType;return!e||e==="mouse"?!0:e==="pen"?!(r.buttons>0):!1}function Zo(r){return!!r&&"onpointerrawupdate"in r&&globalThis.isSecureContext!==!1}function Qo(r){let e=globalThis.document;if(!e||!e.documentElement)return;r&&kt(e),Ui=Math.max(0,Ui+(r?1:-1));let t=e.documentElement;Ui>0?t.setAttribute?.(B,""):t.removeAttribute?.(B)}function Wn(r){return!!r&&typeof r.setCursorDepth=="function"&&typeof r.getCursorDepthSupport=="function"}function ra(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 Bn(r,e,t,i){return[[r,e],...ra(r+.3*t/i,e+.5*t,t,i)]}function Tt(r,e=ee){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],d=Math.hypot(l,c)||1;return[-c/d*i,l/d*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]})}function Xn(r,e,t,i=ve){let n={blurPx:0,alpha:1},s=i;if(!s)return n;if(s.blur&&Number.isFinite(e)&&s.blurK>0&&s.blurMaxPx>0){let o=s.blurMaxPx;if(s.blurMaxFrac>0&&Number.isFinite(t)&&t>0){let l=s.blurMaxFrac*t;o=l<o?l:o}let a=s.blurK*Math.abs(e);n.blurPx=a<o?a:o}if(s.alpha&&Number.isFinite(r)&&s.fullD>0){let o=Math.abs(r)/s.fullD;o=o<1?o:1;let a=o*o*(3-2*o),l=s.alphaMin<0?0:s.alphaMin>1?1:s.alphaMin;n.alpha=1-(1-l)*a}return n}function jn(r,e,t){let i=(e-r[0][0])**2+(t-r[0][1])**2,n=1;for(let s=0,o=r.length-1;s<r.length;o=s,s++){let a=r[s],l=r[o],c=l[0]-a[0],d=l[1]-a[1],f=e-a[0],h=t-a[1],u=Math.min(1,Math.max(0,(f*c+h*d)/(c*c+d*d))),p=f-c*u,m=h-d*u;i=Math.min(i,p*p+m*m);let g=t>=a[1],_=t<l[1],b=c*h>d*f;(g&&_&&b||!g&&!_&&!b)&&(n=-n)}return n*Math.sqrt(i)}var Yo,Bi,Ko,Jo,Pt,Ot,Ui,ea,ta,ia,Vi,Dt,Hn,ee,Tl,Nn,Wi,Hi,Ge,Ol,Dl,Pl,$i=le(()=>{"use strict";be();be();zi();zi();Yo=.03,Bi=19;Ko=-.005,Jo=.5;Pt=Object.freeze({margin:.015,minDisparity:-.6,maxDisparity:0,riseTau:.03,sinkTau:.25,stale:.5});Ot=class{constructor(e,{scope:t="canvas",keepCss:i=!1}={}){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.keepCss=!!i,this._uv=null,this.sampleTime=0,this.samples=0,this._hidden=!1,this._cx=0,this._cy=0,this._pending=!1,this._onMove=n=>this._sample(n),this._onLeave=()=>{this.uv=null},this._onDown=n=>{zn(n)||(this.uv=null)},this._target=t==="window"?globalThis:e,this.source=Zo(this._target)?"pointerrawupdate":"pointermove",this._target.addEventListener("pointermove",this._onMove),this.source==="pointerrawupdate"&&this._target.addEventListener("pointerrawupdate",this._onMove),this._target.addEventListener("pointerdown",this._onDown),t==="window"?(this._onOut=n=>{n.relatedTarget||(this.uv=null)},globalThis.addEventListener("pointerout",this._onOut),globalThis.addEventListener("blur",this._onLeave)):e.addEventListener("pointerleave",this._onLeave)}get uv(){if(this._pending){this._pending=!1;let e=this.canvas.getBoundingClientRect();if(!(e.width>0&&e.height>0))this._uv=null;else{let t=(this._cx-e.left)/e.width,i=(this._cy-e.top)/e.height;this._uv=t>=0&&t<=1&&i>=0&&i<=1?[t,i]:null}}return this._uv}set uv(e){this._pending=!1,this._uv=e}_sample(e){if(!zn(e)){this.uv=null;return}let t=typeof e.getCoalescedEvents=="function"?e.getCoalescedEvents():null,i=t&&t.length?t[t.length-1]:e,n=i.timeStamp>0?i.timeStamp:e.timeStamp>0?e.timeStamp:globalThis.performance?globalThis.performance.now():Date.now();n<this.sampleTime||(this.samples++,this.sampleTime=n,this._cx=i.clientX,this._cy=i.clientY,this._pending=!0)}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)}panelSize(){let e=this.canvas.getBoundingClientRect(),t=globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1;return e.width>0&&e.height>0?[e.width*t,e.height*t]:[0,0]}hideCss(e){this.keepCss&&(e=!1),e!==this._hidden&&(this.scope==="window"?Qo(e):this.canvas.setAttribute&&(e?(kt(),this.canvas.setAttribute(B,"")):this.canvas.removeAttribute(B)),this._hidden=e)}dispose(){this._target.removeEventListener("pointermove",this._onMove),this.source==="pointerrawupdate"&&this._target.removeEventListener("pointerrawupdate",this._onMove),this._target.removeEventListener("pointerdown",this._onDown),this.scope==="window"?(globalThis.removeEventListener("pointerout",this._onOut),globalThis.removeEventListener("blur",this._onLeave)):this.canvas.removeEventListener("pointerleave",this._onLeave),this.hideCss(!1)}};Ui=0;ea=2e3,ta=6,ia=1e4;Vi=new WeakMap,Dt=class{constructor(){this.target=null,this._sent=!1,this.last=null}get support(){let e=this.target;if(!Wn(e))return"none";let t=Vi.get(e);return t?t.state:"pending"}get drawing(){return this.support==="runtime"}bind(e){let t=e||null;if(t!==this.target&&(this.withdraw(),this.target=t),!Wn(t))return!1;let i=Vi.get(t);if(i||Vi.set(t,i={state:"pending",probes:0,inFlight:!1,at:0}),i.state==="runtime"||i.inFlight)return i.state==="runtime";let n=globalThis.performance?globalThis.performance.now():Date.now(),s=i.probes<ta?ea:ia;if(i.probes===0||n-i.at>=s){i.probes++,i.at=n,i.inFlight=!0;let o;try{o=Promise.resolve(t.getCursorDepthSupport())}catch(a){o=Promise.reject(a)}o.then(a=>{i.inFlight=!1,i.state=a==="runtime"?"runtime":"none"},()=>{i.inFlight=!1,i.state="none"})}return i.state==="runtime"}report(e,t,i){if(!this.drawing)return!1;let n={u:Hn(e),v:Hn(t)};i!=null&&Number.isFinite(i)&&(n.disparityPx=i);try{this.target.setCursorDepth(n)}catch{return!1}return this._sent=!0,this.last={u:n.u,v:n.v,disparityPx:n.disparityPx??null},!0}withdraw(){if(this.last=null,!!this._sent){this._sent=!1;try{this.target?.setCursorDepth()}catch{}}}dispose(){this.withdraw(),this.target=null}},Hn=r=>r>0?r<1?r:1:0;ee=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]))),Tl=Object.freeze([[0,1,2],[0,2,5],[0,5,6],[2,3,4],[2,4,5]]);Nn=Object.freeze(Tt(1/19).map(r=>Object.freeze(r))),Wi=Object.freeze([1,1,1,1]),Hi=Object.freeze([.02,.02,.03,1]);Ge=Object.freeze([Object.freeze([0,0,1]),...[[.5,0],[-.5,0],[0,.5],[0,-.5]].map(([r,e])=>Object.freeze([r,e,.7066])),...Array.from({length:8},(r,e)=>{let t=.3927+.7854*e;return Object.freeze([Math.cos(t),Math.sin(t),.2494])})]),Ol=Object.freeze([Math.max(...ee.map(r=>r[0])),Math.max(...ee.map(r=>r[1]))]);Dl=Object.freeze({declarations:`#ifdef PICK_PASS
3
3
  #include "pickPS"
4
4
  #endif
@@ -16,7 +16,7 @@ output.color1 = getPickDepth();
16
16
  `})});var Yi={};Ps(Yi,{PAIR_CURSOR_ARROW:()=>sa,PAIR_CURSOR_CSS_PX:()=>na,PAIR_CURSOR_CSS_PX_M:()=>Kn,PAIR_CURSOR_HEIGHT:()=>Yn,PAIR_SUPPORT_COPY_PX:()=>Zn,PairCursor:()=>Gi,consistentMatch:()=>qi,drawPairArrow:()=>rs,drawPairArrowSoft:()=>ss,drawPairImage:()=>os,pairCursorScale:()=>es,pairCursorTarget:()=>aa,pairFootprintDisparity:()=>Jn,pairNearestSupported:()=>Qn,pairPxPerBaseline:()=>ts});function Jn(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,d=a/2,f=Math.max(8,Math.round(d/20)),h=Math.round(d*.3),u=-Math.round(d*.05),{rL:p,rR:m}=e,g=e.outW/p.sw,_=oa(r),b=[],S=new Set,x=(k,v)=>{let w=Math.round((p.sy+v*p.sh)*c-f/2);if(w<0||w+f>l)return;let y=Math.round((p.sx+k*p.sw)*c-f/2),M=Math.round((m.sx+k*m.sw)*c-f/2);if(!S.has(`L${y},${w}`)){S.add(`L${y},${w}`);let I=qi(o,_,a,l,y,w,f,u,h);I!==null&&b.push({d:I,x:y,y:w,eye:0})}if(!S.has(`R${M},${w}`)){S.add(`R${M},${w}`);let I=qi(_,o,a,l,M,w,f,-h,-u);I!==null&&b.push({d:-I,x:M,y:w,eye:1})}},O=0,E=0,C=0;for(let[k,v]of Bn(t,i,n,s))k>=0&&k<=1&&v>=0&&v<=1&&(x(e.mirror?1-k:k,v),O+=k,E+=v,C++);if(!C)return null;let P=f/2/c/p.sw,D=f/2/c/p.sh;for(let[k,v]of[[-P,0],[P,0],[0,-D],[0,D]]){let w=O/C+k,y=E/C+v;w>=0&&w<=1&&y>=0&&y<=1&&x(e.mirror?1-w:w,y)}for(let k of b)k.d=(k.d/c-(p.sx-m.sx))*g;return Qn(b,Zn/c*g,f/2)}function oa(r){let e=Gn.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 Gn.set(r,e),e}function qi(r,e,t,i,n,s,o,a,l){let c=t/2;if(n<0||n+o>c)return null;let d=_e(r,t,i,n,s,o,o,{dMin:a,dMax:l,dyMax:2});if(!d||d.c<.8)return null;let f=Math.round(n-d.d),h=s+d.dy;if(f<0||f+o>c||h<0||h+o>i)return null;let u=_e(e,t,i,f,h,o,o,{dMin:-Math.ceil(d.d)-2,dMax:-Math.floor(d.d)+2,dyMax:1});return!u||u.c<.8||Math.abs(-u.d-d.d)>1?null:d.d}function Qn(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 es(r,e,t){let i=t>0&&Number.isFinite(t)?t:Kn;return e>0?r/e/i:r/(1e3*i)}function ts(r,e,t,i=Je.eyeSeparationM){return es(r,e,t)*i}function aa(r,e,t=Pt){return r===null||!Number.isFinite(r)||!(e>0)?0:-Xi(t,!0,-r/e)*e||0}function is(r,e){let t=e>0?Math.max(.05263157894736842,1/e):.05263157894736842,i=`${r}:${Math.round(t*1e4)}`,n=At.get(i);return n||(At.size>64&&At.clear(),At.set(i,n=Re(r,t))),n}function rs(r,e,t,i,n,s,o,a="arrow"){let l=n*t,c=is(a,o);for(let d of[0,1]){let f=d*e+i*e+(d===0?s/2:-s/2);r.save(),r.beginPath(),r.rect(d*e,0,e,t),r.clip(),Ni(r,a,f,l,o,c),r.restore()}}function ns(r,e){if(!X||typeof OffscreenCanvas=="function"&&!(X instanceof OffscreenCanvas))try{typeof OffscreenCanvas=="function"?X=new OffscreenCanvas(1,1):globalThis.document&&document.createElement&&(X=document.createElement("canvas"))}catch{X=null}return!X||typeof X.getContext!="function"?null:(X.width<r&&(X.width=r),X.height<e&&(X.height=e),X.getContext("2d"))}function ss(r,e,t,i,n,s,o,a,l,c="arrow"){let d=n*t,f=is(c,o),h=[0,1].map(p=>{let m=p*e+i*e+(p===0?s/2:-s/2);return Fi(c,m,d,o,a,l,[1,1,1,1],[0,0,0,1],f)}),u=ns(Math.max(h[0].width,h[1].width),Math.max(h[0].height,h[1].height));if(!u||typeof u.putImageData!="function"||typeof ImageData!="function")return!1;for(let p of[0,1]){let m=h[p];u.putImageData(new ImageData(m.data,m.width,m.height),0,0),r.save(),r.beginPath(),r.rect(p*e,0,e,t),r.clip(),r.drawImage(u.canvas,0,0,m.width,m.height,m.x0,m.y0,m.width,m.height),r.restore()}return!0}function os(r,e,t,i,n,s,o,a,l,c){let d=o/19,f=Math.max(1,Math.round(a.width*d)),h=Math.max(1,Math.round(a.height*d)),u=ns(f+2*(Math.ceil(l)+2),h+2*(Math.ceil(l)+2));if(!u||typeof u.getImageData!="function"||typeof ImageData!="function")return!1;u.clearRect(0,0,u.canvas.width,u.canvas.height),u.drawImage(a.entry.image,0,0,f,h);let p=ji(u.getImageData(0,0,f,h).data,f,h,l,c);u.clearRect(0,0,u.canvas.width,u.canvas.height),u.putImageData(new ImageData(p.data,p.width,p.height),0,0);let m=n*t-a.hotspot[1]*d-p.pad;for(let g of[0,1]){let _=g*e+i*e+(g===0?s/2:-s/2)-a.hotspot[0]*d-p.pad;r.save(),r.beginPath(),r.rect(g*e,0,e,t),r.clip(),r.drawImage(u.canvas,0,0,p.width,p.height,Math.round(_),Math.round(m),p.width,p.height),r.restore()}return!0}var na,Yn,sa,Kn,Zn,Gn,At,X,Gi,Ki=le(()=>{"use strict";$i();Bt();Mi();na=Bi,Yn=.06,sa=ee,Kn=.0254/96;Zn=1.5,Gn=new WeakMap;At=new Map;X=null;Gi=class{constructor(e,{height:t,pointerScope:i="window",soften:n,shape:s="auto",shapeFor:o=null}={}){this.pointer=new Ot(e,{scope:i}),this.shapes=new qe(this.pointer,{shape:s,shapeFor:o}),this.soften=vt(n,"@displayxr/inline3d pair cursor"),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=Je.eyeSeparationM,this.last=null,this.runtime=new Dt}get hovering(){return!!this.pointer.uv}draw(e,t,i,n){let s=this.runtime.bind(i&&i.handle),o=this.pointer.uv;if(!o)return this.idle();let[a,l]=o,c=this.height??this._osArrowFraction();(t!==this._luma||!this._uv||this._uv[0]!==a||this._uv[1]!==l)&&(this._content=Jn(t,i,a,l,c,i.outW/i.outH),this._luma=t,this._uv=o);let d=this.pointer.canvas.getBoundingClientRect?.();if(s)return this._drawRuntime(a,l,d,i);this._askMetrics(i.handle);let f=ts(i.outW,d&&d.width,this.metersPerCssPx,this.eyeSeparationM),h=this._content===null?null:-this._content/f,u=Xi(Pt,h!==null,h),p=Vn(this.filter,Pt,u,n),m=Un(p,f),g=-p*f,_=null,b=null;if(m){let S=c*i.outH,x=globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1,O=d&&d.width>0?d.width*x/i.outW:1,E=d&&d.height>0?c*d.height*x:S,C=Xn(p,g*O,E,this.soften),P=this.shapes.pick({u:a,v:l,point:null},n*1e3);b=this.shapes.current,_={blurPx:C.blurPx,alpha:C.alpha,ghostPx:Math.abs(g*O),spritePx:E,radius:E>0?C.blurPx/E:0,soft:C.blurPx>0||C.alpha<1},P.kind==="image"?os(e,i.outW,i.outH,a,l,g,S,P,_.soft?_.radius*S:0,_.soft?C.alpha:1):P.kind==="shape"&&(!_.soft||!ss(e,i.outW,i.outH,a,l,g,S,_.radius,C.alpha,b))&&rs(e,i.outW,i.outH,a,l,g,S,b)}return this.pointer.hideCss(m),this.last={contentPx:this._content,targetPx:-u*f||0,disparityPx:m?g:0,filteredPx:g||0,drawn:m,pxPerBaseline:f,soften:_,shape:b},this.last}_drawRuntime(e,t,i,n){this.pointer.hideCss(!1),this.filter={};let s=globalThis.devicePixelRatio>0?globalThis.devicePixelRatio:1,o=i&&i.width>0&&n.outW>0?i.width*s/n.outW:null,a=this._content===null||o===null?null:-this._content*o;return this.runtime.report(e,t,a),this.last={contentPx:this._content,targetPx:0,disparityPx:0,filteredPx:0,drawn:!1,runtime:!0,runtimeDisparityPx:a,pxPerBaseline:null,soften:null,shape:null},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?$n(e.height):Yn}idle(){return this.runtime.withdraw(),this.pointer.hideCss(!1),this.filter={},this._uv=null,this.last=null,null}dispose(){this.runtime.dispose(),this.pointer.dispose(),this.shapes.dispose()}}});var Pe=Object.freeze({speaker:"high",other:"normal",hidden:"paused"}),As=["high","normal","low","paused"],Ls=.02,Is=1e3/20,Fs=3e3,Ns=1e3/28;function Le(r){return typeof r=="function"?r:r===!1||r==="off"?"off":"auto"}function Wt(r=import.meta.url){return De?typeof De=="function"?De():De:new URL("../lift/index.js",r).href}var De=null;function mr(r){De=r||null}function js(){return import(Wt())}async function Ht(r,{importer:e=js,nav:t=globalThis.navigator,log:i=null,capsOpts:n={webFallback:!0}}={}){let s=(h,u)=>i&&i(h,u),o=(h,u={})=>(s("lift-unavailable",{reason:h,...u}),{lift:null,capabilities:null,caps:null,source:"none",reason:h}),a=Le(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 d=typeof l.liftCapabilities=="function"?l.liftCapabilities:null,f=null;if(d){try{f=await d(n)}catch{f=null}let h=!!(f&&f.webFallback&&f.webFallback.webgpu);if(f&&!f.native&&!h)return o("no-provider",{native:!1,webgpu:!1})}else if(!(t&&t.gpu))return o("no-webgpu");return s("lift-ready",{native:!!(f&&f.native),provider:f&&f.provider||null}),{lift:c,capabilities:d,caps:f,source:"module",reason:null}}function Ae(r){let e=Number.isFinite(+r)&&r!==null?Math.max(-1,Math.min(1,+r)):0;return Math.abs(e)<Ls?"auto":Math.round((.5+.5*e)*1e3)/1e3}function Ke({id:r,speakerId:e,visible:t=!0}){return t?r!=null&&r===e?Pe.speaker:Pe.other:Pe.hidden}function $t(r,e){if(!r||!As.includes(e)||typeof r.setPriority!="function")return!1;try{return r.setPriority(e)!==!1}catch{return!1}}function Ut({degradedMs:r=Is,recoveredMs:e=Ns,holdMs:t=Fs,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 Vt({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,u)=>t&&t(h,u),d=(h,u)=>{if(!u.handle)return;let p=Ke({id:h,speakerId:o,visible:u.visible});if(p===u.priority)return;u.priority=p;let m=$t(u.handle,p);c("lift-priority",{peer:h,priority:p,applied:m})},f={get size(){return s.size},get max(){return e},set max(h){e=Math.max(0,h|0)},has:h=>s.has(h),handle:h=>s.get(h)&&s.get(h).handle||null,priority:h=>s.get(h)&&s.get(h).priority||null,canAcquire:h=>s.has(h)||s.size<e,acquire(h,u,{wall:p,visible:m=!0,onError:g}={}){let _=s.get(h);if(_)return _.pending||Promise.resolve(_.handle);if(s.size>=e)return Promise.resolve(null);let b=++l,S=Ke({id:h,speakerId:o,visible:m}),x={gen:b,handle:null,visible:m,priority:S,pending:null};s.set(h,x);let O={quality:"auto",...n,mode:"live",wall:p,ui:"none",convergence:Ae(a),priority:S};return c("lift-acquire",{peer:h,priority:S,convergence:O.convergence}),x.pending=Promise.resolve().then(()=>r(u,O)).then(E=>{if(s.get(h)!==x||x.gen!==b){try{E&&E.remove&&E.remove()}catch{}return null}return x.pending=null,x.handle=E||null,x.priority=null,d(h,x),E&&typeof E.setConvergence=="function"&&E.setConvergence(Ae(a)),x.handle},E=>(s.get(h)===x&&s.delete(h),c("lift-failed",{peer:h,message:String(E&&E.message||E).slice(0,200)}),g&&g(E),null)),x.pending},release(h){let u=s.get(h);if(u){if(s.delete(h),u.handle)try{u.handle.remove()}catch{}c("lift-release",{peer:h})}},releaseAll(){for(let h of[...s.keys()])f.release(h)},setSpeaker(h){o=h===void 0?null:h;for(let[u,p]of s)d(u,p)},setVisible(h,u){let p=s.get(h);!p||p.visible===!!u||(p.visible=!!u,d(h,p))},setDepth(h){a=h;let u=Ae(h);for(let p of s.values())p.handle&&typeof p.handle.setConvergence=="function"&&p.handle.setConvergence(u);return u},get anyWeb(){for(let h of s.values())if(h.handle&&!h.handle.native)return!0;return!1},list(){return[...s].map(([h,u])=>({id:h,priority:u.priority,pending:!!u.pending,native:!!(u.handle&&u.handle.native)}))}};return f}var Ws=null;function gr(r){Ws=typeof r=="function"?r:null}var Hs=new WeakMap;function _r(r,e){r&&(typeof r=="object"||typeof r=="function")&&Hs.set(r,e)}Bt();var Ua=Object.freeze(["shibata","percival"]);var $s="[inline3d] camera rig with convergenceDiopters 0: convergence at infinity puts the whole scene in front of the glass; set convergence to the subject's distance.",Us=new WeakSet;function Vs(r){let e=[];return!r||typeof r!="object"||(r.type==="camera"?(r.convergenceDiopters>0||e.push(["convergence",$s]),r.verticalFov>Math.PI&&e.push(["fov",`[inline3d] camera rig verticalFov ${r.verticalFov} is more than \u03C0: it looks like DEGREES \u2014 the descriptor takes RADIANS (cameraRigFromCamera / cameraRigFromPose convert three's degrees for you).`])):(r.ipdFactor>1||r.parallaxFactor>1)&&e.push(["factor",`[inline3d] display rig ipdFactor ${r.ipdFactor??1} / parallaxFactor ${r.parallaxFactor??1}: above 1 exaggerates depth past what the display shows by construction (1 = correct; below 1 = a comfort dial). Sent as given.`])),e}function Xt(r,e){if(!(!e||typeof e!="object")&&!(e.type==="camera"?e.convergenceDiopters>0&&!(e.verticalFov>Math.PI):!(e.ipdFactor>1||e.parallaxFactor>1)))for(let[t,i]of Vs(e))r.has(t)||(r.add(t),!(t==="convergence"&&Us.has(e))&&console.warn(i))}function yr(r){let e=String(r||"");return e.startsWith("cross-pass")?"the canvas is inside its own render surface: a CSS effect on it or an ancestor (filter, opacity < 1, mask, clip-path, mix-blend-mode, backdrop-filter). Remove it (woven-canvas rule 7)":e==="no-quad"?"the canvas drew nothing the compositor can see: it is not drawing, is occluded, or a CSS effect on it or an ancestor (filter, opacity < 1, mask, clip-path, mix-blend-mode, backdrop-filter) hides it (woven-canvas rule 7)":e==="no-identity"?"the canvas reached the browser without its identity: register it once, keep it mounted, cover it until firstWoven (woven-canvas rules 3-5)":e==="no-join"?"nothing joined this rect; harmless off screen, otherwise check the canvas is drawing and on screen":e==="resolve-dropped"?"the browser could not resolve the canvas's GPU resource (a browser-side issue)":"see docs/woven-canvas-rules.md \xA73"}var wr=new WeakMap,Q;function br(r){let e=null;for(let[t,i]of r)i>0&&(!e||i<e[1])&&(e=[t,i]);return e}function Bs(r){if(!r||typeof r.getParameter!="function")return null;let e=wr.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=br([["MAX_TEXTURE_SIZE",t],["MAX_RENDERBUFFER_SIZE",i],["MAX_VIEWPORT_DIMS",s]]),l=br([["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 wr.set(r,c),c}function xr(){if(Q!==void 0)return Q;Q=null;try{if(typeof document>"u"||!document||typeof document.createElement!="function")return Q;let r=document.createElement("canvas"),e=r.getContext("webgl2")||r.getContext("webgl");if(!e)return Q;Q=Bs(e),e.getExtension?.("WEBGL_lose_context")?.loseContext?.()}catch{Q=null}return Q}function Sr(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,d=Math.min(l,c);if(!(d<1))return a;let f=l<=c,h=Math.max(1,Math.min(Math.floor(r*d+1e-9),Math.floor(t.maxW/i))),u=Math.max(1,Math.min(Math.floor(e*d+1e-9),Math.floor(t.maxH/n)));return{eyeW:h,eyeH:u,cols:i,scale:d,clamped:!0,reqW:s,reqH:o,bufW:h*i,bufH:u*n,limitName:f?t.nameW:t.nameH,limitValue:f?t.valueW:t.valueH}}function qt(r){return Math.round(r*1e3)/1e3}function Mr(r,e,t){let i=typeof t=="number"?` (renderScale ${qt(t)} \u2192 ${qt(t*e.scale)})`:` (scale ${qt(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 Er(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 Rr(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 he="smoothstep",Yt=["linear","smoothstep","easeoutcubic"];function Kt(r){if(typeof r!="string")return null;let e=r.toLowerCase().replace(/[-_\s]/g,"");return Yt.includes(e)?e:null}function Xs(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 ce="idle",Cr="rampDownThenFire",Gt="fireThenRampUp",Ze=class{constructor(e,t){this._phase=ce,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=he,(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=Kt(t)||he),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,d=Number.isFinite(s)?s:c;return this._targetMode=e,this._from=d,a&&!l?(this._phase=Cr,this._to=0,this._fireAtEnd=!0,this._firePending=!1):!a&&l?(this._phase=Gt,this._from=0,this._to=c,this._firePending=!0,this._fireAtEnd=!1):(this._phase=Gt,this._to=a?d: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!==ce){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)*Xs(this._easing,this._t),this._phase===Gt?(this._firePending&&(this._firePending=!1,t=!0),this._t>=1&&(this._phase=ce)):this._t>=1&&(this._fireAtEnd&&(this._fireAtEnd=!1,t=!0),this._phase=ce)}return{factor:this._cur,fire:t,mode:this._targetMode}}active(){return this._phase!==ce}value(){return this._cur}firePending(){return this._phase===Cr?this._fireAtEnd:this._firePending}cancel(){return this._phase=ce,this._firePending=!1,this._fireAtEnd=!1,this._t=1,this}};var Y=null;gr(r=>{let e=Y;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 qs=()=>typeof navigator<"u"&&!!navigator.xr,ne=()=>typeof window<"u"&&typeof window.XRDisplayLayer=="function",Qe=()=>ne()&&"excludeElement"in window.XRDisplayLayer.prototype,Jt=()=>{if(!ne())return!1;try{return"setViewRig"in window.XRDisplayLayer.prototype}catch{return!1}},Gs=["getDisplayInfo","getRenderingModes","requestRenderingMode"],jr=["renderingmodechange","hardwaredisplaystatechange"],oi="trackingstatechange",zr=["unknown","tracking","searching"],Tr=[...jr,oi];function et(r){try{let e=r?r.trackingState:void 0;return zr.includes(e)?e:null}catch{return null}}var Zt=()=>{if(!ne())return!1;try{let r=window.XRDisplayLayer.prototype;return Gs.every(e=>typeof r[e]=="function")}catch{return!1}},Qt=()=>{if(!ne())return!1;try{return typeof window.XRDisplayLayer.prototype.undock=="function"}catch{return!1}},de=null;function ue(){if(de!==null)return de;if(!ne())return!1;try{let r=window.XRDisplayLayer.occlusionByDrawOrder;if(typeof r=="boolean")return de=r}catch{}return!1}function Ys(r){if(de!==null)return de;if(!r||!ne()||!("occlusionByDrawOrder"in window.XRDisplayLayer.prototype))return null;try{return de=!!r.occlusionByDrawOrder}catch{return null}}var Or=!1;function ei(){Or||(Or=!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 Wr(){return qs()&&ne()}function ti(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 Ks(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 Js=16;function W(){return typeof performance<"u"&&performance&&typeof performance.now=="function"?performance.now():Date.now()}var ai=1200,Zs=new Set(["pending","woven","withheld"]),Dr=3,Qs=new Set(["getDisplayInfo","getRenderingModes","requestRenderingMode"]),eo=new Set(["getDisplayInfo","getRenderingModes"]);function to(r){return r==null||Array.isArray(r)&&r.length===0}function ii(){try{let r=typeof XRDisplayLayer=="function"?XRDisplayLayer:null;return!!(r&&r.prototype&&"wovenState"in r.prototype)}catch{return!1}}function tt(r){try{let e=r?r.wovenState:null;return Zs.has(e)?e:null}catch{return null}}function ri(r){try{let e=r?r.withheldReason:null;return typeof e=="string"&&e?e:null}catch{return null}}var Pr=!1;function io(r){if(r==null)return he;let e=Kt(r);return e||(Pr||(Pr=!0,console.warn(`[inline3d] createInline3D({ modeSwitch: { easing: ${JSON.stringify(r)} } }) is not a curve this SDK knows (${Yt.join(" / ")}); using '${he}'.`)),he)}var Ar=!1;function ro(){Ar||(Ar=!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 li(r){return r&&r.detail!==void 0&&r.detail!==null?r.detail:void 0}function Hr(r){let e=li(r);return e!==void 0?[e,r]:[r]}function no(r){for(let e of Hr(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 so(r){for(let e of Hr(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 Lr=!1;function oo(){Lr||(Lr=!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 Ir=!1;function ao(){Ir||(Ir=!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 $r(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(!Wr())return{supported:!1,trackingState:"unknown"};let l;try{l=await navigator.xr.requestSession("inline-3d")}catch(d){return{supported:!1,trackingState:"unknown",error:d}}a!==void 0&&_r(l,a);let c=null;try{c=await l.requestReferenceSpace(e)}catch{}return new ci(l,c,{lazy:t,rootMargin:i,autoChrome:n,modeSwitch:s,untrackedFallback:o})}var Ie=null;function rt(r={}){return Y&&Y._running?Promise.resolve(Y):Ie||(Ie=$r(r).finally(()=>{Ie=null}),Ie)}var Fr=.7,lo=new Set(["IMG","SVG","VIDEO","CANVAS","BUTTON","INPUT","SELECT","TEXTAREA"]);function co(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(lo.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 ni=4;function si(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 Nr(r){let e=typeof window<"u"&&window.devicePixelRatio||1;return{width:r.clientWidth||0,height:r.clientHeight||0,dpr:e}}function ho(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 ci=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 Ze((Number.isFinite(l.durationMs)?Math.max(0,l.durationMs):180)/1e3,io(l.easing)),this._stereoFactor=1,this._msFire=null,this._msArmedUp=!1,this._msLastMs=null,this._msTick=null,this._trackingSupported=et(e)!==null,this._trackingState=this._trackingSupported?et(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=Qt()?{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,Y&&Y._running&&Y!==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."),Y=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))){ue()&&ei(),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(ue()||!this._autoChrome||!Qe()||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 co(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=fo(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&&ao();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&&(ue()&&ei(),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,n&&Xt(t.rigWarned,n),this._pushViewRig(t)),setCursorDepth:n=>{let s=t.layer;if(!s||typeof s.setCursorDepth!="function")return!1;try{return n?s.setCursorDepth(n):s.setCursorDepth(),!0}catch{return!1}},getCursorDepthSupport:()=>{let n=t.layer;if(!n||typeof n.getCursorDepthSupport!="function")return Promise.resolve("none");try{return Promise.resolve(n.getCursorDepthSupport()).then(s=>s==="runtime"?"runtime":"none",()=>"none")}catch{return Promise.resolve("none")}},getDisplayInfo:()=>this._layerCall(t,"getDisplayInfo","getDisplayInfo()"),displayMetrics:async()=>{let n=null;try{n=await this._layerCall(t,"getDisplayInfo","getDisplayInfo()")}catch{}return vr(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 ii()?t.layer?tt(t.layer):"pending":null},get withheldReason(){return!ii()||!t.layer?null:tt(t.layer)==="withheld"?ri(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?ti(e):null):(e.viewRig||(e.stereoSynthRig=!0),Ks(e.viewRig||ti(e),this._stereoFactor))}_setStereoCollapsed(e){let t=!!e;if(this._stereoCollapsed!==t){this._stereoCollapsed=t,t&&ro(),!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||ti(i);i.stereoSaved={ipdFactor:n.ipdFactor,parallaxFactor:n.parallaxFactor}}else i.stereoSaved=null;this._pushViewRig(i)}}}_pushViewRig(e){if(!Jt())return oo(),!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(!Zt())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(Qs.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(!eo.has(t)||!this._layerReadPending(e))return o;let a=e.layer;return o.then(l=>e.layer!==a?l:to(l)?this._layerReadPending(e)?this._whenLayerFramed(e).then(()=>this._layerCall(e,t,i,n)):l:(e.lfAnswered=!0,l))}_layerFramedCap(e){return ni*Math.max(e.fwHoldMs,ai)}_layerReadPending(e){return!e.layer||e.lfAnswered||e.lfCapped?!1:W()-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)-(W()-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?tt(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||!Jt())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=W(),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=W(),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=W(),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())},Js))}_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"||Zt()&&(e.addEventListener("renderingmodechange",t=>{this._onRenderingModeChange(t).catch(()=>{})}),e.addEventListener("hardwaredisplaystatechange",t=>{this._onHardwareDisplayStateChange(t).catch(()=>{})}))}_onHardwareDisplayStateChange(e){let t=so(e),i=li(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=li(e),i=no(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(!Tr.includes(e))throw new TypeError(`[inline3d] on() knows ${Tr.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=jr.map(i=>this.on(i,e));return()=>{for(let i of t)i()}}async refreshUndock(){if(!Qt())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,rigWarned:new Set,warnedWithheld:!1,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:uo(i.firstWovenHoldMs),fwRegAt:W(),fwLayerAt:null,fwStereo:!1,rw:null,rwGone:null,wsLive:!1,rc:null,layerFramed:!1,lfAnswered:!1,lfStereo:!1,lfAt:0,lfCapped:!1,framedWaiters:[]},s=ho(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}),n.viewRig&&Xt(n.rigWarned,n.viewRig),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=Jt()?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=W(),e.fwStereo=!1),e.wsLive=ii(),e.layerFramed=!1,e.lfAnswered=!1,e.lfStereo=!1,e.lfCapped=!1,e.lfAt=W(),this._restartRewoven(e),e.layerLostSent=!1,!this._primedDisplayState&&Zt()&&(this._primedDisplayState=!0,this._getRenderingModes(e).catch(()=>{this._primedDisplayState=!1})),Qt()&&this.undock&&!this._undockRead&&(this._undockRead=!0,this.refreshUndock().catch(()=>{})),Ys(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<Fr||c/o<Fr?!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(ue()||!e.layer||!Qe()||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(ue())return;let i=this._isolatedBy.get(t);if(i&&i.delete(e),(!i||i.size===0)&&this._unpromote(t),!(!e.layer||!Qe()))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&&ei()}_startOverlayScan(e){if(ue()||!Qe()||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=Sr(n,s,xr(),{cols:t?2:1});return l.clamped&&(o*=l.scale,n=l.eyeW,s=l.eyeH,e.warnedBufClamp||(e.warnedBufClamp=!0,console.warn(Mr("[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=Er(t,e.sceneGl);i.mismatch&&(e.warnedBufMismatch=!0,console.warn(Rr("[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=Nr(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=Nr(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:m,h:g}=this._eyeSize(e,e.sbs);(m!==e.eyeW||g!==e.eyeH)&&this._sizeBuffer(e,e.sbs)}let d=e.bufScale||1,f=e.cornerRadius*d,h=e.feather*d;if(o.clearRect(0,0,s.width,s.height),!e.sbs){it(o,n,0,0,a/2,l,0,0,s.width,s.height,f,h);return}let u=s.width/2,p=Math.min(this._stereoFactor,this._bakedStereo);if(p<1){it(o,n,0,0,a/2,l,0,0,u,s.height,f,h),po(o,n,a/2,l,u,s.height,p,f,h);return}f>0||h>0?(it(o,n,0,0,a/2,l,0,0,u,s.height,f,h),it(o,n,a/2,0,a/2,l,u,0,u,s.height,f,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(oi,()=>{this._setTrackingState(et(e)||"unknown")})}_setTrackingState(e){let t=zr.includes(e)?e:"unknown";if(t===this._trackingState)return;this._trackingState=t,this._applyUntrackedTarget();let i={type:oi,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(et(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?tt(e.layer):null;if(t){this._tickWovenState(e,t);return}if(e.rw){this._noteRewovenBox(e);let i=e.rw,n=W();i.stereo&&n-i.at>=e.fwHoldMs?this._settleRewoven(e,!0,"hold-elapsed"):i.at>i.calledAt&&n-i.calledAt>=ni*e.fwHoldMs&&this._settleRewoven(e,!0,"hold-capped")}e.fwResult||!e.fwStereo||e.fwLayerAt===null||W()-e.fwLayerAt<e.fwHoldMs||this._settleFirstWoven(e,!0,"hold-elapsed")}_tickWovenState(e,t){let i=W(),n=ni*Math.max(e.fwHoldMs,ai);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>=Dr||s.boxFrame===null&&this._frameCount-s.callFrame>=Dr)&&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,ri(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,ri(e.layer)||t,!0)))}_noteWithheld(e,t,i,n){t||!n||e.warnedWithheld||!i||i==="pending"||i==="hold-capped"||(e.warnedWithheld=!0,console.warn(`[inline3d] the browser withheld this canvas from the weave (${i}): ${yr(i)}.`,e.canvas))}_settleFirstWoven(e,t,i,n=!1){this._noteWithheld(e,t,i,n),!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(W()-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=W();return e.rw={promise:i,resolve:t,calledAt:n,at:n,stereo:!1,box:si(e.canvas),gap:!1,boxFrame:null,callFrame:this._frameCount},i}_noteRewovenBox(e){let t=e.rw;if(!t)return;let i=si(e.canvas);i!==t.box&&(t.box=i,this._restartRewoven(e))}_restartRewoven(e){e.rw&&(e.rw.at=W(),e.rw.stereo=!1,e.rw.gap=!1,e.rw.boxFrame=this._frameCount)}_settleRewoven(e,t,i,n=!1){let s=e.rw;s&&(this._noteWithheld(e,t,i,n),e.rw=null,s.resolve(Object.freeze({woven:t,confirmed:n,reason:i,ms:Math.round(W()-s.calledAt)})))}_rectCoverCheck(e){let t=e.rc,i=si(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,d=1;a>l?d=l/a:c=a/l;let f=n.width/2*c,h=n.height*d,u=(n.width/2-f)/2,p=(n.height-h)/2;try{i.width=s,i.height=o;let m=i.getContext("2d");if(!m)return;m.drawImage(n,u,p,f,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,Y===this&&(Y=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 uo(r){return typeof r=="number"&&Number.isFinite(r)&&r>=0?r:ai}function fo(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 it(r,e,t,i,n,s,o,a,l,c,d,f){d>0&&r.roundRect?(r.save(),r.beginPath(),r.roundRect(o,a,l,c,d),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),f>0&&Ur(r,o,a,l,c,f)}function po(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&&Ur(r,n,0,n,s,l)}function Ur(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,d,f,h,u]of a){let p=r.createLinearGradient(h[0],h[1],u[0],u[1]);p.addColorStop(0,"rgba(0,0,0,1)"),p.addColorStop(1,"rgba(0,0,0,0)"),r.fillStyle=p,r.fillRect(l,c,d,f)}r.restore()}function fe(r,e){return r>0&&e>0&&r/e>2.5}function q(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 Fe(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 pe(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 hi(r,e,t){let i=new r.constructor(r.length);for(let n of pe(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 Vr(r,e){return!(r>0)||!(e>0)||e>=180?null:r/2/Math.tan(e/2*Math.PI/180)}function nt({eyeWidthPx:r,hfovDeg:e,baselineMm:t,subjectZmm:i}){let n=Vr(r,e);return n===null||!(t>0)||!(i>0)?0:n*t/(2*i)}function st(r,e,t=.2){let i=Math.max(0,e*t);return Math.max(-i,Math.min(i,r||0))}function ot(r,e,t=.2){let i=r+t*(e-r);return Math.abs(e-i)<.05?e:i}function Ne(){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?nt({eyeWidthPx:e,hfovDeg:r.hello.hfovDeg,baselineMm:r.hello.baselineMm,subjectZmm:r.subjectZmm}):0;return st(t+r.depth*.05*e,e)},step(e){return r.current=ot(r.current,r.target(e)),r.current}};return r}var at=1,ui="inline3d-call/1",Br=Object.freeze(["sbs","mono"]),me=4,Xr=4,di=5,mo=150,go=5e3,_o=/^[A-Za-z0-9_-]{16,64}$/,vo=16;function fi(r){let e=new Uint8Array(vo);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),Gr(e)}function qr(r){let e=new Uint8Array(8);return(r||(i=>globalThis.crypto.getRandomValues(i)))(e),Gr(e)}function Gr(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 ge(r){return typeof r=="string"&&_o.test(r)}function je(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 ge(n)?n:null}return null}function lt(r,e){if(!ge(e))throw new Error(`@displayxr/inline3d/call: invalid room id "${e}"`);return`${String(r||"").split("#")[0]}#room=${e}`}function pi(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:at,format:Br.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 mi({format:r,width:e,height:t,baselineMm:i,hfovDeg:n,rectified:s}={}){let o={type:"hello",v:at,format:Br.includes(r)?r:"mono",width:e||0,height:t||0,rectified:!!s,sdk:ui};return Number.isFinite(i)&&(o.baselineMm=i),Number.isFinite(n)&&(o.hfovDeg=n),o}function gi(r){if(!r||r.type!=="hint")return null;let e=r.subjectZmm;return typeof e=="number"&&Number.isFinite(e)&&e>=mo&&e<=go?{type:"hint",subjectZmm:e}:null}function Yr(r){return!r||r.type!=="state"?null:{type:"state",muted:r.muted===!0,cameraOff:r.cameraOff===!0,speaking:r.speaking===!0}}function _i(r){let e=1e3/r,t=-1/0;return i=>i-t<e?!1:(t=i,!0)}function vi({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 yi(r){return r==="woven-sbs"?"3D":r==="lifted"?"2D\u21923D":"2D"}function wi({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 ct(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 K(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 ze=Object.freeze(["VP9","VP8","AV1"]);function wo(r,e=ze){let t=e.indexOf(String(r||"").toUpperCase());return t<0?e.length:t}function ht(r,e=ze){let t=i=>wo(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 We(r,e=ze){if(!r)return r;let t=r.includes(`\r
17
17
  `)?`\r
18
18
  `:`
19
- `,i=r.split(t),n=i.findIndex(u=>u.startsWith("m=video"));if(n<0)return r;let s=i.findIndex((u,p)=>p>n&&u.startsWith("m="));s<0&&(s=i.length);let o=i.slice(n,s),a=new Map,l=new Map;for(let u of o){let p=u.match(/^a=rtpmap:(\d+) ([\w-]+)\//);p&&a.set(p[1],p[2].toUpperCase());let m=u.match(/^a=fmtp:(\d+) apt=(\d+)/);m&&(l.has(m[2])||l.set(m[2],[]),l.get(m[2]).push(m[1]))}let c=i[n].split(" "),d=c.slice(3),f=[];for(let u of e)for(let p of d)if(a.get(p)===u&&!f.includes(p)){f.push(p);for(let m of l.get(p)||[])d.includes(m)&&!f.includes(m)&&f.push(m)}if(!f.length)return r;let h=d.filter(u=>!f.includes(u));return i[n]=[...c.slice(0,3),...f,...h].join(" "),i.join(t)}var Kr=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),xo=4e3,So=1e4,Mo=2e4,Eo=8e3,Ro=1e4;function $e(r){let e=Number.isInteger(r)?r:me;return Math.max(2,Math.min(Xr,e))}function Jr(r,e){return r<e}var He=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:n,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:Ro,this.signaling=e,this.id=t,this.maxPeers=$e(i),this.pageIce=n||null,this.iceServers=n||Kr,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:d,onGhost:f}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:d,onGhost:f};let h=m=>(...g)=>this.ready?m(...g):this._pending.push(()=>m(...g));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(m=>this._onPeerJoined(m)),onPeerLeft:h(m=>this._onPeerLeftSignaling(m)),onSignal:h((m,g)=>this._onSignal(m,g)),onDisconnect:m=>d?.(m?"closed":"reconnecting",m),onPeerUnreachable:h(m=>f?.(m,!0)),onPeerReachable:h(m=>f?.(m,!1)),onReconnect:h(m=>{d?.("connected");for(let g of m)this._onPeerJoined(g)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Kr,...this.session.iceServers]);let u=this.session.peers||[];if(u.length>=this.maxPeers){this.session.leave();let m=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw m.code="room-full",m}this.ready=!0;for(let m of u)this._onPeerJoined(m);let p=this._pending;this._pending=[];for(let m of p)m();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"&&Jr(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),Eo)}_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:Jr(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(d=>d.kind==="audio"),a=s.find(d=>d.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,Mo,()=>{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=We(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=We(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(ht(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,xo,()=>{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,So,()=>{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=K(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,K(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=ct(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 Zr={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},bi={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},Co=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function ko(r){return!!r&&(r.name==="NotReadableError"||r.name==="TrackStartError"||/in use|busy/i.test(r.message||""))}function To(r){return!!r&&(r.name==="NotAllowedError"||r.name==="PermissionDeniedError"||r.name==="SecurityError")}function Qr(r){return r.length&&r.every(e=>e.busy)?"camera-busy":r.some(e=>e.denied)?"permission-denied":"no-camera"}function xi(r){return/stereo|\b3d\b|\bsbs\b|dual/i.test(r||"")}async function en(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 p=r.getVideoTracks()[0],m=p?p.getSettings():{},g=e.format==="sbs"?"sbs":"mono";return{stream:r,format:g,width:m.width||0,height:m.height||0,deviceId:m.deviceId||null,label:p?p.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 p=>{let m=await t.getUserMedia({video:p,audio:!1}),g=m.getVideoTracks()[0],_=g?g.getSettings():{};if(!g||g.readyState==="ended"||!(_.width>0)||!(_.height>0))throw m.getTracks().forEach(S=>S.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=_.displayxrStereo&&_.displayxrStereo.layout==="side-by-side"?_.displayxrStereo:null;return{stream:m,track:g,width:_.width,height:_.height,deviceId:_.deviceId||null,label:g.label||"",stereo:b}},a=(p,m)=>{n.push({label:p,error:`${m.name}: ${m.message}`,busy:ko(m),denied:To(m)}),i("camera-skip",{label:p,error:m.name})},l=p=>p&&p.stream.getTracks().forEach(m=>m.stop()),c=(p,m)=>({stream:p.stream,format:m,width:p.width,height:p.height,deviceId:p.deviceId,label:p.label,owned:!0,skipped:n,calibration:{rectified:!1,...m==="sbs"&&p.stereo?{rectified:!!p.stereo.rectified,...p.stereo.baselineMm>0?{baselineMm:p.stereo.baselineMm}:{},...p.stereo.horizontalFovDeg>0?{hfovDeg:p.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof r=="string"&&!["auto","stereo","mono"].includes(r)){let p;try{p=await o({deviceId:{exact:r},...bi})}catch(m){throw a(r,m),Object.assign(new Error(`camera unavailable: ${m.message}`),{code:Qr(n),skipped:n})}return fe(p.width,p.height)?c(p,"sbs"):(l(p),c(await o({deviceId:{exact:r},...Zr}),"mono"))}let d=new Set;if(r!=="mono"){let p=[];try{p=(await t.enumerateDevices()).filter(m=>m.kind==="videoinput"&&m.deviceId&&xi(m.label))}catch{}for(let m of p){d.add(m.deviceId);let g=null;try{g=await o({deviceId:{exact:m.deviceId},...bi})}catch(_){a(m.label,_);continue}if(fe(g.width,g.height))return i("camera-sbs",{label:g.label,width:g.width,height:g.height,direct:!0}),c(g,"sbs");l(g)}}let f=null;try{f=await o(Zr)}catch(p){a("default",p)}if(r==="mono"&&f)return c(f,"mono");if(f&&fe(f.width,f.height))return c(f,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(p=>p.kind==="videoinput")}catch{}h.sort((p,m)=>Number(xi(m.label))-Number(xi(p.label)));for(let p of h){if(!p.deviceId||f&&p.deviceId===f.deviceId||d.has(p.deviceId))continue;let m=null;try{m=await o({deviceId:{exact:p.deviceId},...bi})}catch(g){a(p.label,g);continue}if(fe(m.width,m.height))return l(f),i("camera-sbs",{label:m.label,width:m.width,height:m.height}),c(m,"sbs");l(m)}if(f)return r==="stereo"&&i("camera-no-stereo",{fallback:f.label}),c(f,"mono");let u=Qr(n);throw Object.assign(new Error(u==="camera-busy"?"every camera is in use by another app (e.g. eye tracking)":u==="permission-denied"?"camera access was denied":"no camera could be opened"),{code:u,skipped:n})}async function tn(r={}){let e=r.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...Co},video:!1})).getAudioTracks()[0]||null}catch(t){return(r.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Mi();be();var ln="http://displayxr.org/ns/stereo/1.0/",wt="http://ns.adobe.com/xap/1.0/\0";function xt(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 Fo=r=>String(r).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Se=r=>Math.round(r*1e3)/1e3;function cn(r){let e=xt(r),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:Se(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:Se(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:Se(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}="${Fo(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="${ln}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Ci(r){if(typeof r!="string"||!r.includes(ln))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 xt({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(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&amp;/g,"&")})}var bt=r=>new TextEncoder().encode(r),Ri=r=>new TextDecoder().decode(r),hn=r=>r.length>4&&r[0]===255&&r[1]===216;function*un(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 dn(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 fn(r,e){if(!hn(r))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...bt(wt),...bt(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 d of un(r)){if(d.marker===225&&dn(d.data,wt)){o=d;break}if(d.marker===224||d.marker===225)s=d.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 ki(r){if(!hn(r))return null;for(let e of un(r))if(e.marker===225&&dn(e.data,wt))return Ri(e.data.subarray(wt.length));return null}var pn=r=>Ci(ki(r)),U={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},No=r=>r.length>4&&r[0]===26&&r[1]===69&&r[2]===223&&r[3]===163;function mn(r){let e=[];for(let t=r;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function gn(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 Ti(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 Ve(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 xe(r,e){return[...mn(r),...gn(e.length),...e]}function jo(r){let e=[];for(let[i,n]of Object.entries(r))n!=null&&e.push(...xe(U.SimpleTag,[...xe(U.TagName,[...bt(String(i))]),...xe(U.TagString,[...bt(String(n))])]));let t=xe(U.Tag,[...xe(U.Targets,[]),...e]);return new Uint8Array(xe(U.Tags,t))}function _n(r){let e=xt(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(Se(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(Se(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(Se(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 zo(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 xt({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 vn(r){if(!No(r))return null;let e=Ve(r,4);if(!e)return null;let t=4+e.width+e.size;for(;t<r.length;){let i=Ti(r,t);if(!i)return null;let n=Ve(r,t+i.width);if(!n)return null;let s=t+i.width+n.width;if(i.id===U.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 yn(r,e){let t=vn(r);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=jo(e);if(t.unknown){let d=new Uint8Array(r.length+i.length);return d.set(r,0),d.set(i,r.length),d}let n=Math.min(r.length,t.dataStart+t.size),s=n-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=gn(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 wn(r,e,t){let i={},n=(s,o,a)=>{let l=s;for(;l<o;){let c=Ti(r,l);if(!c)return;let d=Ve(r,l+c.width);if(!d||d.unknown)return;let f=l+c.width+d.width;a(c.id,f,Math.min(o,f+d.size)),l=f+d.size}};return n(e,t,(s,o,a)=>{s===U.Tag&&n(o,a,(l,c,d)=>{if(l!==U.SimpleTag)return;let f=null,h=null;n(c,d,(u,p,m)=>{u===U.TagName?f=Ri(r.subarray(p,m)):u===U.TagString&&(h=Ri(r.subarray(p,m)))}),f!==null&&(i[f]=h??"")})}),i}function Wo(r){let e=vn(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=Ti(r,n);if(!s)break;let o=Ve(r,n+s.width);if(!o)break;let a=n+s.width+o.width;if(s.id===U.Tags&&!o.unknown&&(i={...i||{},...wn(r,a,Math.min(t,a+o.size))}),o.unknown){i=i||Ho(r,t);break}n=a+o.size}return i}function Ho(r,e){let t=mn(U.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=Ve(r,i+4);if(n&&!n.unknown&&i+4+n.width+n.size===e)return wn(r,i+4+n.width,e)}return null}var bn=r=>zo(Wo(r));var oe="[inline3d/camera]",cs="inline3d-camera/1",la=200,ca=240,ha=66,ua=4e3,da=4,fa=1500,pa=2e4,ma=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],Lt=()=>typeof document<"u"&&document&&typeof document.createElement=="function",as=()=>{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())}`},ga=r=>/jpe?g/.test(r)?"jpg":/png/.test(r)?"png":/webp/.test(r)?"webp":/mp4/.test(r)?"mp4":/webm/.test(r)?"webm":"bin";function It(r,e,t){return`${String(r||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${ga(t)}`}var te=(r,e,t={})=>Object.assign(new Error(`${oe} ${r}`),{code:e,...t});function ls(r,e=ua){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(te("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(te("no video element (no document?)","no-frame"))}function hs(r,e,t=ca){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:dt(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var Ji=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,Lt()&&(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(`${oe} 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(`${oe} '${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||!Lt())return null;try{await ls(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=hs(this.video,this._scratch);if(!e)return null;let t=Ue().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:cs}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:n}={}){if(this.state==="closed")throw te("the camera is closed","closed");if(!this.video||!Lt())throw te("capturePhoto needs a document","no-frame");await ls(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((u,p)=>l.toBlob(m=>m?u(m):p(te("toBlob produced nothing","encode-failed")),e,t)),d=this._meta(a,s,o),f=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(f=cn(d),c=new Blob([fn(new Uint8Array(await c.arrayBuffer()),f)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:It(i||`photo-${as()}`,this.format,c.type||e),xmp:f};return this.log("photo",{width:s,height:o,layout:this.format,convergencePx:a,bytes:c.size,name:h.suggestedName}),h}record({mimeType:e,mono:t=!1,audio:i=null,videoBitsPerSecond:n,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw te("the camera is closed","closed");if(typeof MediaRecorder!="function")throw te("MediaRecorder is not available here","unsupported");let l=e||ma.find(v=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(v))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw te(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],d=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...d);let f=new MediaStream(c),h={...l?{mimeType:l}:{},...n?{videoBitsPerSecond:n}:{}},u=new MediaRecorder(f,h),p=[];u.ondataavailable=v=>v.data&&v.data.size&&p.push(v.data);let m=null,g=[],_=null,b=0,S=!!t&&this.format==="sbs"&&Lt()&&this.video;if(S){_=document.createElement("canvas");let v=()=>{b=requestAnimationFrame(v);let y=this.video,M=y.videoWidth,I=y.videoHeight;!M||!I||(y.readyState||0)<2||((_.width!==M/2||_.height!==I)&&(_.width=M/2,_.height=I),_.getContext("2d").drawImage(y,0,0,M/2,I,0,0,M/2,I))};v();let w=_.captureStream(a);for(let y of d)w.addTrack(y);m=new MediaRecorder(w,h),m.ondataavailable=y=>y.data&&y.data.size&&g.push(y.data)}let x=performance.now(),O=[],E=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(v=>v!==null&&O.push(v)),1500):0;this.measureConvergence().then(v=>v!==null&&O.push(v)),u.start(s),m?.start(s),this.log("record-start",{mimeType:l,mono:S,audio:d.length});let C=(v,w)=>new Promise(y=>{if(!v||v.state==="inactive")return y(w);v.onstop=()=>y(w),v.stop()}),P=o||`clip-${as()}`,D=this;return{get state(){return u.state},get mimeType(){return u.mimeType||l},pause(){u.state==="recording"&&u.pause(),m&&m.state==="recording"&&m.pause()},resume(){u.state==="paused"&&u.resume(),m&&m.state==="paused"&&m.resume()},async stop(){clearInterval(E),b&&cancelAnimationFrame(b);let[v,w]=await Promise.all([C(u,p),C(m,g)]),y=u.mimeType||l||v[0]&&v[0].type||"video/webm",M=[...O].sort((Oe,G)=>Oe-G),I=M.length?M[Math.floor(M.length/2)]:null,T=D._meta(I),N=/webm|matroska/.test(y),$=async(Oe,G)=>{let re=new Blob(Oe,{type:y});if(N&&re.size)try{re=new Blob([yn(new Uint8Array(await re.arrayBuffer()),_n({...T,layout:G}))],{type:y})}catch(pr){D.log("record-tag-failed",{message:String(pr&&pr.message)})}return re},L=await $(v,D.format),j={blob:L,type:y,layout:D.format,durationMs:Math.round(performance.now()-x),convergencePx:I,stereo:D.stereo,suggestedName:It(P,D.format,y),tagged:N&&L.size>0};return m&&(j.mono=await $(w,"mono"),j.monoSuggestedName=It(P,"mono",y)),D.log("record-stop",{bytes:L.size,mono:j.mono?j.mono.size:null,ms:j.durationMs,convergencePx:I,name:j.suggestedName}),j}}}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 Qi(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(`${oe} ${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 en(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 Ji(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 Ft=r=>!!r&&typeof r=="object"&&typeof r.capturePhoto=="function"&&typeof r.record=="function"&&r.stream&&typeof r.stream.getVideoTracks=="function";function _a(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 er(r,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${oe} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!Ft(t))throw new TypeError(`${oe} addCameraView: cam must be a StereoCamera from openCamera()`);let n=new Zi(r,e,t,i);return t._views?.add(n),n}var Zi=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=Ne(),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=ft(),this._focus=Ue(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=yt(n.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(Ki(),Yi)).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>=da)return;let t=Math.min(pa,fa*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(`${oe} 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(),!_a(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=q(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}=Fe(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 d=this.conv.step(n),f=l.getContext("2d");if(this.mirror)for(let h of pe(t,i)){let u=h.src==="L"?0:1,p=q(n,i,s,d,u),m=h.dx===0?0:o;f.save(),f.translate(m+o,0),f.scale(-1,1),f.drawImage(e,h.sx+p.sx,p.sy,p.sw,p.sh,0,0,o,a),f.restore()}else for(let h of[0,1]){let u=q(n,i,s,d,h);f.drawImage(e,h*n+u.sx,u.sy,u.sw,u.sh,h*o,0,o,a)}if(this.cursor){let h={rL:q(n,i,s,d,0),rR:q(n,i,s,d,1),outW:o,outH:a,mirror:this.mirror,handle:this.handle};this.cursor.draw(f,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?ha:la))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let n=hs(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 ds=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],fs=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],va=[1,0],tr=10;function ps(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 us=(r,e)=>Math.floor(ps(r)/8)-ds[e][r]*fs[e][r];function ir(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 ya(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]=ir(e[n],t),n+1<e.length&&(e[n]^=e[n+1]);t=ir(t,2)}return e}function wa(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]^=ir(s,n))}return t}function rr(r,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(r))],n=1;for(;n<=tr&&!(4+(n<=9?8:16)+i.length*8<=us(n,t)*8);n++);if(n>tr)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${tr} code`);let s=[],o=(v,w)=>{for(let y=w-1;y>=0;y--)s.push(v>>>y&1)};o(4,4),o(i.length,n<=9?8:16);for(let v of i)o(v,8);let a=us(n,t)*8;o(0,Math.min(4,a-s.length)),o(0,(8-s.length%8)%8);for(let v=236;s.length<a;v^=253)o(v,8);let l=[];for(let v=0;v<s.length;v+=8)l.push(s.slice(v,v+8).reduce((w,y)=>w<<1|y,0));let c=fs[t][n],d=ds[t][n],f=Math.floor(ps(n)/8),h=c-f%c,u=Math.floor(f/c),p=ya(d),m=[];for(let v=0,w=0;v<c;v++){let y=l.slice(w,w+u-d+(v<h?0:1));w+=y.length;let M=wa(y,p);v<h&&y.push(0),m.push(y.concat(M))}let g=[];for(let v=0;v<m[0].length;v++)for(let w=0;w<m.length;w++)(v!==u-d||w>=h)&&g.push(m[w][v]);let _=n*4+17,b=Array.from({length:_},()=>new Array(_).fill(!1)),S=Array.from({length:_},()=>new Array(_).fill(!1)),x=(v,w,y)=>{b[w][v]=y,S[w][v]=!0};for(let v=0;v<_;v++)x(6,v,v%2===0),x(v,6,v%2===0);let O=(v,w)=>{for(let y=-4;y<=4;y++)for(let M=-4;M<=4;M++){let I=Math.max(Math.abs(M),Math.abs(y)),T=v+M,N=w+y;T>=0&&T<_&&N>=0&&N<_&&x(T,N,I!==2&&I!==4)}};O(3,3),O(_-4,3),O(3,_-4);let E=[];if(n>1){let v=Math.floor(n/7)+2,w=Math.ceil((n*4+4)/(v*2-2))*2;E.push(6);for(let y=_-7;E.length<v;y-=w)E.splice(1,0,y)}for(let v=0;v<E.length;v++)for(let w=0;w<E.length;w++)if(!(v===0&&w===0||v===0&&w===E.length-1||v===E.length-1&&w===0))for(let y=-2;y<=2;y++)for(let M=-2;M<=2;M++)x(E[v]+M,E[w]+y,Math.max(Math.abs(M),Math.abs(y))!==1);let C=v=>{let w=va[t]<<3|v,y=w;for(let T=0;T<10;T++)y=y<<1^(y>>>9)*1335;let M=(w<<10|y)^21522,I=T=>(M>>>T&1)!==0;for(let T=0;T<=5;T++)x(8,T,I(T));x(8,7,I(6)),x(8,8,I(7)),x(7,8,I(8));for(let T=9;T<15;T++)x(14-T,8,I(T));for(let T=0;T<8;T++)x(_-1-T,8,I(T));for(let T=8;T<15;T++)x(8,_-15+T,I(T));x(8,_-8,!0)};if(C(0),n>=7){let v=n;for(let y=0;y<12;y++)v=v<<1^(v>>>11)*7973;let w=n<<12|v;for(let y=0;y<18;y++){let M=(w>>>y&1)!==0,I=_-11+y%3,T=Math.floor(y/3);x(I,T,M),x(T,I,M)}}let P=0;for(let v=_-1;v>=1;v-=2){v===6&&(v=5);for(let w=0;w<_;w++)for(let y=0;y<2;y++){let M=v-y,T=(v+1&2)===0?_-1-w:w;!S[T][M]&&P<g.length*8&&(b[T][M]=(g[P>>>3]>>>7-(P&7)&1)!==0,P++)}}let D=v=>{for(let w=0;w<_;w++)for(let y=0;y<_;y++){if(S[w][y])continue;let M;switch(v){case 0:M=(y+w)%2===0;break;case 1:M=w%2===0;break;case 2:M=y%3===0;break;case 3:M=(y+w)%3===0;break;case 4:M=(Math.floor(y/3)+Math.floor(w/2))%2===0;break;case 5:M=y*w%2+y*w%3===0;break;case 6:M=(y*w%2+y*w%3)%2===0;break;default:M=((y+w)%2+y*w%3)%2===0}M&&(b[w][y]=!b[w][y])}},k=Number.isInteger(e.mask)?e.mask:-1;if(k<0){let v=1/0;for(let w=0;w<8;w++){D(w),C(w);let y=ba(b,_);y<v&&(v=y,k=w),D(w)}}return D(k),C(k),{version:n,size:_,mask:k,modules:b}}function ba(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 d=l.indexOf(c);d>=0;d=l.indexOf(c,d+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 ms(r,e,{px:t=4,dark:i="#000",light:n="#fff",ecl:s="M"}={}){let o=rr(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 d=0;d<o.size;d++)o.modules[c][d]&&l.fillRect((d+4)*t,(c+4)*t,t,t);return o}function ie(r,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=r,t}async function nr(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 Nt="wss://signal.displayxr.org",gs=Object.freeze([Nt,"wss://dxr-signal.displayxr.workers.dev"]),_s=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function Ce(r=Nt,e={}){if(!r||typeof r!="string")throw ie("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):gs.includes(i)?[...gs]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,d){let h=`k=${await nr(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,u=D=>`${a[D]}/v1/connect?${h}`,p=null,m=!1,g=0,_=null,b=new Set,S=[],x=D=>O(D,a.length),O=(D,k)=>new Promise((v,w)=>{let y=!1,M=!1,I=!1,T=new n(u(l));p=T;let N=$=>{if(!y){y=!0;try{T.close()}catch{}w($)}};T.onopen=()=>{I=!0,T.send(JSON.stringify({t:"join",v:1,room:c,id:d.id,max:d.maxPeers}))},T.onmessage=$=>{let L;try{L=JSON.parse(typeof $.data=="string"?$.data:String($.data))}catch{return}switch(L.t){case"welcome":{g=0;let j=Array.isArray(L.peers)?L.peers.filter(G=>typeof G=="string"):[];clearInterval(_),_=setInterval(()=>E({t:"ping"}),s);let Oe=S;S=[];for(let G of Oe)E(G);if(D){let G=new Set(j);for(let re of b)G.has(re)||d.onPeerLeft?.(re);b=G,d.onReconnect?.(j)}else b=new Set(j);y=!0,M=!0,v({id:L.id,peers:j,iceServers:Array.isArray(L.iceServers)?L.iceServers:void 0,max:L.max,tier:L.tier==="key"?"key":"anon",key:typeof L.key=="string"?L.key:void 0,turn:L.turn&&typeof L.turn=="object"?L.turn:void 0});break}case"full":m=!0,N(ie("room-full",`this call is full (${L.max} participants)`));break;case"expired":{m=!0,clearInterval(_);let j=ie("expired","this room has reached its lifetime on the signalling server");y?d.onDisconnect?.(j):N(j);break}case"error":if(!y&&_s.includes(L.code))m=!0,N(ie(L.code,L.message||L.code));else if(!y&&(L.code==="rate-limited"||L.code==="quota")){let j=ie(L.code,L.message||L.code);j.retryMs=L.retryMs>0?L.retryMs:0,N(j)}else!y&&L.code==="id-taken"&&N(ie("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof L.id=="string"&&!b.has(L.id)&&(b.add(L.id),d.onPeerJoined?.(L.id));break;case"peer-left":typeof L.id=="string"&&(b.delete(L.id),d.onPeerLeft?.(L.id));break;case"signal":typeof L.from=="string"&&d.onSignal?.(L.from,L.data);break}},T.onerror=()=>{if(!I&&!y&&k>1){y=!0,l=(l+1)%a.length,O(D,k-1).then(v,w);return}N(ie("signaling-unreachable",`cannot reach ${a[l]}`))},T.onclose=()=>{clearInterval(_),N(ie("signaling-closed","signalling closed before joining")),M&&!m&&p===T&&C()}}),E=D=>{p&&p.readyState===1?p.send(JSON.stringify(D)):m||S.push(D)},C=()=>{d.onDisconnect?.();let D=()=>{m||x(!0).catch(k=>{if(m||k&&(k.code==="room-full"||_s.includes(k.code))){d.onDisconnect?.(k);return}setTimeout(D,Math.max(K(g++,{baseMs:500,maxMs:15e3}),k&&k.retryMs||0))})};setTimeout(D,K(g++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(D,k)=>E({t:"signal",to:D,data:k}),leave:()=>{if(!m){m=!0,clearInterval(_);try{p&&p.readyState===1&&p.send(JSON.stringify({t:"leave"})),p&&p.close(1e3,"leave")}catch{}}}}}}}var sr=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),ys=r=>typeof r=="string"&&sr[r.toLowerCase()]||r,ws=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),Ye=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 bs(r){let e={...Ye,...r&&typeof r=="object"?r:{}};return(t,i)=>{let n=typeof e[t]=="string"?e[t]:Ye[t]||t;if(i)for(let[s,o]of Object.entries(i))n=n.split(`{${s}}`).join(String(o));return n}}var vs="dxr-call-style",Ma=`
19
+ `,i=r.split(t),n=i.findIndex(u=>u.startsWith("m=video"));if(n<0)return r;let s=i.findIndex((u,p)=>p>n&&u.startsWith("m="));s<0&&(s=i.length);let o=i.slice(n,s),a=new Map,l=new Map;for(let u of o){let p=u.match(/^a=rtpmap:(\d+) ([\w-]+)\//);p&&a.set(p[1],p[2].toUpperCase());let m=u.match(/^a=fmtp:(\d+) apt=(\d+)/);m&&(l.has(m[2])||l.set(m[2],[]),l.get(m[2]).push(m[1]))}let c=i[n].split(" "),d=c.slice(3),f=[];for(let u of e)for(let p of d)if(a.get(p)===u&&!f.includes(p)){f.push(p);for(let m of l.get(p)||[])d.includes(m)&&!f.includes(m)&&f.push(m)}if(!f.length)return r;let h=d.filter(u=>!f.includes(u));return i[n]=[...c.slice(0,3),...f,...h].join(" "),i.join(t)}var Kr=Object.freeze([{urls:"stun:stun.l.google.com:19302"}]),xo=4e3,So=1e4,Mo=2e4,Eo=8e3,Ro=1e4;function $e(r){let e=Number.isInteger(r)?r:me;return Math.max(2,Math.min(Xr,e))}function Jr(r,e){return r<e}var He=class{constructor({signaling:e,id:t,maxPeers:i,iceServers:n,RTCPeerConnection:s,log:o,unreachableMs:a}={}){this.unreachableMs=a>0?a:Ro,this.signaling=e,this.id=t,this.maxPeers=$e(i),this.pageIce=n||null,this.iceServers=n||Kr,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:d,onGhost:f}){this.localStream=t,this.sendFormat=i||"mono",this.cb={onPeer:n,onPeerLeft:s,onStream:o,onMessage:a,onPeerState:l,onRefused:c,onSignalingState:d,onGhost:f};let h=m=>(...g)=>this.ready?m(...g):this._pending.push(()=>m(...g));this.session=await this.signaling.join(e,{id:this.id,maxPeers:this.maxPeers,onPeerJoined:h(m=>this._onPeerJoined(m)),onPeerLeft:h(m=>this._onPeerLeftSignaling(m)),onSignal:h((m,g)=>this._onSignal(m,g)),onDisconnect:m=>d?.(m?"closed":"reconnecting",m),onPeerUnreachable:h(m=>f?.(m,!0)),onPeerReachable:h(m=>f?.(m,!1)),onReconnect:h(m=>{d?.("connected");for(let g of m)this._onPeerJoined(g)})}),!this.pageIce&&this.session.iceServers&&this.session.iceServers.length&&(this.iceServers=[...Kr,...this.session.iceServers]);let u=this.session.peers||[];if(u.length>=this.maxPeers){this.session.leave();let m=new Error(`@displayxr/inline3d/call: this call is full (${this.maxPeers} participants)`);throw m.code="room-full",m}this.ready=!0;for(let m of u)this._onPeerJoined(m);let p=this._pending;this._pending=[];for(let m of p)m();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"&&Jr(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),Eo)}_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:Jr(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(d=>d.kind==="audio"),a=s.find(d=>d.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,Mo,()=>{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=We(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=We(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(ht(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,xo,()=>{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,So,()=>{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=K(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,K(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=ct(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 Zr={width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},bi={width:{ideal:3840},height:{ideal:1080},frameRate:{ideal:30}},Co=Object.freeze({echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0});function ko(r){return!!r&&(r.name==="NotReadableError"||r.name==="TrackStartError"||/in use|busy/i.test(r.message||""))}function To(r){return!!r&&(r.name==="NotAllowedError"||r.name==="PermissionDeniedError"||r.name==="SecurityError")}function Qr(r){return r.length&&r.every(e=>e.busy)?"camera-busy":r.some(e=>e.denied)?"permission-denied":"no-camera"}function xi(r){return/stereo|\b3d\b|\bsbs\b|dual/i.test(r||"")}async function en(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 p=r.getVideoTracks()[0],m=p?p.getSettings():{},g=e.format==="sbs"?"sbs":"mono";return{stream:r,format:g,width:m.width||0,height:m.height||0,deviceId:m.deviceId||null,label:p?p.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 p=>{let m=await t.getUserMedia({video:p,audio:!1}),g=m.getVideoTracks()[0],_=g?g.getSettings():{};if(!g||g.readyState==="ended"||!(_.width>0)||!(_.height>0))throw m.getTracks().forEach(S=>S.stop()),Object.assign(new Error("the camera opened but delivers no picture (0x0)"),{name:"NotReadableError"});let b=_.displayxrStereo&&_.displayxrStereo.layout==="side-by-side"?_.displayxrStereo:null;return{stream:m,track:g,width:_.width,height:_.height,deviceId:_.deviceId||null,label:g.label||"",stereo:b}},a=(p,m)=>{n.push({label:p,error:`${m.name}: ${m.message}`,busy:ko(m),denied:To(m)}),i("camera-skip",{label:p,error:m.name})},l=p=>p&&p.stream.getTracks().forEach(m=>m.stop()),c=(p,m)=>({stream:p.stream,format:m,width:p.width,height:p.height,deviceId:p.deviceId,label:p.label,owned:!0,skipped:n,calibration:{rectified:!1,...m==="sbs"&&p.stereo?{rectified:!!p.stereo.rectified,...p.stereo.baselineMm>0?{baselineMm:p.stereo.baselineMm}:{},...p.stereo.horizontalFovDeg>0?{hfovDeg:p.stereo.horizontalFovDeg}:{}}:{},...s}});if(typeof r=="string"&&!["auto","stereo","mono"].includes(r)){let p;try{p=await o({deviceId:{exact:r},...bi})}catch(m){throw a(r,m),Object.assign(new Error(`camera unavailable: ${m.message}`),{code:Qr(n),skipped:n})}return fe(p.width,p.height)?c(p,"sbs"):(l(p),c(await o({deviceId:{exact:r},...Zr}),"mono"))}let d=new Set;if(r!=="mono"){let p=[];try{p=(await t.enumerateDevices()).filter(m=>m.kind==="videoinput"&&m.deviceId&&xi(m.label))}catch{}for(let m of p){d.add(m.deviceId);let g=null;try{g=await o({deviceId:{exact:m.deviceId},...bi})}catch(_){a(m.label,_);continue}if(fe(g.width,g.height))return i("camera-sbs",{label:g.label,width:g.width,height:g.height,direct:!0}),c(g,"sbs");l(g)}}let f=null;try{f=await o(Zr)}catch(p){a("default",p)}if(r==="mono"&&f)return c(f,"mono");if(f&&fe(f.width,f.height))return c(f,"sbs");let h=[];try{h=(await t.enumerateDevices()).filter(p=>p.kind==="videoinput")}catch{}h.sort((p,m)=>Number(xi(m.label))-Number(xi(p.label)));for(let p of h){if(!p.deviceId||f&&p.deviceId===f.deviceId||d.has(p.deviceId))continue;let m=null;try{m=await o({deviceId:{exact:p.deviceId},...bi})}catch(g){a(p.label,g);continue}if(fe(m.width,m.height))return l(f),i("camera-sbs",{label:m.label,width:m.width,height:m.height}),c(m,"sbs");l(m)}if(f)return r==="stereo"&&i("camera-no-stereo",{fallback:f.label}),c(f,"mono");let u=Qr(n);throw Object.assign(new Error(u==="camera-busy"?"every camera is in use by another app (e.g. eye tracking)":u==="permission-denied"?"camera access was denied":"no camera could be opened"),{code:u,skipped:n})}async function tn(r={}){let e=r.mediaDevices||globalThis.navigator&&navigator.mediaDevices;try{return(await e.getUserMedia({audio:{...Co},video:!1})).getAudioTracks()[0]||null}catch(t){return(r.log||(()=>{}))("mic-skip",{error:t&&t.name}),null}}Mi();be();var ln="http://displayxr.org/ns/stereo/1.0/",wt="http://ns.adobe.com/xap/1.0/\0";function xt(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 Fo=r=>String(r).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;"),Se=r=>Math.round(r*1e3)/1e3;function cn(r){let e=xt(r),t=[["Layout",e.layout==="sbs"?"side-by-side":"mono"],["Columns",e.columns],["Rows",e.rows],["ConvergencePx",e.convergencePx===null?null:Se(e.convergencePx)],["BaselineMm",e.baselineMm===null?null:Se(e.baselineMm)],["HorizontalFovDeg",e.horizontalFovDeg===null?null:Se(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}="${Fo(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="${ln}"${t}/></rdf:RDF></x:xmpmeta><?xpacket end="w"?>`}function Ci(r){if(typeof r!="string"||!r.includes(ln))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 xt({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(/&quot;/g,'"').replace(/&lt;/g,"<").replace(/&amp;/g,"&")})}var bt=r=>new TextEncoder().encode(r),Ri=r=>new TextDecoder().decode(r),hn=r=>r.length>4&&r[0]===255&&r[1]===216;function*un(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 dn(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 fn(r,e){if(!hn(r))throw new TypeError("jpegWithXmp: not a JPEG");let t=new Uint8Array([...bt(wt),...bt(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 d of un(r)){if(d.marker===225&&dn(d.data,wt)){o=d;break}if(d.marker===224||d.marker===225)s=d.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 ki(r){if(!hn(r))return null;for(let e of un(r))if(e.marker===225&&dn(e.data,wt))return Ri(e.data.subarray(wt.length));return null}var pn=r=>Ci(ki(r)),U={EBML:440786851,Segment:408125543,Tags:307544935,Tag:29555,Targets:25536,SimpleTag:26568,TagName:17827,TagString:17543},No=r=>r.length>4&&r[0]===26&&r[1]===69&&r[2]===223&&r[3]===163;function mn(r){let e=[];for(let t=r;t>0;t=Math.floor(t/256))e.unshift(t%256);return e}function gn(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 Ti(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 Ve(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 xe(r,e){return[...mn(r),...gn(e.length),...e]}function jo(r){let e=[];for(let[i,n]of Object.entries(r))n!=null&&e.push(...xe(U.SimpleTag,[...xe(U.TagName,[...bt(String(i))]),...xe(U.TagString,[...bt(String(n))])]));let t=xe(U.Tag,[...xe(U.Targets,[]),...e]);return new Uint8Array(xe(U.Tags,t))}function _n(r){let e=xt(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(Se(e.convergencePx)),DXR_BASELINE_MM:e.baselineMm===null?null:String(Se(e.baselineMm)),DXR_HFOV_DEG:e.horizontalFovDeg===null?null:String(Se(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 zo(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 xt({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 vn(r){if(!No(r))return null;let e=Ve(r,4);if(!e)return null;let t=4+e.width+e.size;for(;t<r.length;){let i=Ti(r,t);if(!i)return null;let n=Ve(r,t+i.width);if(!n)return null;let s=t+i.width+n.width;if(i.id===U.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 yn(r,e){let t=vn(r);if(!t)throw new TypeError("webmWithTags: not a WebM/Matroska file (no Segment)");let i=jo(e);if(t.unknown){let d=new Uint8Array(r.length+i.length);return d.set(r,0),d.set(i,r.length),d}let n=Math.min(r.length,t.dataStart+t.size),s=n-t.dataStart+i.length,o=s<=2**(7*t.sizeWidth)-2,a=gn(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 wn(r,e,t){let i={},n=(s,o,a)=>{let l=s;for(;l<o;){let c=Ti(r,l);if(!c)return;let d=Ve(r,l+c.width);if(!d||d.unknown)return;let f=l+c.width+d.width;a(c.id,f,Math.min(o,f+d.size)),l=f+d.size}};return n(e,t,(s,o,a)=>{s===U.Tag&&n(o,a,(l,c,d)=>{if(l!==U.SimpleTag)return;let f=null,h=null;n(c,d,(u,p,m)=>{u===U.TagName?f=Ri(r.subarray(p,m)):u===U.TagString&&(h=Ri(r.subarray(p,m)))}),f!==null&&(i[f]=h??"")})}),i}function Wo(r){let e=vn(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=Ti(r,n);if(!s)break;let o=Ve(r,n+s.width);if(!o)break;let a=n+s.width+o.width;if(s.id===U.Tags&&!o.unknown&&(i={...i||{},...wn(r,a,Math.min(t,a+o.size))}),o.unknown){i=i||Ho(r,t);break}n=a+o.size}return i}function Ho(r,e){let t=mn(U.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=Ve(r,i+4);if(n&&!n.unknown&&i+4+n.width+n.size===e)return wn(r,i+4+n.width,e)}return null}var bn=r=>zo(Wo(r));var oe="[inline3d/camera]",cs="inline3d-camera/1",la=200,ca=240,ha=66,ua=4e3,da=4,fa=1500,pa=2e4,ma=["video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm","video/mp4"],Lt=()=>typeof document<"u"&&document&&typeof document.createElement=="function",as=()=>{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())}`},ga=r=>/jpe?g/.test(r)?"jpg":/png/.test(r)?"png":/webp/.test(r)?"webp":/mp4/.test(r)?"mp4":/webm/.test(r)?"webm":"bin";function It(r,e,t){return`${String(r||"capture").replace(/[^\w.-]+/g,"-").replace(/^-+|-+$/g,"")||"capture"}${e==="sbs"?"_2x1":""}.${ga(t)}`}var te=(r,e,t={})=>Object.assign(new Error(`${oe} ${r}`),{code:e,...t});function ls(r,e=ua){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(te("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(te("no video element (no document?)","no-frame"))}function hs(r,e,t=ca){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:dt(l.getImageData(0,0,o,a).data,o*a),w:o,h:a,scale:o/i}}catch{return null}}var Ji=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,Lt()&&(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 facing(){try{let e=this.stream.getVideoTracks()[0]?.getSettings?.().facingMode;return typeof e=="string"&&e?e:null}catch{return null}}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(`${oe} 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(`${oe} '${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||!Lt())return null;try{await ls(this.video)}catch{return null}this._scratch=this._scratch||document.createElement("canvas");let e=hs(this.video,this._scratch);if(!e)return null;let t=Ue().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:cs}}async capturePhoto({type:e="image/jpeg",quality:t=.92,name:i,convergencePx:n}={}){if(this.state==="closed")throw te("the camera is closed","closed");if(!this.video||!Lt())throw te("capturePhoto needs a document","no-frame");await ls(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((u,p)=>l.toBlob(m=>m?u(m):p(te("toBlob produced nothing","encode-failed")),e,t)),d=this._meta(a,s,o),f=null;(c.type==="image/jpeg"||/jpe?g/.test(e))&&(f=cn(d),c=new Blob([fn(new Uint8Array(await c.arrayBuffer()),f)],{type:"image/jpeg"}));let h={blob:c,type:c.type||e,width:s,height:o,layout:this.format,convergencePx:a,stereo:this.stereo,suggestedName:It(i||`photo-${as()}`,this.format,c.type||e),xmp:f};return this.log("photo",{width:s,height:o,layout:this.format,convergencePx:a,bytes:c.size,name:h.suggestedName}),h}record({mimeType:e,mono:t=!1,audio:i=null,videoBitsPerSecond:n,timesliceMs:s=1e3,name:o,fps:a=30}={}){if(this.state==="closed")throw te("the camera is closed","closed");if(typeof MediaRecorder!="function")throw te("MediaRecorder is not available here","unsupported");let l=e||ma.find(v=>typeof MediaRecorder.isTypeSupported!="function"||MediaRecorder.isTypeSupported(v))||"";if(l&&typeof MediaRecorder.isTypeSupported=="function"&&!MediaRecorder.isTypeSupported(l))throw te(`${l} is not a supported recording type here`,"unsupported");let c=[...this.stream.getVideoTracks()],d=i&&typeof i.getAudioTracks=="function"?i.getAudioTracks():i&&i.kind==="audio"?[i]:[];c.push(...d);let f=new MediaStream(c),h={...l?{mimeType:l}:{},...n?{videoBitsPerSecond:n}:{}},u=new MediaRecorder(f,h),p=[];u.ondataavailable=v=>v.data&&v.data.size&&p.push(v.data);let m=null,g=[],_=null,b=0,S=!!t&&this.format==="sbs"&&Lt()&&this.video;if(S){_=document.createElement("canvas");let v=()=>{b=requestAnimationFrame(v);let y=this.video,M=y.videoWidth,I=y.videoHeight;!M||!I||(y.readyState||0)<2||((_.width!==M/2||_.height!==I)&&(_.width=M/2,_.height=I),_.getContext("2d").drawImage(y,0,0,M/2,I,0,0,M/2,I))};v();let w=_.captureStream(a);for(let y of d)w.addTrack(y);m=new MediaRecorder(w,h),m.ondataavailable=y=>y.data&&y.data.size&&g.push(y.data)}let x=performance.now(),O=[],E=this.format==="sbs"?setInterval(()=>this.measureConvergence().then(v=>v!==null&&O.push(v)),1500):0;this.measureConvergence().then(v=>v!==null&&O.push(v)),u.start(s),m?.start(s),this.log("record-start",{mimeType:l,mono:S,audio:d.length});let C=(v,w)=>new Promise(y=>{if(!v||v.state==="inactive")return y(w);v.onstop=()=>y(w),v.stop()}),P=o||`clip-${as()}`,D=this;return{get state(){return u.state},get mimeType(){return u.mimeType||l},pause(){u.state==="recording"&&u.pause(),m&&m.state==="recording"&&m.pause()},resume(){u.state==="paused"&&u.resume(),m&&m.state==="paused"&&m.resume()},async stop(){clearInterval(E),b&&cancelAnimationFrame(b);let[v,w]=await Promise.all([C(u,p),C(m,g)]),y=u.mimeType||l||v[0]&&v[0].type||"video/webm",M=[...O].sort((Oe,G)=>Oe-G),I=M.length?M[Math.floor(M.length/2)]:null,T=D._meta(I),N=/webm|matroska/.test(y),$=async(Oe,G)=>{let re=new Blob(Oe,{type:y});if(N&&re.size)try{re=new Blob([yn(new Uint8Array(await re.arrayBuffer()),_n({...T,layout:G}))],{type:y})}catch(pr){D.log("record-tag-failed",{message:String(pr&&pr.message)})}return re},L=await $(v,D.format),j={blob:L,type:y,layout:D.format,durationMs:Math.round(performance.now()-x),convergencePx:I,stereo:D.stereo,suggestedName:It(P,D.format,y),tagged:N&&L.size>0};return m&&(j.mono=await $(w,"mono"),j.monoSuggestedName=It(P,"mono",y)),D.log("record-stop",{bytes:L.size,mono:j.mono?j.mono.size:null,ms:j.durationMs,convergencePx:I,name:j.suggestedName}),j}}}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 Qi(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(`${oe} ${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 en(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 Ji(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 Ft=r=>!!r&&typeof r=="object"&&typeof r.capturePhoto=="function"&&typeof r.record=="function"&&r.stream&&typeof r.stream.getVideoTracks=="function";function _a(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 er(r,e,t,i={}){if(!e||typeof e.getContext!="function")throw new TypeError(`${oe} addCameraView(wall, canvas, cam, opts) needs a canvas`);if(!Ft(t))throw new TypeError(`${oe} addCameraView: cam must be a StereoCamera from openCamera()`);let n=new Zi(r,e,t,i);return t._views?.add(n),n}var Zi=class{constructor(e,t,i,n){this.wall=e||null,this.canvas=t,this.cam=i,this.mirror=n.mirror===void 0?i.facing!=="environment":!!n.mirror,this.aspect=typeof n.aspect=="number"&&n.aspect>.3&&n.aspect<4?n.aspect:16/9,this.autoConverge=!!n.autoConverge,this.conv=Ne(),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=ft(),this._focus=Ue(),this._scratch=null,this._luma=null,this.disparityPx=null,this._cursorOpt=yt(n.cursor,"@displayxr/inline3d/camera"),this.cursor=null,this._cursorOpt&&Promise.resolve().then(()=>(Ki(),Yi)).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>=da)return;let t=Math.min(pa,fa*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(`${oe} 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(),!_a(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=q(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}=Fe(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 d=this.conv.step(n),f=l.getContext("2d");if(this.mirror)for(let h of pe(t,i)){let u=h.src==="L"?0:1,p=q(n,i,s,d,u),m=h.dx===0?0:o;f.save(),f.translate(m+o,0),f.scale(-1,1),f.drawImage(e,h.sx+p.sx,p.sy,p.sw,p.sh,0,0,o,a),f.restore()}else for(let h of[0,1]){let u=q(n,i,s,d,h);f.drawImage(e,h*n+u.sx,u.sy,u.sw,u.sh,h*o,0,o,a)}if(this.cursor){let h={rL:q(n,i,s,d,0),rR:q(n,i,s,d,1),outW:o,outH:a,mirror:this.mirror,handle:this.handle};this.cursor.draw(f,this._luma,h,performance.now()/1e3)}}_sample(e,t=!1){let i=performance.now();if(i-this._autoAt<(t?ha:la))return;this._autoAt=i,this._scratch=this._scratch||document.createElement("canvas");let n=hs(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 ds=[[-1,7,10,15,20,26,18,20,24,30,18],[-1,10,16,26,18,24,16,18,22,22,26]],fs=[[-1,1,1,1,1,1,2,2,2,2,4],[-1,1,1,1,2,2,4,4,4,5,5]],va=[1,0],tr=10;function ps(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 us=(r,e)=>Math.floor(ps(r)/8)-ds[e][r]*fs[e][r];function ir(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 ya(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]=ir(e[n],t),n+1<e.length&&(e[n]^=e[n+1]);t=ir(t,2)}return e}function wa(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]^=ir(s,n))}return t}function rr(r,e={}){let t=e.ecl==="L"?0:1,i=[...new TextEncoder().encode(String(r))],n=1;for(;n<=tr&&!(4+(n<=9?8:16)+i.length*8<=us(n,t)*8);n++);if(n>tr)throw new Error(`qrEncode: ${i.length} bytes is too long for a version-${tr} code`);let s=[],o=(v,w)=>{for(let y=w-1;y>=0;y--)s.push(v>>>y&1)};o(4,4),o(i.length,n<=9?8:16);for(let v of i)o(v,8);let a=us(n,t)*8;o(0,Math.min(4,a-s.length)),o(0,(8-s.length%8)%8);for(let v=236;s.length<a;v^=253)o(v,8);let l=[];for(let v=0;v<s.length;v+=8)l.push(s.slice(v,v+8).reduce((w,y)=>w<<1|y,0));let c=fs[t][n],d=ds[t][n],f=Math.floor(ps(n)/8),h=c-f%c,u=Math.floor(f/c),p=ya(d),m=[];for(let v=0,w=0;v<c;v++){let y=l.slice(w,w+u-d+(v<h?0:1));w+=y.length;let M=wa(y,p);v<h&&y.push(0),m.push(y.concat(M))}let g=[];for(let v=0;v<m[0].length;v++)for(let w=0;w<m.length;w++)(v!==u-d||w>=h)&&g.push(m[w][v]);let _=n*4+17,b=Array.from({length:_},()=>new Array(_).fill(!1)),S=Array.from({length:_},()=>new Array(_).fill(!1)),x=(v,w,y)=>{b[w][v]=y,S[w][v]=!0};for(let v=0;v<_;v++)x(6,v,v%2===0),x(v,6,v%2===0);let O=(v,w)=>{for(let y=-4;y<=4;y++)for(let M=-4;M<=4;M++){let I=Math.max(Math.abs(M),Math.abs(y)),T=v+M,N=w+y;T>=0&&T<_&&N>=0&&N<_&&x(T,N,I!==2&&I!==4)}};O(3,3),O(_-4,3),O(3,_-4);let E=[];if(n>1){let v=Math.floor(n/7)+2,w=Math.ceil((n*4+4)/(v*2-2))*2;E.push(6);for(let y=_-7;E.length<v;y-=w)E.splice(1,0,y)}for(let v=0;v<E.length;v++)for(let w=0;w<E.length;w++)if(!(v===0&&w===0||v===0&&w===E.length-1||v===E.length-1&&w===0))for(let y=-2;y<=2;y++)for(let M=-2;M<=2;M++)x(E[v]+M,E[w]+y,Math.max(Math.abs(M),Math.abs(y))!==1);let C=v=>{let w=va[t]<<3|v,y=w;for(let T=0;T<10;T++)y=y<<1^(y>>>9)*1335;let M=(w<<10|y)^21522,I=T=>(M>>>T&1)!==0;for(let T=0;T<=5;T++)x(8,T,I(T));x(8,7,I(6)),x(8,8,I(7)),x(7,8,I(8));for(let T=9;T<15;T++)x(14-T,8,I(T));for(let T=0;T<8;T++)x(_-1-T,8,I(T));for(let T=8;T<15;T++)x(8,_-15+T,I(T));x(8,_-8,!0)};if(C(0),n>=7){let v=n;for(let y=0;y<12;y++)v=v<<1^(v>>>11)*7973;let w=n<<12|v;for(let y=0;y<18;y++){let M=(w>>>y&1)!==0,I=_-11+y%3,T=Math.floor(y/3);x(I,T,M),x(T,I,M)}}let P=0;for(let v=_-1;v>=1;v-=2){v===6&&(v=5);for(let w=0;w<_;w++)for(let y=0;y<2;y++){let M=v-y,T=(v+1&2)===0?_-1-w:w;!S[T][M]&&P<g.length*8&&(b[T][M]=(g[P>>>3]>>>7-(P&7)&1)!==0,P++)}}let D=v=>{for(let w=0;w<_;w++)for(let y=0;y<_;y++){if(S[w][y])continue;let M;switch(v){case 0:M=(y+w)%2===0;break;case 1:M=w%2===0;break;case 2:M=y%3===0;break;case 3:M=(y+w)%3===0;break;case 4:M=(Math.floor(y/3)+Math.floor(w/2))%2===0;break;case 5:M=y*w%2+y*w%3===0;break;case 6:M=(y*w%2+y*w%3)%2===0;break;default:M=((y+w)%2+y*w%3)%2===0}M&&(b[w][y]=!b[w][y])}},k=Number.isInteger(e.mask)?e.mask:-1;if(k<0){let v=1/0;for(let w=0;w<8;w++){D(w),C(w);let y=ba(b,_);y<v&&(v=y,k=w),D(w)}}return D(k),C(k),{version:n,size:_,mask:k,modules:b}}function ba(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 d=l.indexOf(c);d>=0;d=l.indexOf(c,d+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 ms(r,e,{px:t=4,dark:i="#000",light:n="#fff",ecl:s="M"}={}){let o=rr(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 d=0;d<o.size;d++)o.modules[c][d]&&l.fillRect((d+4)*t,(c+4)*t,t,t);return o}function ie(r,e){let t=new Error(`@displayxr/inline3d/call: ${e}`);return t.code=r,t}async function nr(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 Nt="wss://signal.displayxr.org",gs=Object.freeze([Nt,"wss://dxr-signal.displayxr.workers.dev"]),_s=["bad-room","bad-id","bad-version","bad-key","origin-not-allowed","blocked"];function Ce(r=Nt,e={}){if(!r||typeof r!="string")throw ie("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):gs.includes(i)?[...gs]:[],a=[i,...o.filter(c=>c!==i)],l=0;return{name:"dxr",url:i,async join(c,d){let h=`k=${await nr(c)}${typeof e.key=="string"&&e.key?`&key=${encodeURIComponent(e.key)}`:""}`,u=D=>`${a[D]}/v1/connect?${h}`,p=null,m=!1,g=0,_=null,b=new Set,S=[],x=D=>O(D,a.length),O=(D,k)=>new Promise((v,w)=>{let y=!1,M=!1,I=!1,T=new n(u(l));p=T;let N=$=>{if(!y){y=!0;try{T.close()}catch{}w($)}};T.onopen=()=>{I=!0,T.send(JSON.stringify({t:"join",v:1,room:c,id:d.id,max:d.maxPeers}))},T.onmessage=$=>{let L;try{L=JSON.parse(typeof $.data=="string"?$.data:String($.data))}catch{return}switch(L.t){case"welcome":{g=0;let j=Array.isArray(L.peers)?L.peers.filter(G=>typeof G=="string"):[];clearInterval(_),_=setInterval(()=>E({t:"ping"}),s);let Oe=S;S=[];for(let G of Oe)E(G);if(D){let G=new Set(j);for(let re of b)G.has(re)||d.onPeerLeft?.(re);b=G,d.onReconnect?.(j)}else b=new Set(j);y=!0,M=!0,v({id:L.id,peers:j,iceServers:Array.isArray(L.iceServers)?L.iceServers:void 0,max:L.max,tier:L.tier==="key"?"key":"anon",key:typeof L.key=="string"?L.key:void 0,turn:L.turn&&typeof L.turn=="object"?L.turn:void 0});break}case"full":m=!0,N(ie("room-full",`this call is full (${L.max} participants)`));break;case"expired":{m=!0,clearInterval(_);let j=ie("expired","this room has reached its lifetime on the signalling server");y?d.onDisconnect?.(j):N(j);break}case"error":if(!y&&_s.includes(L.code))m=!0,N(ie(L.code,L.message||L.code));else if(!y&&(L.code==="rate-limited"||L.code==="quota")){let j=ie(L.code,L.message||L.code);j.retryMs=L.retryMs>0?L.retryMs:0,N(j)}else!y&&L.code==="id-taken"&&N(ie("id-taken","peer id still held; retrying"));break;case"peer-joined":typeof L.id=="string"&&!b.has(L.id)&&(b.add(L.id),d.onPeerJoined?.(L.id));break;case"peer-left":typeof L.id=="string"&&(b.delete(L.id),d.onPeerLeft?.(L.id));break;case"signal":typeof L.from=="string"&&d.onSignal?.(L.from,L.data);break}},T.onerror=()=>{if(!I&&!y&&k>1){y=!0,l=(l+1)%a.length,O(D,k-1).then(v,w);return}N(ie("signaling-unreachable",`cannot reach ${a[l]}`))},T.onclose=()=>{clearInterval(_),N(ie("signaling-closed","signalling closed before joining")),M&&!m&&p===T&&C()}}),E=D=>{p&&p.readyState===1?p.send(JSON.stringify(D)):m||S.push(D)},C=()=>{d.onDisconnect?.();let D=()=>{m||x(!0).catch(k=>{if(m||k&&(k.code==="room-full"||_s.includes(k.code))){d.onDisconnect?.(k);return}setTimeout(D,Math.max(K(g++,{baseMs:500,maxMs:15e3}),k&&k.retryMs||0))})};setTimeout(D,K(g++,{baseMs:300,maxMs:15e3}))};return{...await x(!1),send:(D,k)=>E({t:"signal",to:D,data:k}),leave:()=>{if(!m){m=!0,clearInterval(_);try{p&&p.readyState===1&&p.send(JSON.stringify({t:"leave"})),p&&p.close(1e3,"leave")}catch{}}}}}}}var sr=Object.freeze({azure:"#4da3ff",violet:"#9b7bff",magenta:"#ff4fa3",sunset:"#ff7a45",amber:"#ffc23d",lime:"#9be15d",mint:"#35e0b0",ice:"#8fe3ff"}),ys=r=>typeof r=="string"&&sr[r.toLowerCase()]||r,ws=Object.freeze({accent:"--dxr-accent",ink:"--dxr-ink",shell:"--dxr-shell",danger:"--dxr-danger",radius:"--dxr-radius",font:"--dxr-font"}),Ye=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 bs(r){let e={...Ye,...r&&typeof r=="object"?r:{}};return(t,i)=>{let n=typeof e[t]=="string"?e[t]:Ye[t]||t;if(i)for(let[s,o]of Object.entries(i))n=n.split(`{${s}}`).join(String(o));return n}}var vs="dxr-call-style",Ma=`
20
20
  .dxr-call-host{--dxr-accent:#4da3ff;--dxr-ink:#fff;--dxr-shell:rgba(16,17,22,.92);--dxr-danger:#ff5a5f;--dxr-radius:12px;
21
21
  --dxr-font:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
22
22
  display:flex;flex-direction:column;gap:12px;color:var(--dxr-ink);
@@ -97,4 +97,4 @@ output.color1 = getPickDepth();
97
97
  .dxr-call-depth{display:flex;align-items:center;gap:6px;padding:0 8px;font-size:12px;opacity:.9;}
98
98
  .dxr-call-depth input{width:110px;accent-color:var(--dxr-accent);}
99
99
  .dxr-call-note{font-size:12px;opacity:.65;}
100
- `;function xs(r=document){if(r.getElementById(vs))return;let e=r.createElement("style");e.id=vs,e.textContent=Ma,(r.head||r.documentElement).appendChild(e)}var ae=r=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${r}"/></svg>`,J={mic:ae("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:ae("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:ae("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:ae("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:ae("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:ae("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:ae("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 A(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 z=(r,e)=>r&&r.classList.toggle("dxr-call-hidden",!e);be();var Ms="[inline3d/call]",Ea="https://github.com/DisplayXR/displayxr-browser",Es=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"}),Ss=new Set;function Ra(r){Ss.has(r)||(Ss.add(r),console.warn(`${Ms} option \`${r}\` is deprecated (removed in 1.31) \u2014 use ${Es[r]}`))}function or(r={}){for(let g of Object.keys(Es))r[g]!==void 0&&Ra(g);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"&&!ge(l)){let g=je(l);if(!g)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=g}let c=r.liftOptions&&typeof r.liftOptions=="object"?{...r.liftOptions}:null,d=c&&c.max!==void 0?c.max:r.maxLifted;c&&delete c.max;let f=e.accent!==void 0?e.accent:r.accent,h={};for(let[g,_]of Object.entries(ws)){let b=g==="accent"?f:e[g];typeof b=="string"&&b?h[_]=g==="accent"?ys(b):b:typeof b=="number"&&g==="radius"&&(h[_]=`${b}px`)}let u=t.base!==void 0?t.base:r.inviteBase,p=t.updateUrl!==void 0?t.updateUrl:r.updateUrl,m=i.browserUrl!==void 0?i.browserUrl:r.browserUrl;return{room:l,signaling:r.signaling||Ce(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:yt(r.cursor,"@displayxr/inline3d/call"),mono3D:Le(r.mono3D),maxPeers:$e(r.maxPeers===void 0?me:r.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+d)&&d!==null&&d!==void 0?Math.max(0,Math.min(me,Math.floor(+d))):me,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 u=="string"?u:null,updateUrl:p===void 0?s:!!p},landing:{browserUrl:typeof m=="string"?m:Ea,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!r.debug,log:typeof r.log=="function"?r.log:r.debug?(g,_)=>console.log(`${Ms} ${g} ${JSON.stringify(_)}`):null,_liftImporter:typeof r._liftImporter=="function"?r._liftImporter:void 0}}var ec=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 lr="dxr-call:",Ca=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],ar="[inline3d/call] <dxr-call>",ke=r=>r!=null&&!/^(false|0|off|no)$/i.test(String(r).trim()),Rs=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},H=r=>r==null||String(r).trim()===""?void 0:String(r).trim();function cr(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",H(e("room")));let n=H(e("signaling"));n&&(t.signaling=Ce(n,H(e("key"))?{key:H(e("key"))}:{})),i("key",H(e("key"))),i("camera",H(e("camera"))),i("layout",H(e("layout"))),i("maxPeers",Rs(e("max-peers")));let s=H(e("ui"));ke(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),ke(e("auto-join"))&&(t.autoJoin=!0);let o=H(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),ke(e("no-audio"))&&(t.audio=!1),ke(e("no-self-view"))&&(t.selfView=!1),ke(e("no-auto-converge"))&&(t.autoConverge=!1),H(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:H(e("accent")),tileAspect:Rs(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),H(e("invite-base"))&&(t.invite={base:H(e("invite-base"))}),H(e("browser-url"))&&(t.landing={browserUrl:H(e("browser-url"))}),ke(e("debug"))&&(t.debug=!0),t}var ka=typeof HTMLElement=="function"?HTMLElement:class{},Te=class r extends ka{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={...cr(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||r.mount||hr;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=Ca.map(s=>n.on(s,o=>this._dispatch(s,o))),this._off.push(n.on("error",s=>console.warn(`${ar} ${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(`${ar} 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(lr+e,{detail:t,bubbles:!0,composed:!0}))}};function jt(r="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(r);return t?(t!==Te&&console.warn(`${ar} <${r}> is already defined by another class; leaving it`),!1):(e.define(r,Te),!0)}var Z="[inline3d/call]",Ta=2e3,Oa=2500,Da=500,ur=.02,Pa=4,Aa=2,La=200,Cs=240,Ia=66,Fa=new Set(["I420","I420A","I422","I444","NV12"]);async function Os(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=or(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 dr(r,e,i);return await n._init(),n.handle}async function hr(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 rt(i.wallOptions);return Os(n,r,i)}var dr=class{constructor(e,t,i){this.o=i,this.t=bs(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=qr(),this.room=i.room==="auto"?je(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=_i(di),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=Ut(),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(`${Z} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${Z} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${Z} ${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,u)=>this.log(h,u),s=null,o=null,a=Ft(e)?e:null;try{if(s=a||await Qi({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 u=h.code==="camera-busy";if(this.error(u?"camera-busy":h.code||"no-camera",u?`${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=u?"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 tn({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 d=new MediaStream([c,l].filter(Boolean)),f=this.local;return this.local={stream:d,cam:s,camStream:s?s.stream:null,video:s?s.video:null,videoTrack:c,audioTrack:l,format:s?s.format:"mono",width:s?s.width:0,height:s?s.height:0,calibration:s?s.calibration:{},owned:s?s.owned&&s!==a:!1,label:s?s.label:"",skipped:s?s.skipped:o?.skipped||[]},s&&s!==f?.cam&&(this._camEndedOff?.(),this._camEndedOff=s.on("ended",()=>{this.local?.cam===s&&(this.local.videoTrack=null,this.camStatus="none",this.error("no-camera",'the camera ended (revoked, unplugged, or taken by another app). Audio-only until "Retry camera".'),this.transport?.broadcast(this.stateMsg()),this._refreshSelf(),this._refreshBar())})),this.log("camera",{format:this.local.format,width:this.local.width,height:this.local.height,label:this.local.label,skipped:this.local.skipped.length}),f&&f.owned&&f.cam&&f.cam!==s&&f.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return mi({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=fi(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",lt(location.href,this.room))}catch{}this._setState("joining");let e=new He({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 zt(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 zt(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()},Oa))}_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=pi(t);if(n)return i.setHello(n);let s=gi(t);if(s)return i.setHint(s);let o=Yr(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return lt(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=gi({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=wi(),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 rt()}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)},K(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(`${Z} 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=Ht(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(n=>(this.liftApi=n,n.lift?(this.liftPool=Vt({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(`${Z} 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),Da)}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 d={};c.forEach(u=>{u.type==="codec"&&(d[u.id]=u.mimeType)});let f={in:null,out:null};c.forEach(u=>{if(u.type==="inbound-rtp"&&u.kind==="audio"&&typeof u.audioLevel=="number"&&(a.level=Math.max(u.audioLevel,(a.level||0)*.6)),u.type==="media-source"&&u.kind==="audio"&&typeof u.audioLevel=="number"&&(i=Math.max(i,u.audioLevel)),!!e){if(u.type==="inbound-rtp"&&u.kind==="video"){let p=a._prevIn;f.in={width:u.frameWidth||0,height:u.frameHeight||0,fps:u.framesPerSecond||0,codec:d[u.codecId]||null,kbps:p?Math.round((u.bytesReceived-p.bytes)*8/(u.timestamp-p.t)):null,dropped:u.framesDropped||0,decoder:u.decoderImplementation||null},a._prevIn={bytes:u.bytesReceived,t:u.timestamp}}else if(u.type==="outbound-rtp"&&u.kind==="video"){let p=a._prevOut;f.out={width:u.frameWidth||0,height:u.frameHeight||0,fps:u.framesPerSecond||0,codec:d[u.codecId]||null,kbps:p?Math.round((u.bytesSent-p.bytes)*8/(u.timestamp-p.t)):null,limitation:u.qualityLimitationReason||null,encoder:u.encoderImplementation||null},a._prevOut={bytes:u.bytesSent,t:u.timestamp}}}}),e&&(f.in||f.out)&&(a.quality=f,this.emit("quality",{id:o,...f}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>ur||a.remote.speaking),h>ur&&(!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>ur;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;xs(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=A("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[A("span",{text:t("banner2D")}),A("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=A("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=A("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=A("div",{class:"dxr-call-self",part:"self"}),i.bar=A("div",{class:"dxr-call-bar",part:"bar"}),i.foot=A("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=A("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||z(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new fr(this,i.selfSlot):z(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(n,s,o,a="")=>A("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":n,title:n,html:s,onclick:o});e.mic=i(t("mute"),J.mic,()=>this.mute()),e.cam=i(t("cameraOff"),J.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=A("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"),J.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),J.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,A("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?J.micOff:J.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?J.camOff:J.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=A("input",{type:"text",readOnly:!0,value:n,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=A("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=A("canvas",{"aria-label":s("qrLabel"),role:"img"});try{ms(l,n,{px:4})}catch{l.style.display="none"}e.append(A("h3",{text:t}),A("p",{text:i}),A("div",{class:"dxr-call-invite"},[A("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),z(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),z(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,d]of this.tiles)d.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){z(a,!0),a.replaceChildren();let c=this.local,d=!!this.room,f=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(d?"lobbyJoinTitle":"lobbyStartTitle"),h={width:c?.width||0,height:c?.height||0},u=this.camStatus==="busy"?i("kindBusy"):!c||!c.videoTrack?i("kindNone"):c.format==="sbs"?i("kindSbs",h):i("kindMono",h),p=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:u})}${this._liftHint()?` ${this._liftHint()}`:""}`,m=A("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(d?"join":"start")});m.addEventListener("click",()=>this.join().catch(()=>{}));let g=A("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(g),g.addEventListener("change",()=>this.setCamera(g.value).catch(b=>this.error("camera-failed",b.message,b)));let _=!c||!c.videoTrack?A("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;_?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(A("h3",{text:f}),A("p",{text:p}),A("div",{class:"dxr-call-row"},[this.state==="full"?null:m,_,g]))}else this.state==="in-call"&&s===0?(z(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(z(a,!0),a.replaceChildren(A("p",{text:i("joining")}))):z(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),z(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:ui,wire:at,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)=>A("option",{value:n.deviceId,text:n.label||`Camera ${s+1}`}))),i&&(e.value=i),z(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(`${Z} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${Z} 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(`${Z} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function Na(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 ks(r,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Na(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=q(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 zt=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=Ne(),this.autoTrack=ft(),this.autoFocus=Ue(),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=_i(di),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=A("canvas"),this.cover=A("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=A("div",{class:"dxr-call-badge",part:"badge"}),this.plate=A("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=A("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=A("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,A("div",{class:"dxr-call-talk"})]),e.o.ui||z(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(Ki(),Yi)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return yi(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())},Ta)}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||"",z(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(A("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",J.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"}:vi({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(),z(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(z(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++>=Aa)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},K(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++>=Pa)return;let e=K(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(z(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||ks(this.canvas,this.video):ks(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}=Fe(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 d=this.conv.step(n),f=l.getContext("2d"),h=[];for(let u of[0,1]){let p=h[u]=q(n,i,s,d,u);f.drawImage(e,u*n+p.sx,p.sy,p.sw,p.sh,u*o,0,o,a)}this.cursor&&this.cursor.draw(f,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?Ia:La))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&Fa.has(h.format)){this.autoPending=!0;let u=this.autoGen,p=h.visibleRect?h.visibleRect.width:h.displayWidth,m=h.visibleRect?h.visibleRect.height:h.displayHeight,g=new Uint8Array(h.allocationSize());h.copyTo(g).then(_=>{if(u!==this.autoGen)return;let b=performance.now(),S=Math.max(1,Math.ceil(p/2/Cs)),x=nn(g,_[0].offset,_[0].stride,p,m,S);this._applyMeasurement(x.img,x.w,x.h,x.w/p,s,performance.now()-b,"videoframe")}).catch(()=>{u===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,Cs/(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 d=c.getContext("2d",{willReadFrequently:!0}),f=null;try{d.drawImage(e,0,0,a,l),f=dt(d.getImageData(0,0,a,l).data,a*l)}catch{f=null}this._applyMeasurement(f,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,d=this.autoTrack.push(c?c.d/n:null);this.conv.measuredPx=d,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(d*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()}},fr=class{constructor(e,t){this.call=e,this.canvas=A("canvas"),this.badge=A("div",{class:"dxr-call-badge",part:"badge"}),this.plate=A("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=A("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=A("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,A("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"):"",z(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=er(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(A("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)}},ja="1.31",Ts=new Set;function F(r,e,t){let i=()=>{Ts.has(r)||(Ts.add(r),console.warn(`${Z} \`${r}\` is internal and leaves '@displayxr/inline3d/call' in ${ja} \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 vc=F("normalizeCallOptions","js/call/options.js",or),yc=F("newRoomId","js/call/wire.js",fi),wc=F("isValidRoomId","js/call/wire.js",ge),bc=F("buildInviteLink","js/call/wire.js",lt),xc=F("normalizeHello","js/call/wire.js",pi),Sc=F("makeHello","js/call/wire.js",mi),Mc=F("routeFor","js/call/wire.js",vi),Ec=F("badgeFor","js/call/wire.js",yi),Rc=F("createLiveGate","js/call/wire.js",wi),Cc=F("convergenceShiftPx","js/camera/converge.js",nt),kc=F("lowPass","js/camera/converge.js",ot),Tc=F("clampShift","js/camera/converge.js",st),Oc=F("eyeCropRect","js/camera/geometry.js",q),Dc=F("mirrorSwapOps","js/camera/geometry.js",pe),Pc=F("mirrorSwapPixels","js/camera/geometry.js",hi),Ac=F("maxBitrateKbps","js/call/wire.js",ct),Lc=F("measureFocusDisparity","js/camera/disparity.js",Si),Ic=F("preferVideoCodecs","js/call/sdp.js",We),Fc=F("sortCodecCapabilities","js/call/sdp.js",ht),Nc=F("VIDEO_CODEC_ORDER","js/call/sdp.js",ze),jc=F("MeshTransport","js/call/transport.js",He),zc=F("clampMaxPeers","js/call/transport.js",$e),Wc=F("qrEncode","js/call/qr.js",rr),Hc=F("roomKey","js/call/signaling.js",nr);var $c=F("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:Ye.unreachable,cameraBusy:Ye.cameraBusy})),Uc=F("CALL_ACCENTS","js/call/ui.js",sr),Vc=F("normalizeMono3D","js/call/lift.js",Le),Bc=F("resolveLift","js/call/lift.js",Ht),Xc=F("createLiftPool","js/call/lift.js",Vt),qc=F("createFrameWatch","js/call/lift.js",Ut),Gc=F("liftConvergenceFor","js/call/lift.js",Ae),Yc=F("liftPriorityFor","js/call/lift.js",Ke),Kc=F("setLiftPriority","js/call/lift.js",$t),Jc=F("defaultLiftSpecifier","js/call/lift.js",Wt),Zc=F("LIFT_PRIORITY","js/call/lift.js",Pe);jt();mr(()=>new URL("./lift.js",import.meta.url).href);export{lr as CALL_EVENT_PREFIX,cs as CAMERA_SDK,Nt as DXR_SIGNAL_DEFAULT,Te as DxrCallElement,Os as addCall,er as addCameraView,cr as attrsToOpts,$r as createInline3D,jt as defineCallElement,Ce as dxrSignaling,Wr as inline3DAvailable,Ft as isStereoCamera,hr as mountCall,Qi as openCamera,je as parseInviteLink,Ci as parseStereoXmp,pn as readJpegStereoMeta,ki as readJpegXmp,bn as readWebmStereoMeta,rt as sharedInline3D,It as suggestedName};
100
+ `;function xs(r=document){if(r.getElementById(vs))return;let e=r.createElement("style");e.id=vs,e.textContent=Ma,(r.head||r.documentElement).appendChild(e)}var ae=r=>`<svg viewBox="0 0 24 24" aria-hidden="true"><path d="${r}"/></svg>`,J={mic:ae("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:ae("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:ae("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:ae("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:ae("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:ae("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:ae("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 A(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 z=(r,e)=>r&&r.classList.toggle("dxr-call-hidden",!e);be();var Ms="[inline3d/call]",Ea="https://github.com/DisplayXR/displayxr-browser",Es=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"}),Ss=new Set;function Ra(r){Ss.has(r)||(Ss.add(r),console.warn(`${Ms} option \`${r}\` is deprecated (removed in 1.31) \u2014 use ${Es[r]}`))}function or(r={}){for(let g of Object.keys(Es))r[g]!==void 0&&Ra(g);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"&&!ge(l)){let g=je(l);if(!g)throw new Error(`@displayxr/inline3d/call: room "${l}" is not a valid room id (16-64 base64url chars) or invite link`);l=g}let c=r.liftOptions&&typeof r.liftOptions=="object"?{...r.liftOptions}:null,d=c&&c.max!==void 0?c.max:r.maxLifted;c&&delete c.max;let f=e.accent!==void 0?e.accent:r.accent,h={};for(let[g,_]of Object.entries(ws)){let b=g==="accent"?f:e[g];typeof b=="string"&&b?h[_]=g==="accent"?ys(b):b:typeof b=="number"&&g==="radius"&&(h[_]=`${b}px`)}let u=t.base!==void 0?t.base:r.inviteBase,p=t.updateUrl!==void 0?t.updateUrl:r.updateUrl,m=i.browserUrl!==void 0?i.browserUrl:r.browserUrl;return{room:l,signaling:r.signaling||Ce(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:yt(r.cursor,"@displayxr/inline3d/call"),mono3D:Le(r.mono3D),maxPeers:$e(r.maxPeers===void 0?me:r.maxPeers),liftOptions:c&&Object.keys(c).length?c:null,maxLifted:Number.isFinite(+d)&&d!==null&&d!==void 0?Math.max(0,Math.min(me,Math.floor(+d))):me,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 u=="string"?u:null,updateUrl:p===void 0?s:!!p},landing:{browserUrl:typeof m=="string"?m:Ea,allow2D:i.allow2D===void 0?!0:!!i.allow2D},debug:!!r.debug,log:typeof r.log=="function"?r.log:r.debug?(g,_)=>console.log(`${Ms} ${g} ${JSON.stringify(_)}`):null,_liftImporter:typeof r._liftImporter=="function"?r._liftImporter:void 0}}var ec=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 lr="dxr-call:",Ca=["joined","left","peer","peerleft","state","display","speaker","quality","error","warning"],ar="[inline3d/call] <dxr-call>",ke=r=>r!=null&&!/^(false|0|off|no)$/i.test(String(r).trim()),Rs=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},H=r=>r==null||String(r).trim()===""?void 0:String(r).trim();function cr(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",H(e("room")));let n=H(e("signaling"));n&&(t.signaling=Ce(n,H(e("key"))?{key:H(e("key"))}:{})),i("key",H(e("key"))),i("camera",H(e("camera"))),i("layout",H(e("layout"))),i("maxPeers",Rs(e("max-peers")));let s=H(e("ui"));ke(e("no-ui"))?t.ui=!1:s==="tiles"&&(t.ui="tiles"),ke(e("auto-join"))&&(t.autoJoin=!0);let o=H(e("mono3d"));o&&/^(off|false|0|no)$/i.test(o)&&(t.mono3D="off"),ke(e("no-audio"))&&(t.audio=!1),ke(e("no-self-view"))&&(t.selfView=!1),ke(e("no-auto-converge"))&&(t.autoConverge=!1),H(e("cursor"))==="depth"&&(t.cursor="depth");let a={accent:H(e("accent")),tileAspect:Rs(e("tile-aspect"))};return(a.accent!==void 0||a.tileAspect!==void 0)&&(t.theme=Object.fromEntries(Object.entries(a).filter(([,l])=>l!==void 0))),H(e("invite-base"))&&(t.invite={base:H(e("invite-base"))}),H(e("browser-url"))&&(t.landing={browserUrl:H(e("browser-url"))}),ke(e("debug"))&&(t.debug=!0),t}var ka=typeof HTMLElement=="function"?HTMLElement:class{},Te=class r extends ka{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={...cr(this),...this.options&&typeof this.options=="object"?this.options:{}},i=this.constructor.mount||r.mount||hr;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=Ca.map(s=>n.on(s,o=>this._dispatch(s,o))),this._off.push(n.on("error",s=>console.warn(`${ar} ${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(`${ar} 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(lr+e,{detail:t,bubbles:!0,composed:!0}))}};function jt(r="dxr-call",e=globalThis.customElements){if(!e||typeof e.define!="function")return!1;let t=e.get(r);return t?(t!==Te&&console.warn(`${ar} <${r}> is already defined by another class; leaving it`),!1):(e.define(r,Te),!0)}var Z="[inline3d/call]",Ta=2e3,Oa=2500,Da=500,ur=.02,Pa=4,Aa=2,La=200,Cs=240,Ia=66,Fa=new Set(["I420","I420A","I422","I444","NV12"]);async function Os(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=or(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 dr(r,e,i);return await n._init(),n.handle}async function hr(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 rt(i.wallOptions);return Os(n,r,i)}var dr=class{constructor(e,t,i){this.o=i,this.t=bs(i.strings),this.container=t,this.wall=e||null,this.wallLive=!!(e&&e.supported),this.weaveLive=!1,this.camStatus="pending",this.id=qr(),this.room=i.room==="auto"?je(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=_i(di),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=Ut(),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(`${Z} '${e}' listener threw`,s)}}error(e,t,i){this.log("error",{code:e,message:t}),this.listeners.get("error")?.size||console.warn(`${Z} ${e}: ${t}`),this.emit("error",{code:e,message:t,error:i||null})}warning(e,t){this.log("warning",{code:e,message:t}),console.warn(`${Z} ${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,u)=>this.log(h,u),s=null,o=null,a=Ft(e)?e:null;try{if(s=a||await Qi({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 u=h.code==="camera-busy";if(this.error(u?"camera-busy":h.code||"no-camera",u?`${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=u?"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 tn({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 d=new MediaStream([c,l].filter(Boolean)),f=this.local;return this.local={stream:d,cam:s,camStream:s?s.stream:null,video:s?s.video:null,videoTrack:c,audioTrack:l,format:s?s.format:"mono",width:s?s.width:0,height:s?s.height:0,calibration:s?s.calibration:{},owned:s?s.owned&&s!==a:!1,label:s?s.label:"",skipped:s?s.skipped:o?.skipped||[]},s&&s!==f?.cam&&(this._camEndedOff?.(),this._camEndedOff=s.on("ended",()=>{this.local?.cam===s&&(this.local.videoTrack=null,this.camStatus="none",this.error("no-camera",'the camera ended (revoked, unplugged, or taken by another app). Audio-only until "Retry camera".'),this.transport?.broadcast(this.stateMsg()),this._refreshSelf(),this._refreshBar())})),this.log("camera",{format:this.local.format,width:this.local.width,height:this.local.height,label:this.local.label,skipped:this.local.skipped.length}),f&&f.owned&&f.cam&&f.cam!==s&&f.cam.close(),this._refreshSelf(),this._refreshLobby(),this.local}hello(){let e=this.local||{};return mi({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=fi(),this.log("room-created",{})),this.o.invite.updateUrl&&globalThis.history&&globalThis.location)try{history.replaceState(history.state,"",lt(location.href,this.room))}catch{}this._setState("joining");let e=new He({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 zt(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 zt(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()},Oa))}_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=pi(t);if(n)return i.setHello(n);let s=gi(t);if(s)return i.setHint(s);let o=Yr(t);if(o)return i.setRemoteState(o)}inviteLink(){if(!this.room)return null;let e=this.o.invite.base||(globalThis.location?location.href:"");return lt(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=gi({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=wi(),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 rt()}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)},K(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(`${Z} 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=Ht(this.mono3D,{log:e,capsOpts:i,...this.o._liftImporter?{importer:this.o._liftImporter}:{}}).then(n=>(this.liftApi=n,n.lift?(this.liftPool=Vt({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(`${Z} 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),Da)}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 d={};c.forEach(u=>{u.type==="codec"&&(d[u.id]=u.mimeType)});let f={in:null,out:null};c.forEach(u=>{if(u.type==="inbound-rtp"&&u.kind==="audio"&&typeof u.audioLevel=="number"&&(a.level=Math.max(u.audioLevel,(a.level||0)*.6)),u.type==="media-source"&&u.kind==="audio"&&typeof u.audioLevel=="number"&&(i=Math.max(i,u.audioLevel)),!!e){if(u.type==="inbound-rtp"&&u.kind==="video"){let p=a._prevIn;f.in={width:u.frameWidth||0,height:u.frameHeight||0,fps:u.framesPerSecond||0,codec:d[u.codecId]||null,kbps:p?Math.round((u.bytesReceived-p.bytes)*8/(u.timestamp-p.t)):null,dropped:u.framesDropped||0,decoder:u.decoderImplementation||null},a._prevIn={bytes:u.bytesReceived,t:u.timestamp}}else if(u.type==="outbound-rtp"&&u.kind==="video"){let p=a._prevOut;f.out={width:u.frameWidth||0,height:u.frameHeight||0,fps:u.framesPerSecond||0,codec:d[u.codecId]||null,kbps:p?Math.round((u.bytesSent-p.bytes)*8/(u.timestamp-p.t)):null,limitation:u.qualityLimitationReason||null,encoder:u.encoderImplementation||null},a._prevOut={bytes:u.bytesSent,t:u.timestamp}}}}),e&&(f.in||f.out)&&(a.quality=f,this.emit("quality",{id:o,...f}));let h=a.remote.muted?0:a.level||0;a.setSpeaking(h>ur||a.remote.speaking),h>ur&&(!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>ur;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;xs(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=A("div",{class:"dxr-call-banner dxr-call-hidden",part:"banner"},[A("span",{text:t("banner2D")}),A("a",{href:this.o.landing.browserUrl,target:"_blank",rel:"noopener",text:t("bannerLink")})]),i.grid=A("div",{class:"dxr-call-grid",part:"grid","data-layout":this.o.layout,"data-n":"0"}),i.panel=A("div",{class:"dxr-call-panel dxr-call-hidden",part:"lobby"}),i.selfSlot=A("div",{class:"dxr-call-self",part:"self"}),i.bar=A("div",{class:"dxr-call-bar",part:"bar"}),i.foot=A("div",{class:"dxr-call-foot"},[i.selfSlot,i.bar]),i.invite=A("div",{class:"dxr-call-panel dxr-call-hidden",part:"invite"}),this.o.chrome||z(i.bar,!1),e.append(i.banner,i.panel,i.grid,i.invite,i.foot),this.o.selfView?this.self=new fr(this,i.selfSlot):z(i.selfSlot,!1),this.o.chrome&&this._buildBar()}_buildBar(){let e=this.ui,t=this.t,i=(n,s,o,a="")=>A("button",{class:`dxr-call-ib ${a}`,type:"button","aria-label":n,title:n,html:s,onclick:o});e.mic=i(t("mute"),J.mic,()=>this.mute()),e.cam=i(t("cameraOff"),J.cam,()=>this.local?.videoTrack?this.setCameraOff():this.retryCamera().catch(()=>{})),e.depth=A("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"),J.link,()=>{this._showInvite=!this._showInvite,this._layout()}),e.leave=i(t("leave"),J.leave,()=>this.leave(),"dxr-call-ib--leave"),e.bar.append(e.mic,e.cam,A("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?J.micOff:J.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?J.camOff:J.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=A("input",{type:"text",readOnly:!0,value:n,"aria-label":s("inviteLink")});o.addEventListener("focus",()=>o.select());let a=A("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=A("canvas",{"aria-label":s("qrLabel"),role:"img"});try{ms(l,n,{px:4})}catch{l.style.display="none"}e.append(A("h3",{text:t}),A("p",{text:i}),A("div",{class:"dxr-call-invite"},[A("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),z(e.banner,this.o.chrome&&!this.woven);let s=this.tiles.size;e.grid.dataset.n=String(Math.min(s,4)),z(e.grid,s>0&&this.state!=="left");let o=this.o.layout==="speaker"?this.speakerId||[...this.tiles.keys()][0]:null;for(let[c,d]of this.tiles)d.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){z(a,!0),a.replaceChildren();let c=this.local,d=!!this.room,f=this.state==="full"?i("lobbyFullTitle"):this.state==="left"?i("lobbyLeftTitle"):i(d?"lobbyJoinTitle":"lobbyStartTitle"),h={width:c?.width||0,height:c?.height||0},u=this.camStatus==="busy"?i("kindBusy"):!c||!c.videoTrack?i("kindNone"):c.format==="sbs"?i("kindSbs",h):i("kindMono",h),p=this.state==="full"?i("lobbyFullText",{maxPeers:this.o.maxPeers}):`${i("lobbyText",{camera:c?.label||i("cameraDefault"),kind:u})}${this._liftHint()?` ${this._liftHint()}`:""}`,m=A("button",{class:"dxr-call-btn dxr-call-btn--primary",type:"button",text:this.state==="left"?i("rejoin"):i(d?"join":"start")});m.addEventListener("click",()=>this.join().catch(()=>{}));let g=A("select",{class:"dxr-call-select","aria-label":i("cameraSelect")});this._fillCameras(g),g.addEventListener("change",()=>this.setCamera(g.value).catch(b=>this.error("camera-failed",b.message,b)));let _=!c||!c.videoTrack?A("button",{class:"dxr-call-btn",type:"button",text:i("retryCamera")}):null;_?.addEventListener("click",()=>this.retryCamera().catch(()=>{})),a.append(A("h3",{text:f}),A("p",{text:p}),A("div",{class:"dxr-call-row"},[this.state==="full"?null:m,_,g]))}else this.state==="in-call"&&s===0?(z(a,!0),this._renderInvite(a,i("waitingTitle"),i("waitingText"))):this.state==="joining"?(z(a,!0),a.replaceChildren(A("p",{text:i("joining")}))):z(a,!1);let l=this.state==="in-call"&&s>0&&this._showInvite;l&&!e.invite.childElementCount&&this._renderInvite(e.invite,i("inviteTitle"),i("inviteText")),z(e.invite,l),l||e.invite.replaceChildren(),e.inviteBtn?.setAttribute("aria-pressed",String(!!l))}diagnostics(){let e=this.local;return{sdk:ui,wire:at,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)=>A("option",{value:n.deviceId,text:n.label||`Camera ${s+1}`}))),i&&(e.value=i),z(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(`${Z} on() takes a function`);if(s in t&&!e._eventWarned?.has(s)){(e._eventWarned||=new Set).add(s);let a=t[s];console.warn(`${Z} 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(`${Z} handle.${s} is deprecated (removed in 1.31) \u2014 use ${o}`)),a()}});return i}};function Na(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 ks(r,e,{eyeHalf:t=null,mirror:i=!1}={}){if(!Na(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=q(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 zt=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=Ne(),this.autoTrack=ft(),this.autoFocus=Ue(),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=_i(di),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=A("canvas"),this.cover=A("div",{class:"dxr-call-cover dxr-call-hidden"}),this.badge=A("div",{class:"dxr-call-badge",part:"badge"}),this.plate=A("div",{class:"dxr-call-state",part:"plate",text:e.t("connecting")}),this.stage=A("div",{class:"dxr-call-stage"},[this.canvas,this.cover,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=A("div",{class:"dxr-call-tile",part:"tile","data-dxr-peer":t,"data-peer":t},[this.stage,A("div",{class:"dxr-call-talk"})]),e.o.ui||z(this.badge,!1),e.ui.grid.appendChild(this.el),this._renderBadge(),this.cursor=null,e.o.cursor&&(e._pairCursorMod=e._pairCursorMod||Promise.resolve().then(()=>(Ki(),Yi)),e._pairCursorMod.then(i=>{this.destroyed||(this.cursor=new i.PairCursor(this.canvas,e.o.cursor))}))}display(){return yi(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())},Ta)}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||"",z(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(A("b",{text:i})),this.badge.dataset.route=this.route||"",this.remote.muted&&this.badge.insertAdjacentHTML("beforeend",J.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"}:vi({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(),z(this.cover,!0);let t=e.wall.addImage(this.canvas,this.convCanvas);this.handle=t,t.firstWoven?.then(i=>{this.handle===t&&(z(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++>=Aa)&&(clearTimeout(this.liftTimer),this.liftTimer=setTimeout(()=>{this.liftFailed=!1,this.reroute(!1)},K(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++>=Pa)return;let e=K(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(z(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||ks(this.canvas,this.video):ks(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}=Fe(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 d=this.conv.step(n),f=l.getContext("2d"),h=[];for(let u of[0,1]){let p=h[u]=q(n,i,s,d,u);f.drawImage(e,u*n+p.sx,p.sy,p.sw,p.sh,u*o,0,o,a)}this.cursor&&this.cursor.draw(f,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?Ia:La))return;if(this.autoAt=s,typeof VideoFrame=="function"){let h=null;try{h=new VideoFrame(e)}catch{h=null}if(h&&Fa.has(h.format)){this.autoPending=!0;let u=this.autoGen,p=h.visibleRect?h.visibleRect.width:h.displayWidth,m=h.visibleRect?h.visibleRect.height:h.displayHeight,g=new Uint8Array(h.allocationSize());h.copyTo(g).then(_=>{if(u!==this.autoGen)return;let b=performance.now(),S=Math.max(1,Math.ceil(p/2/Cs)),x=nn(g,_[0].offset,_[0].stride,p,m,S);this._applyMeasurement(x.img,x.w,x.h,x.w/p,s,performance.now()-b,"videoframe")}).catch(()=>{u===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,Cs/(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 d=c.getContext("2d",{willReadFrequently:!0}),f=null;try{d.drawImage(e,0,0,a,l),f=dt(d.getImageData(0,0,a,l).data,a*l)}catch{f=null}this._applyMeasurement(f,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,d=this.autoTrack.push(c?c.d/n:null);this.conv.measuredPx=d,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(d*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()}},fr=class{constructor(e,t){this.call=e,this.canvas=A("canvas"),this.badge=A("div",{class:"dxr-call-badge",part:"badge"}),this.plate=A("div",{class:"dxr-call-state dxr-call-hidden",part:"plate"}),this.stage=A("div",{class:"dxr-call-stage"},[this.canvas,this.badge,this.plate]),this.stage.style.aspectRatio=String(e.o.tileAspect),this.el=A("div",{class:"dxr-call-tile dxr-call-tile--self",part:"tile"},[this.stage,A("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"):"",z(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=er(n,this.canvas,i,{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(A("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)}},ja="1.31",Ts=new Set;function F(r,e,t){let i=()=>{Ts.has(r)||(Ts.add(r),console.warn(`${Z} \`${r}\` is internal and leaves '@displayxr/inline3d/call' in ${ja} \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 vc=F("normalizeCallOptions","js/call/options.js",or),yc=F("newRoomId","js/call/wire.js",fi),wc=F("isValidRoomId","js/call/wire.js",ge),bc=F("buildInviteLink","js/call/wire.js",lt),xc=F("normalizeHello","js/call/wire.js",pi),Sc=F("makeHello","js/call/wire.js",mi),Mc=F("routeFor","js/call/wire.js",vi),Ec=F("badgeFor","js/call/wire.js",yi),Rc=F("createLiveGate","js/call/wire.js",wi),Cc=F("convergenceShiftPx","js/camera/converge.js",nt),kc=F("lowPass","js/camera/converge.js",ot),Tc=F("clampShift","js/camera/converge.js",st),Oc=F("eyeCropRect","js/camera/geometry.js",q),Dc=F("mirrorSwapOps","js/camera/geometry.js",pe),Pc=F("mirrorSwapPixels","js/camera/geometry.js",hi),Ac=F("maxBitrateKbps","js/call/wire.js",ct),Lc=F("measureFocusDisparity","js/camera/disparity.js",Si),Ic=F("preferVideoCodecs","js/call/sdp.js",We),Fc=F("sortCodecCapabilities","js/call/sdp.js",ht),Nc=F("VIDEO_CODEC_ORDER","js/call/sdp.js",ze),jc=F("MeshTransport","js/call/transport.js",He),zc=F("clampMaxPeers","js/call/transport.js",$e),Wc=F("qrEncode","js/call/qr.js",rr),Hc=F("roomKey","js/call/signaling.js",nr);var $c=F("PLATE_TEXT","js/call/ui.js (CALL_STRINGS)",Object.freeze({unreachable:Ye.unreachable,cameraBusy:Ye.cameraBusy})),Uc=F("CALL_ACCENTS","js/call/ui.js",sr),Vc=F("normalizeMono3D","js/call/lift.js",Le),Bc=F("resolveLift","js/call/lift.js",Ht),Xc=F("createLiftPool","js/call/lift.js",Vt),qc=F("createFrameWatch","js/call/lift.js",Ut),Gc=F("liftConvergenceFor","js/call/lift.js",Ae),Yc=F("liftPriorityFor","js/call/lift.js",Ke),Kc=F("setLiftPriority","js/call/lift.js",$t),Jc=F("defaultLiftSpecifier","js/call/lift.js",Wt),Zc=F("LIFT_PRIORITY","js/call/lift.js",Pe);jt();mr(()=>new URL("./lift.js",import.meta.url).href);export{lr as CALL_EVENT_PREFIX,cs as CAMERA_SDK,Nt as DXR_SIGNAL_DEFAULT,Te as DxrCallElement,Os as addCall,er as addCameraView,cr as attrsToOpts,$r as createInline3D,jt as defineCallElement,Ce as dxrSignaling,Wr as inline3DAvailable,Ft as isStereoCamera,hr as mountCall,Qi as openCamera,je as parseInviteLink,Ci as parseStereoXmp,pn as readJpegStereoMeta,ki as readJpegXmp,bn as readWebmStereoMeta,rt as sharedInline3D,It as suggestedName};
@@ -25,8 +25,11 @@ on real panels; everything else about how your scene looks is your call.
25
25
  5. **Low contrast between the subject and what is behind it.** The display's crosstalk correction
26
26
  works only within the range of the image, so a bright edge on black ghosts first. A light or
27
27
  mid-tone, low-contrast background works best: a real texture or a soft gradient, not generated
28
- noise. A dark grey is the minimum, and pure black is the worst case; keep the subject's darkest
29
- faces above the background. Soften high-contrast detail far from the glass in the colours and
28
+ noise. A dark grey is the minimum (a bright orange beak still ghosts against it), and pure
29
+ black is the worst case; keep the subject's darkest faces above the background. In front of
30
+ the glass, contrast matters more than the depth number: the same pop-out read fine on a
31
+ mid-tone globe and ghosted on a dark one. Keep bright subjects off near-black backgrounds,
32
+ above all the ones that come closest. Soften high-contrast detail far from the glass in the colours and
30
33
  materials, not with fog, since camera-distance fog follows the viewer's head.
31
34
  6. **Text: flat HTML near the glass, at a readable size.** Text drawn in the 3D scene, especially
32
35
  white on dark, ghosts. Put titles, labels and values in HTML, or keep in-scene labels close to
@@ -39,9 +42,14 @@ on real panels; everything else about how your scene looks is your call.
39
42
  8. **No detail finer than a few pixels.** Thin lines, single-pixel stars and fine repeating
40
43
  patterns alias and shimmer as the head moves. Draw them thicker, softer or as sprites, and size
41
44
  textures to their surfaces instead of stretching them.
42
- 9. **A cover over the canvas must always come off.** If you hide the canvas until `firstWoven`,
43
- also remove the cover after a few seconds and if your setup throws. Otherwise a missed signal
44
- leaves the page with its UI and no scene.
45
+ 9. **A cover over the canvas must always come off, and only a lost layer means flat.** If you
46
+ hide the canvas until `firstWoven`, also remove the cover after a few seconds and if your setup
47
+ throws; otherwise a missed signal leaves the page with its UI and no scene. A `firstWoven` of
48
+ `woven: false` is not "no 3D here": drop the cover and keep drawing both eyes (the layer can
49
+ still join). Go flat only on `onLayerLost` or with no session. And never draw one full-width
50
+ flat picture into a canvas the browser is still weaving: it splits it, so each eye sees a
51
+ different half of the room. To show a flat picture on purpose, remove the scene first, or call
52
+ `setStereoEnabled(false)` and keep drawing every view you are given.
45
53
 
46
54
  The mechanics (one view per eye, CSS that breaks the weave, the 2D/3D switch) are in
47
55
  [woven-canvas-rules.md](woven-canvas-rules.md) and [authoring-inline-3d.md](authoring-inline-3d.md),
@@ -121,7 +121,7 @@ poster.remove(); // cut, never fade
121
121
  |---|---|---|
122
122
  | `woven: true`, `reason: 'woven'`, `confirmed: true` | the browser reported the layer woven (`XRDisplayLayer.wovenState`), after a real stereo frame | drop the cover |
123
123
  | `woven: true`, `reason: 'hold-elapsed'` | a browser without that report: the window has drawn a real stereo frame on a layer that has existed for `firstWovenHoldMs` (default **1200**, the browser's measured worst case) | drop the cover |
124
- | `woven: false`, `confirmed: true`, `reason` a withheld token (or `'pending'`) | the browser kept reporting the layer withheld for the whole safety cap (four holds, at least 4.8 s). The canvas is not taken flat | drop the cover, then read the token in §3: it names the page fix |
124
+ | `woven: false`, `confirmed: true`, `reason` a withheld token (or `'pending'`) | the browser kept reporting the layer withheld for the whole safety cap (four holds, at least 4.8 s). The canvas is not taken flat, and the layer can still join | drop the cover and **keep drawing both eyes**, then read the token in §3: it names the page fix. Do not switch to a flat full-width picture: the browser is still weaving the canvas and would give each eye a different half of it |
125
125
  | `woven: false`, `reason: 'layer-failed'` / `'session-ended'` / `'removed'` | this window will not weave. An image or video canvas has already been painted flat, and a scene's `onLayerLost` has already run | drop the cover onto the 2D fallback |
126
126
  | `woven: false`, `reason: 'unsupported'` (`addSplat` / `addModel` only) | no inline-3D session: the viewer is on its mono path | same |
127
127
 
@@ -1895,7 +1895,7 @@ class SelfTile {
1895
1895
  // onRouteChange: the view drops to its flat left eye by itself when the wall says the tile
1896
1896
  // will not weave (firstWoven → woven:false, web#131), and the badge must follow it.
1897
1897
  this.view = addCameraView(wall, this.canvas, cam, {
1898
- mirror: true,
1898
+ // mirror: unset — a selfie camera mirrors, a rear ('environment') camera does not.
1899
1899
  autoConverge: !!this.call.o.autoConverge, // the call option (default on) governs the self view too
1900
1900
  cursor: this.call.o.cursor || undefined, // and so does `cursor: 'depth'`
1901
1901
  aspect: this.call.o.tileAspect,
@@ -167,6 +167,20 @@ class StereoCamera {
167
167
  for (const t of this.stream.getVideoTracks()) t.addEventListener?.('ended', this._onEnded);
168
168
  }
169
169
 
170
+ /**
171
+ * Which way the camera faces, from the track's settings: 'user' (a selfie / front camera),
172
+ * 'environment' (a rear camera), 'left' / 'right', or null when the browser does not say (most
173
+ * desktop webcams).
174
+ */
175
+ get facing() {
176
+ try {
177
+ const f = this.stream.getVideoTracks()[0]?.getSettings?.().facingMode;
178
+ return typeof f === 'string' && f ? f : null;
179
+ } catch {
180
+ return null;
181
+ }
182
+ }
183
+
170
184
  /** Source width of ONE eye (the whole frame for mono). */
171
185
  get eyeWidth() {
172
186
  return this.format === 'sbs' ? this.width / 2 : this.width;
@@ -499,7 +513,9 @@ class CameraView {
499
513
  this.wall = wall || null;
500
514
  this.canvas = canvas;
501
515
  this.cam = cam;
502
- this.mirror = o.mirror === undefined ? true : !!o.mirror;
516
+ // A self view mirrors; a rear camera shows the world as it is. Unset: mirror unless the track
517
+ // says it faces the environment (an unknown facing is a webcam pointed at the viewer).
518
+ this.mirror = o.mirror === undefined ? cam.facing !== 'environment' : !!o.mirror;
503
519
  this.aspect = typeof o.aspect === 'number' && o.aspect > 0.3 && o.aspect < 4 ? o.aspect : 16 / 9;
504
520
  this.autoConverge = !!o.autoConverge;
505
521
  this.conv = createConvergence();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displayxr/inline3d",
3
- "version": "1.47.1",
3
+ "version": "1.47.3",
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",