@displayxr/inline3d 1.47.0 → 1.47.2

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,35 @@ 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.2 — 2026-10-30
9
+
10
+ ### Docs only — two more panel findings in the shipped guide
11
+
12
+ No code change. `docs/making-3d-look-right.md` and `docs/woven-canvas-rules.md` (both in the
13
+ package):
14
+
15
+ - **Rule 9:** a `firstWoven` of `woven: false` is not "no 3D here". Drop the cover and keep drawing
16
+ both eyes, since the layer can still join, and go flat only on `onLayerLost` or with no session.
17
+ Never draw one full-width flat picture into a canvas the browser is still weaving: each eye
18
+ would see a different half of it. To show a flat picture on purpose, remove the scene, or call
19
+ `setStereoEnabled(false)` and keep drawing every view.
20
+ - **Rule 5:** in front of the glass, contrast matters more than the depth number. Keep bright
21
+ subjects off near-black backgrounds, above all the ones that come closest; dark grey is the
22
+ minimum, not the target.
23
+
24
+ ## 1.47.1 — 2026-10-29
25
+
26
+ ### Fixed — a splat on a camera rig briefly declared convergence at infinity (`./splat`, PlayCanvas)
27
+
28
+ Touches the preview tier (`./splat` on PlayCanvas) only.
29
+
30
+ - When a camera-rig splat's focus sat at or behind its camera — in practice the first push, before
31
+ the first focus has landed — the adapter declared `convergence: 0` (infinity), which asks for
32
+ the whole scene in front of the glass, for one push. It now keeps the rig as declared until the
33
+ focus is in front of the camera. Seen on a panel as one such rig in the first 0.3–2 s of each
34
+ page of an app built on 1.47.0 (and silently in earlier versions); 1.47.0's one-time
35
+ convergence-0 warning is what surfaced it, and it no longer fires from the SDK's own rigs.
36
+
8
37
  ## 1.47.0 — 2026-10-29
9
38
 
10
39
  The look-right release: a short guide for people and coding agents (`docs/making-3d-look-right.md`,
package/dist/call.js CHANGED
@@ -1,4 +1,4 @@
1
- /* @displayxr/inline3d 1.47.0 — dist/call.js — Apache-2.0 — https://github.com/DisplayXR/displayxr-web */
1
+ /* @displayxr/inline3d 1.47.2 — 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
@@ -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
 
@@ -3983,6 +3983,10 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
3983
3983
  // three looks down −z; convergence is the focus's distance along that axis (the PLANE).
3984
3984
  const fwd = [-pose[8], -pose[9], -pose[10]];
3985
3985
  const d = (f.x - pose[12]) * fwd[0] + (f.y - pose[13]) * fwd[1] + (f.z - pose[14]) * fwd[2];
3986
+ // A focus at or behind the camera has no zero-disparity plane in front of it: a transient
3987
+ // before the first focus lands, or a focus moved behind the camera. Keep the rig as declared;
3988
+ // convergence at infinity would put the whole scene in front of the glass.
3989
+ if (!(d > 0)) return;
3986
3990
  if (!force && Math.abs(d - lastConvergence) < 1e-3) return;
3987
3991
  lastConvergence = d;
3988
3992
  out.rig.convergence = d;
@@ -3996,7 +4000,7 @@ export function attachPlayCanvasSplat(out, wall, canvas, src, opts, pending = []
3996
4000
  fov: viewer.mono.fov,
3997
4001
  },
3998
4002
  {
3999
- convergence: d > 0 ? d : 0,
4003
+ convergence: d,
4000
4004
  ipdFactor: out.rig.ipdFactor,
4001
4005
  parallaxFactor: out.rig.parallaxFactor,
4002
4006
  out: camRigObj,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@displayxr/inline3d",
3
- "version": "1.47.0",
3
+ "version": "1.47.2",
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",