ldr 0.34.0 → 0.34.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.
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/spec.ts
2
2
  var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
3
3
  var COLOUR_ID_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
4
4
  var namedCodes = new Map;
@@ -833,7 +833,7 @@ function fileStepViews(f) {
833
833
  viewMemo.set(f, out);
834
834
  return out;
835
835
  }
836
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/model.ts
836
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/model.ts
837
837
  class ModelLimitError extends Error {
838
838
  limit;
839
839
  code = "ldr-model-limit";
@@ -1274,7 +1274,7 @@ function blendedColourHex(code) {
1274
1274
  const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
1275
1275
  return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
1276
1276
  }
1277
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/instructions.ts
1277
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/instructions.ts
1278
1278
  var MIN_VIS = 0.5;
1279
1279
  var REORIENT = 0.35;
1280
1280
  var deg = Math.PI / 180;
@@ -1642,10 +1642,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1642
1642
  }
1643
1643
  };
1644
1644
  }
1645
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/render.ts
1645
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/render.ts
1646
1646
  import * as THREE from "three";
1647
1647
 
1648
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/pack-io.ts
1648
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/pack-io.ts
1649
1649
  import { decompress } from "fzstd";
1650
1650
  async function decompressPack(data) {
1651
1651
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1668,7 +1668,7 @@ function decodePack(buf) {
1668
1668
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1669
1669
  }
1670
1670
 
1671
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/cull.ts
1671
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/cull.ts
1672
1672
  var upright = (m, o = 0) => Math.abs(m[o + 7] - 1) < 0.001 && Math.abs(m[o + 4]) < 0.001 && Math.abs(m[o + 10]) < 0.001;
1673
1673
  var prepCache = new WeakMap;
1674
1674
  var lastH = null;
@@ -2259,7 +2259,7 @@ function precomputeCull(instances, H, useTex = true) {
2259
2259
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
2260
2260
  }
2261
2261
 
2262
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/render.ts
2262
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/render.ts
2263
2263
  async function loadPack(url) {
2264
2264
  const res = await fetch(url);
2265
2265
  if (!res.ok)
@@ -4702,7 +4702,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
4702
4702
  await new Promise((r) => setTimeout(r, 0));
4703
4703
  }
4704
4704
  }
4705
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/scene.ts
4705
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/scene.ts
4706
4706
  import * as THREE2 from "three";
4707
4707
  var _box = new THREE2.Box3;
4708
4708
  var _m4 = new THREE2.Matrix4;
@@ -5057,10 +5057,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5057
5057
  return finish();
5058
5058
  })();
5059
5059
  }
5060
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/parts-cdn.ts
5060
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/parts-cdn.ts
5061
5061
  import { decompress as decompress2 } from "fzstd";
5062
5062
 
5063
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/embedded.ts
5063
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/embedded.ts
5064
5064
  function splitFiles(text, fallback) {
5065
5065
  const files = new Map;
5066
5066
  let cur = null, saw = false, skip = false;
@@ -5138,7 +5138,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
5138
5138
  return out;
5139
5139
  }
5140
5140
 
5141
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/parts-cdn.ts
5141
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/parts-cdn.ts
5142
5142
  var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
5143
5143
  var indexCache = new Map;
5144
5144
  var shardCache = new Map;
@@ -5399,10 +5399,10 @@ async function prepareModel(source, o = {}) {
5399
5399
  return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
5400
5400
  }
5401
5401
 
5402
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/load-worker.gen.ts
5402
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/load-worker.gen.ts
5403
5403
  var load_worker_gen_default = 'var nn=ArrayBuffer,W=Uint8Array,ze=Uint16Array,rn=Int16Array;var $e=Int32Array,Ye=function(e,t,n){if(W.prototype.slice)return W.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new W(n-t);return r.set(e.subarray(t,n)),r},Re=function(e,t,n,r){if(W.prototype.fill)return W.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},sn=function(e,t,n,r){if(W.prototype.copyWithin)return W.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var on=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],Z=function(e,t,n){var r=Error(t||on[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,Z);if(!n)throw r;return r},bt=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},an=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},ln=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)Z(0);var a=6-s,u=i==3?4:i,l=bt(e,a,u);a+=u;var f=c?1<<c:s,h=bt(e,a,f)+(c==1&&256),g=h;if(!s){var p=1<<10+(e[5]>>3);g=p+(p>>3)*(e[5]&7)}if(g>2145386496)Z(1);var m=new W((t==1?h||g:t?0:g)+12);return m[0]=1,m[4]=4,m[8]=8,{b:a+f,y:0,l:0,d:l,w:t&&t!=1?t:m.subarray(12),e:g,o:new $e(m.buffer,0,3),u:h,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return an(e,4)+8;Z(0)},Se=function(e){var t=0;for(;1<<t<=e;++t);return t-1},Be=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)Z(3);var o=1<<s,i=o,c=-1,a=-1,u=-1,l=o,f=new nn(512+(o<<2)),h=new rn(f,0,256),g=new ze(f,0,256),p=new ze(f,512,o),m=512+(o<<1),A=new W(f,m,o),x=new W(f,m+o);while(c<255&&i>0){var d=Se(i+1),w=r>>3,b=(1<<d+1)-1,M=(e[w]|e[w+1]<<8|e[w+2]<<16)>>(r&7)&b,k=(1<<d)-1,N=b-i-1,P=M&k;if(P<N)r+=d,M=P;else if(r+=d+1,M>k)M-=N;if(h[++c]=--M,M==-1)i+=M,A[--l]=c;else i-=M;if(!M)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,c+=a}while(a==3)}if(c>255||i)Z(0);var y=0,B=(o>>1)+(o>>3)+3,C=o-1;for(var I=0;I<=c;++I){var R=h[I];if(R<1){g[I]=-R;continue}for(u=0;u<R;++u){A[y]=I;do y=y+B&C;while(y>=l)}}if(y)Z(0);for(u=0;u<o;++u){var S=g[A[u]]++,V=x[u]=s-Se(S);p[u]=(S<<V)-o}return[r+7>>3,{b:s,s:A,n:x,t:p}]},cn=function(e,t){var n=0,r=-1,s=new W(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),a=new ze(s.buffer,268);if(o<128){var u=Be(e,t+1,6),l=u[0],f=u[1];t+=o;var h=l<<3,g=e[t];if(!g)Z(0);var p=0,m=0,A=f.b,x=A,d=(++t<<3)-8+Se(g);for(;;){if(d-=A,d<h)break;var w=d>>3;if(p+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<A)-1,i[++r]=f.s[p],d-=x,d<h)break;w=d>>3,m+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<x)-1,i[++r]=f.s[m],A=f.n[p],p=f.t[p],x=f.n[m],m=f.t[m]}if(++r>255)Z(0)}else{r=o-127;for(;n<r;n+=2){var b=e[++t];i[n]=b>>4,i[n+1]=b&15}++t}var M=0;for(n=0;n<r;++n){var k=i[n];if(k>11)Z(0);M+=k&&1<<k-1}var N=Se(M)+1,P=1<<N,D=P-M;if(D&D-1)Z(0);i[r++]=Se(D)+1;for(n=0;n<r;++n){var k=i[n];++c[i[n]=k&&N+1-k]}var y=new W(P<<1),B=y.subarray(0,P),C=y.subarray(P);a[N]=0;for(n=N;n>0;--n){var I=a[n];Re(C,n,I,a[n-1]=I+c[n]*(1<<N-n))}if(a[0]!=P)Z(0);for(n=0;n<r;++n){var R=i[n];if(R){var S=a[R];Re(B,n,S,a[R]=S+(1<<N-R))}}return[t,{n:C,b:N,s:B}]},un=Be(new W([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],fn=Be(new W([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],pn=Be(new W([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],yt=function(e,t){var n=e.length,r=new $e(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Je=new W(new $e([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),mn=yt(Je,0),Qe=new W(new $e([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),hn=yt(Qe,3),Fe=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)Z(0);var a=0,u=n.b,l=(r<<3)-8+Se(o)-u,f=-1;for(;l>c&&f<s;){var h=l>>3,g=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(l&7);a=(a<<u|g)&i,t[++f]=n.s[a],l-=u=n.n[a]}if(l!=c||f+1!=s)Z(0)},gn=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;Fe(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),Fe(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),Fe(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),Fe(e.subarray(r),t.subarray(c),n)},dn=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,a=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return Re(n,e[s],t.y,t.y+=c),n;return Re(new W(c),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=c,n;return Ye(e,s,a)}if(i==2){var u=e[s],l=u&3,f=u>>2&3,h=u>>4,g=0,p=0;if(l<2)if(f&1)h|=e[++s]<<4|(f&2&&e[++s]<<12);else h=u>>3;else if(p=f,f<2)h|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(f==2)h|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var m=n?n.subarray(t.y,t.y+t.m):new W(t.m),A=m.length-h;if(l==0)m.set(e.subarray(s,s+=h),A);else if(l==1)Re(m,e[s++],A);else{var x=t.h;if(l==2){var d=cn(e,s);g+=s-(s=d[0]),t.h=x=d[1]}else if(!x)Z(0);(p?gn:Fe)(e.subarray(s,s+=g),m.subarray(A),x)}var w=e[s++];if(w){if(w==255)w=(e[s++]|e[s++]<<8)+32512;else if(w>127)w=w-128<<8|e[s++];var b=e[s++];if(b&3)Z(0);var M=[fn,pn,un];for(var k=2;k>-1;--k){var N=b>>(k<<1)+2&3;if(N==1){var P=new W([0,0,e[s++]]);M[k]={s:P.subarray(2,3),n:P.subarray(0,1),t:new ze(P.buffer,0,1),b:0}}else if(N==2)r=Be(e,s,9-(k&1)),s=r[0],M[k]=r[1];else if(N==3){if(!t.t)Z(0);M[k]=t.t[k]}}var D=t.t=M,y=D[0],B=D[1],C=D[2],I=e[a-1];if(!I)Z(0);var R=(a<<3)-8+Se(I)-C.b,S=R>>3,V=0,he=(e[S]|e[S+1]<<8)>>(R&7)&(1<<C.b)-1;S=(R-=B.b)>>3;var ce=(e[S]|e[S+1]<<8)>>(R&7)&(1<<B.b)-1;S=(R-=y.b)>>3;var Me=(e[S]|e[S+1]<<8)>>(R&7)&(1<<y.b)-1;for(++w;--w;){var re=C.s[he],Te=C.n[he],be=y.s[Me],ve=y.n[Me],fe=B.s[ce],ke=B.n[ce];S=(R-=fe)>>3;var O=1<<fe,T=O+((e[S]|e[S+1]<<8|e[S+2]<<16|e[S+3]<<24)>>>(R&7)&O-1);S=(R-=Qe[be])>>3;var _=hn[be]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Qe[be])-1);S=(R-=Je[re])>>3;var X=mn[re]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Je[re])-1);if(S=(R-=Te)>>3,he=C.t[he]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<Te)-1),S=(R-=ve)>>3,Me=y.t[Me]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ve)-1),S=(R-=ke)>>3,ce=B.t[ce]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ke)-1),T>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=T-=3;else{var q=T-(X!=0);if(q){if(T=q==3?t.o[0]-1:t.o[q],q>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=T}else T=t.o[0]}for(var k=0;k<X;++k)m[V+k]=m[A+k];V+=X,A+=X;var ee=V-T;if(ee<0){var J=-ee,L=t.e+ee;if(J>_)J=_;for(var k=0;k<J;++k)m[V+k]=t.w[L+k];V+=J,_-=J,ee=0}for(var k=0;k<_;++k)m[V+k]=m[ee+k];V+=_}if(V!=A)while(A<m.length)m[V++]=m[A++];else V=m.length;if(n)t.y+=V;else m=Ye(m,0,V)}else if(n){if(t.y+=h,A)for(var k=0;k<h;++k)m[k]=m[A+k]}else if(A)m=Ye(m,A);return t.b=a,m}Z(2)},bn=function(e,t){if(e.length==1)return e[0];var n=new W(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function je(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=ln(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var c=dn(e,i,t);if(!c)Z(5);if(t)i.e=i.y;else n.push(c),o+=c.length,sn(i.w,0,c.length),i.w.set(c,i.w.length-c.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return bn(n,o)}async function yn(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(je(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function xt(e){return new TextDecoder().decode(await yn(e))}var wt=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function Ve(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var Y=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),et=/^[A-Za-z][A-Za-z0-9_]*$/,qe=new Map;function tt(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!qe.has(r))qe.set(r,t);return r}function nt(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&et.test(e))return tt(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var At=/^~?\\s*moved\\s+to\\s+(.+)$/i,xn=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),wn=new Set(["FILE","NOFILE","!DATA"]),Et=1000000000000000,Pt=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),An=new Set(["model","submodel","configuration"]),Mn=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function Mt(e){let t=Mn.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Pt.has(n)||An.has(n)?n:void 0}function vn(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function Cn(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((f)=>Number.isFinite(f)&&Math.abs(f)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let f=0;f<s;f++)c=c.replace(/^\\S+\\s*/,"");let a=vn(c);if(!a.length)return null;let u={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)u.a=i[9];if(s===11)u.b=i[10];let l=a.findIndex((f,h)=>h>0&&f.toUpperCase()==="GLOSSMAP");if(l>0&&a[l+1])u.glossmap=a[l+1];if(t)u.next=!0;return u}var kn=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,"");if(t.length%4===1)t=t.slice(0,-1);let n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function Tn(e,t){let n=e.length,r=1,s=(p)=>p===32||p===9,o=()=>{while(r<n&&s(e.charCodeAt(r)))r++;let p=r,m=e.charCodeAt(r),A=m===45;if(A)m=e.charCodeAt(++r);let x=0,d=0;while(m>=48&&m<=57)x=x*10+(m-48),d++,m=e.charCodeAt(++r);if(d>0&&d<=15&&(r>=n||s(m)))return A?-x:x;while(r<n&&!s(e.charCodeAt(r)))r++;return p<r?+e.slice(p,r):NaN};while(r<n&&s(e.charCodeAt(r)))r++;let i=r;if(r>=n)return null;let c=e.charCodeAt(r),a=c===45,u=0,l=0;if(a)c=e.charCodeAt(++r);while(c>=48&&c<=57)u=u*10+(c-48),l++,c=e.charCodeAt(++r);if(l>0&&l<=15&&(r>=n||s(c))){if(a)u=-u}else{while(r<n&&!s(e.charCodeAt(r)))r++;u=nt(e.slice(i,r))}let f=Array(12);for(let p=0;p<12;p++){let m=o();if(!Number.isFinite(m))return null;f[p]=m}while(r<n&&s(e.charCodeAt(r)))r++;if(r>=n)return null;let h=e.slice(r),g=t.get(h);if(g===void 0)g=Y(/[ \\t]{2,}|\\t/.test(h)?h.split(/\\s+/).join(" "):h),t.set(h,g);if(!Number.isFinite(u))return null;return{t:1,color:u,m:f,file:g}}var Ln=[0,12,6,9,12,12];function vt(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=nt(e[1]),r=Ln[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=Y(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function It(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,a=null,u=[],l=null,f=()=>{if(!a)return;let w=kn(a.chunks.join("")),b=w[0]===137&&w[1]===80&&w[2]===78&&w[3]===71;(c??=new Map).set(Y(a.name),{name:a.name,bytes:w,...b?{mime:"image/png"}:{}}),a=null},h=new Map,g=!0,p=(w)=>{if(f(),o={name:Y(w),cmds:[]},s.set(o.name,o),!i)i=o.name;u=[],l=null,g=!0},m=!1,A=!1,x=()=>{if(A)return;A=!0,s.clear(),o=null,i=""},d=(w,b)=>{if(l){w.tex=l,l=null;return}let M=u[u.length-1];if(!M)return;if(M.fallback){if(!b)w.fallback=!0}else w.tex=M.map};for(let w of e.split(`\n`)){let b=w.trim();if(!b)continue;if(r&&b.charCodeAt(0)>=50&&b.charCodeAt(0)<=53&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){if(a||m)continue;if(!o)p(t);let P=b.slice(2).trimStart(),D=P.search(/\\s/),y={t:b.charCodeAt(0)-48,color:nt(D<0?P:P.slice(0,D)),p:[],src:b};d(y,!1),o.cmds.push(y),g=!1;continue}if(b.charCodeAt(0)===48&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){let P=2;while(b.charCodeAt(P)===32||b.charCodeAt(P)===9)P++;let D=P;while(D<b.length&&b.charCodeAt(D)!==32&&b.charCodeAt(D)!==9)D++;let y=b.slice(P,D),B=/[^\\x21-\\x7e]/.test(y)?b.slice(P).trim().split(/\\s+/)[0]:y;if(!xn.has(B)&&!(B.length>=4&&B.length<=6&&wn.has(B.toUpperCase()))){if(m||a)continue;if(!o)p(t);let C=b.slice(P),I={t:0,text:C};if(y.charCodeAt(0)===33)I.meta=y;if(l=null,g&&!o.org){let S=Mt(C);if(S)o.org=S}let R=C.match(At);if(R&&!o.movedTo){let S=R[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(S))S+=".dat";o.movedTo=Y(S)}o.cmds.push(I);continue}}if(b.charCodeAt(0)===49&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)&&!a&&!m){let P=Tn(b,h);if(P){if(!o)p(t);d(P,!1),o.cmds.push(P),g=!1;continue}}let M=b.split(/\\s+/);if(+M[0]===0){let P=b.slice(1).trim(),D=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(D==="FILE"){let C=P.slice(5).trimStart().split("\\r")[0].trim();if(C){x(),m=!1,p(C);continue}}if(D==="NOFILE"){f(),o=null,m=!0;continue}if(D==="!DATA"){x(),f(),o=null,m=!1,a={name:P.slice(5).trim(),chunks:[]};continue}if(m)continue;if(a){if(M[1]==="!:")a.chunks.push(M.slice(2).join(""));continue}if(!o)p(t);let y={t:0,text:P};if(M[1]==="STEP")y.step=!0,u=[],l=null;else if(M[1]==="BFC")y.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(y.meta="ROTSTEP",y.step=!0,u=[],l=null,(M[2]??"").toUpperCase()==="END")y.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(M[5]??"REL").toUpperCase(),I=(R)=>{let S=Number(R);return Number.isFinite(S)?S:0};y.rotstep={x:I(M[2]),y:I(M[3]),z:I(M[4]),mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(M[1]==="BUFEXCHG"){y.meta="BUFEXCHG";let C=(M[2]??"").toUpperCase();y.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))y.meta=M[1];if(g&&!o.org){let C=Mt(P);if(C)o.org=C}if(M[1]==="!TEXMAP"){let C=(M[2]??"").toUpperCase();if(l=null,C==="START"||C==="NEXT"){let I=Cn(P.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(y.texmap={op:C,...I?{map:I}:{}},I)if((o.texmaps??=[]).push(I),C==="START")u.push({map:I,fallback:!1});else l=I}else if(C==="FALLBACK"){y.texmap={op:C};let I=u[u.length-1];if(I)I.fallback=!0}else if(C==="END")y.texmap={op:C},u.pop()}else if(M[1]==="!:"){l=null;let C=vt(M.slice(2));if(C)d(C,!0),y.geom=C}else l=null;let B=P.match(At);if(B&&!o.movedTo){let C=B[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=Y(C)}o.cmds.push(y);continue}if(a||m)continue;if(!o)p(t);let N=vt(M);if(!N){if(/^[2-5][ \\t]/.test(b))g=!1;continue}d(N,!1),o.cmds.push(N),g=!1}return f(),c?{main:i,files:s,data:c}:{main:i,files:s}}var rr=Math.PI/180;function Ft(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function Rt(e,t){let[n,r,s,o,i,c,a,u,l,f,h,g]=e,[p,m,A,x,d,w,b,M,k,N,P,D]=t;return[o*p+i*m+c*A+n,a*p+u*m+l*A+r,f*p+h*m+g*A+s,o*x+i*b+c*N,o*d+i*M+c*P,o*w+i*k+c*D,a*x+u*b+l*N,a*d+u*M+l*P,a*w+u*k+l*D,f*x+h*b+g*N,f*d+h*M+g*P,f*w+h*k+g*D]}var rt=[0,0,0,1,0,0,0,1,0,0,0,1];var Ct=new WeakMap,Sn=/^(s|8|48)\\//;function st(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=Ct.get(n);if(r)return r;if(n.org)r=Pt.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&Sn.test(s.file))?"part":"model";return Ct.set(n,r),r}var kt=new WeakMap;function Bt(e){let t=kt.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return kt.set(e,t),t}var Tt=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?qe.get(e)??String(e):String(e),En=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Tt(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Tt(e.color)} ${e.p.join(" ")}`,ot=(e,t)=>`${Y(e)}#${t}`;function Pn(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:ot(e.name,t),cmds:n}}function Dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Pn(e,t).cmds.map(En)].join(`\n`)+`\n`}function it(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function Ut(e){let[t,n,r,s,o,i,c,a,u,l,f,h]=e,g=a*h-u*f,p=-(c*h-u*l),m=c*f-a*l,A=s*g+o*p+i*m;if(!Number.isFinite(A)||Math.abs(A)<0.000000000001)return null;let x=1/A,d=[g*x,-(o*h-i*f)*x,(o*u-i*a)*x,p*x,(s*h-i*l)*x,-(s*u-i*c)*x,m*x,-(s*f-o*l)*x,(s*a-o*c)*x];return[-(d[0]*t+d[1]*n+d[2]*r),-(d[3]*t+d[4]*n+d[5]*r),-(d[6]*t+d[7]*n+d[8]*r),...d]}var In=(e)=>String(+e.toFixed(6)||0),Lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function Nt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(In).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${Lt(t.texture)}${t.glossmap?" GLOSSMAP "+Lt(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${Y(e)}\n0 !TEXMAP END\n`;return{name:`${Y(e)}#tex-${it(r)}`,source:r}}var Fn=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function Rn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),a=Math.sin(n*r),u=Math.cos(n*r);return[c*u,-c*a,i,o*a+s*i*u,o*u-s*i*a,-s*c,s*a-o*i*u,s*u+o*i*a,o*c]}var St=new WeakMap;function Ot(e){let t=St.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=Rn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:Fn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),St.set(e,n),n}class at extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var Bn=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=Et))return!1;return!0},zt=999999,Vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",_t=new WeakMap,$t=new WeakMap;function Dn(e,t){let n=$t.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=_t.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},$t.set(t,n);let r=n.parts.get(e);if(!r){let s=Y(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${it(o)}`,source:o},n.parts.set(e,r)}return r}function Un(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,a=0,u=new Set,l=t.maxInstances??2000000,f=0,h=(p,m)=>{let A=p.name+"#"+m,x=c.get(A);if(!x){let d;x=Object.assign(()=>d??=Dt(p,m),{file:p,step:m}),c.set(A,x)}return x},g=(p,m,A,x,d,w,b,M,k=null,N=[],P=[],D=void 0,y=null)=>{let B=p.files.get(m);if(!B||b>r||u.has(B))return;if(++f>l)throw new at("model",l);u.add(B);let C=y,I=0,R=b>0?++a:0,S=i&&R?[...N,R]:N,V=i&&R?[...P,A]:P,he=i&&!k?new Map:null,ce=-1,Me=0,re=(O,T,_,X,q,ee,J)=>{if(ce!==I)ce=I,Me=0;let L=he?.get(I+"|"+T);if(L)return L.n++,g(O,O===p?T:O.main,_,X,d+"/"+T,[...q,zt],b+1,ee,[...q,zt],S,V,J,C);let F=[...q,Me++],v=n.length;g(O,O===p?T:O.main,_,X,d+"/"+T,F,b+1,ee,k,S,V,J,C),he?.set(I+"|"+T,{n:1,from:v,to:n.length})},Te=Ot(B),be=s?Bt(B):[],ve=0,fe=(O,T,_,X,q,ee,J,L,F)=>{if(k)X=k;if(++f>l)throw new at("model",l);let v={part:O,color:T,m:_,step:X[0],steps:X,localStep:q,path:d};if(L)v.colour=L;if(R){if(v.sub=R,i)v.subPath=S,v.subMats=V}if(ee)v.embedded=!0;if(J){let E=Nt(O,J);v.texPart=E.name,v.texSource=E.source}else if(F){let E=Dn(O,F);v.colPart=E.name,v.colSource=E.source}let U=Te[q];if(U)v.view=U;return n.push(v),v},ke=(O)=>{while(ve<be.length&&be[ve]<=O){let T=be[ve++];fe(ot(B.name,T),x,A,[...w,T],T,!1,null,D,y).source=h(B,T)}};for(let O of B.cmds){if(O.t===0&&O.step){I++;continue}let T=O;if(T.t>=2||T.t===0&&T.geom&&T.geom.t>=2){ke(I);continue}if(T.t===0){if(T.meta==="!COLOUR"){let U=On(T.text);if(U&&U.code!==16&&U.code!==24)_t.set(U,T.text),(C=new Map(C??[])).set(U.code,U);continue}if(o&&T.geom?.t===1)T=T.geom;else continue}if(T.t!==1)continue;if(o&&T.fallback)continue;let _=Rt(A,T.m);if(!Bn(_))continue;let X=T.color===16?x:T.color,q=T.color===16?D:C?.get(T.color),ee=[...w,I],J=o?T.tex??M:null,L=J?Ut(T.m):null,F=J&&L?Ft(J,L):null;if(p.files.has(T.file)){if(st(p,T.file)==="model"){re(p,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!0,F,q,C);continue}let v=t.resolveModel?.(T.file);if(v){re(v,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!1,F,q,C)}if(ke(1/0),u.delete(B),he){for(let O of he.values())if(O.n>1)for(let T=O.from;T<O.to;T++)n[T].mult??=O.n}};if(st(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...rt],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,rt,16,e.main,[],0,null),n}function Gt(e,t="main.ldr",n){return Un(It(e,t,{geometryText:!0}),n)}var Nn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function lt(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function jt(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=lt(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function On(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,a=0,u={type:"default"},l=1;while(l<n.length){let f=n[l].toUpperCase(),h=n[l+1];if(f==="CODE")s=h!==void 0&&et.test(h)?tt(h):h!==void 0&&/^\\d+$/.test(h)?+h:NaN,l+=2;else if(f==="VALUE"){let g=lt(h);if(g)o=g;l+=2}else if(f==="EDGE")i=lt(h)??h,l+=2;else if(f==="ALPHA")c=+h,l+=2;else if(f==="LUMINANCE")a=+h,l+=2;else if(f==="CHROME")u={type:"chrome"},l+=1;else if(f==="PEARLESCENT")u={type:"pearlescent"},l+=1;else if(f==="RUBBER")u={type:"rubber"},l+=1;else if(f==="MATTE_METALLIC")u={type:"matte_metallic"},l+=1;else if(f==="METAL")u={type:"metal"},l+=1;else if(f==="MATERIAL"){let g=(n[l+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:p,next:m}=jt(n,l+2);u={type:"glitter",material:p},l=m}else if(g==="SPECKLE"){let{grain:p,next:m}=jt(n,l+2);u={type:"speckle",material:p},l=m}else if(g==="FABRIC"){let p=(n[l+2]||"").toUpperCase(),m=["VELVET","CANVAS","STRING","FUR"].includes(p)?p.toLowerCase():void 0;u={type:"fabric",kind:m},l+=m?3:2}else l=n.length}else if(Nn.has(f))l+=1;else l+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(a)?a:0,finish:u}}function zn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function ct(e){let t=zn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function $n(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(Y(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(Y(t),r)}let a=i.trim().replace(/\\s+/g," ");if(a)r.push(a)}return n}var jn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Vn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Wt(e,t,n="main.ldr"){let r=[...t],s=new Map;if(!r.length)return s;let o=$n(e,n);for(let i of r){let c=Y(i);if(!o.has(c)||s.has(c))continue;let a=new Set([c]),u=[c];while(u.length)for(let f of o.get(u.pop())){let h=jn(f);if(h&&o.has(h)&&!a.has(h))a.add(h),u.push(h)}let l=[c,...[...a].filter((f)=>f!==c).sort()].map((f)=>"0 FILE "+(f===c?"":f)+`\n`+o.get(f).join(`\n`)).join(`\n`);s.set(c,`emb/${Vn(l)}.dat`)}return s}var Xt=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Ht=new WeakMap,ut=null,ft="",pt=null;function mt(e,t){if(e===ut&&t===ft)return pt;let n=Ht.get(e);if(!n)Ht.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return ut=e,ft=t,pt=r,r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],a=[];s.studs.forEach((g,p)=>{c.push(g[0]),a.push(g[1]);for(let m=0;m<12;m++)i[p*12+m]=g[2+m]});let u=null,l=0,f=0;if(s.mask){l=s.mask[0],f=s.mask[1];let g=s.mask[2];u=new Uint8Array(g.length);for(let p=0;p<g.length;p++)u[p]=g.charCodeAt(p)===49?1:0}let h=!!u;if(u){for(let g=0;g<u.length;g++)if(u[g]!==1){h=!1;break}}return n.set(t,r={nStuds:o,studM:i,kind:c,color:a,mask:u,nx:l,nz:f,full:h}),ut=e,ft=t,pt=r,r}var Pe=1073741824;class Ee{t;tag;mask;size=0;shift;constructor(e=1024,t=-1){let n=1024;while(n<e*2)n*=2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.shift=t}slot(e,t,n){let r=this.shift;if(r<0){let o=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return o^=o>>>15,o=Math.imul(o,739982445),o^=o>>>12,o&this.mask}let s=Math.imul(e>>r+2,2654435761)^Math.imul(t,2246822507)^Math.imul(n>>r+2,3266489909);return s^=s>>>15,s=Math.imul(s,739982445),s^=s>>>12,(s<<4|(e>>r&3)<<2|n>>r&3)&this.mask}static tagOf(e,t,n){return Math.imul(e^Math.imul(t,374761393)^Math.imul(n,668265261),2654435761)>>>24|1}get(e,t,n){let r=Ee.tagOf(e,t,n),s=this.tag,o=this.t,i=this.mask,c=this.slot(e,t,n);for(;;){let a=s[c];if(a===0)return-1;if(a===r){let u=c<<2;if(o[u]===e&&o[u+1]===t&&o[u+2]===n)return o[u+3]}c=c+1&i}}put(e,t,n,r){if((this.size+1)*2>this.tag.length)this.grow();let s=Ee.tagOf(e,t,n),o=this.tag,i=this.t,c=this.mask,a=this.slot(e,t,n);for(;;){let u=o[a],l=a<<2;if(u===0)return o[a]=s,i[l]=e,i[l+1]=t,i[l+2]=n,i[l+3]=r,this.size++,-1;if(u===s&&i[l]===e&&i[l+1]===t&&i[l+2]===n){let f=i[l+3];return i[l+3]=r,f}a=a+1&c}}grow(){let e=this.t,t=this.tag,n=t.length*2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.size=0;for(let r=0;r<t.length;r++)if(t[r]){let s=r<<2;this.put(e[s],e[s+1],e[s+2],e[s+3])}}}class Zt{grp=new Ee(64);gBits=[];gX0=[];gZ0=[];gNz=[];gNx=[];bits;rest;lk=NaN;lpx=NaN;lpz=NaN;lg=-1;group(e,t,n){if(e!==this.lk||t!==this.lpx||n!==this.lpz)this.lk=e,this.lpx=t,this.lpz=n,this.lg=this.grp.get(e,t,n);return this.lg}constructor(e,t,n,r){let s=[],o=[],i=[],c=[],a=[];for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=(h%20+20)%20,A=(p%20+20)%20,x=this.group(g,m,A);if(x<0)x=s.length,this.grp.put(g,m,A,x),this.lg=x,s.push(0),o.push(h),i.push(h),c.push(p),a.push(p);if(s[x]++,h<o[x])o[x]=h;else if(h>i[x])i[x]=h;if(p<c[x])c[x]=p;else if(p>a[x])a[x]=p}let u=0,l=0;for(let f=0;f<s.length;f++){let h=(i[f]-o[f])/20+1,g=(a[f]-c[f])/20+1,p=h*g;if(this.gX0.push(o[f]),this.gZ0.push(c[f]),this.gNx.push(h),this.gNz.push(g),p<=64*s[f]+1024&&u+p<2147483648)this.gBits.push(u),u+=p;else this.gBits.push(-1),l+=s[f]}this.bits=new Uint8Array(Math.ceil(u/8)),this.rest=new Ee(l);for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=this.group(g,(h%20+20)%20,(p%20+20)%20),A=this.gBits[m];if(A<0){this.rest.put(h,g,p,1);continue}let x=A+(h-this.gX0[m])/20*this.gNz[m]+(p-this.gZ0[m])/20;this.bits[x>>>3]|=1<<(x&7)}}has(e,t,n){let r=this.group(t,(e%20+20)%20,(n%20+20)%20);if(r<0)return!1;let s=this.gBits[r];if(s<0)return this.rest.get(e,t,n)>=0;let o=(e-this.gX0[r])/20,i=(n-this.gZ0[r])/20;if(o<0||i<0||o>=this.gNx[r]||i>=this.gNz[r])return!1;let c=s+o*this.gNz[r]+i;return(this.bits[c>>>3]&1<<(c&7))!==0}}var _n=(e,t,n,r)=>e===0&&r===0&&(t===1||t===-1)&&(n===1||n===-1)||t===0&&n===0&&(e===1||e===-1)&&(r===1||r===-1),Ie=(e,t,n)=>e>-Pe&&e<Pe&&t>-Pe&&t<Pe&&n>-Pe&&n<Pe,De=2147483647;function Gn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function Wn(e,t,n){return Kt(e,t,n,-1)??Kt(e,t,n,Yt)}var Yt=0;function Kt(e,t,n,r){let o=new Map,i=(L)=>{let F=o.get(L);if(F===void 0)o.set(L,F=Gn(t,L));return F},c=e.length,a=0,u=0;for(let L=0,F="";L<c;L++){let v=e[L].part;if(v===F){a++;continue}let U=t.parts[v];if(U&&U.mask)a++,F=v}let l=new Float64Array(a),f=new Float64Array(a),h=new Float64Array(a),g=new Float64Array(a),p=new Int32Array(a),m=new Int32Array(a),A=new Float64Array(a),x=new Float64Array(a),d=[],w=new Int32Array(a),b=new Float64Array(a*9),M=new Uint8Array(a);if(r<0)r=a*4+64;let k=new Ee(e.length*2),N=new Int32Array(r),P=new Int32Array(r),D=0,y=0;for(let L=0;L<e.length;L++){let F=e[L],v=F.m,U=t.parts[F.part];if(!U||!U.mask||!Xt(v)||i(F.color))continue;let E=U.bbox,z=1/0,j=-1/0,te=1/0,H=-1/0;for(let K=0;K<2;K++)for(let le=0;le<2;le++){let ne=K?E[3]:E[0],Le=le?E[5]:E[2],Ae=v[0]+v[3]*ne+v[5]*Le,de=v[2]+v[9]*ne+v[11]*Le;if(Ae<z)z=Ae;if(Ae>j)j=Ae;if(de<te)te=de;if(de>H)H=de}let G=Math.round((v[1]+E[4])*2),Q=mt(t,F.part),ue=Math.floor(z/40),ye=Math.floor(j/40),xe=Math.floor(te/40),we=Math.floor(H/40);if(!((ye-ue+1)*(we-xe+1)<=65536)||!Ie(G,ue,xe)||!Ie(G,ye,we))continue;let ge=Math.floor((z+5)/40),se=Math.floor((j-5)/40),oe=Math.floor((te+5)/40),ie=Math.floor((H-5)/40),Ce=ge<=se&&oe<=ie?(se-ge+1)*(ie-oe+1):0;y+=Ce;let pe=-1;for(let K=ge<=se&&oe<=ie?k.get(G,ge,oe):-1,le=0;K>=0&&le<8;K=N[K],le++){let ne=P[K];if(l[ne]!==z||f[ne]!==j||h[ne]!==te||g[ne]!==H||d[ne]!==Q)continue;let Le=e[p[ne]].m,Ae=!0;for(let de=0;de<12;de++)if(Le[de]!==v[de]){Ae=!1;break}if(Ae){pe=ne;break}}if(pe>=0){let K=n?n[L]:0;if(n&&K<n[p[pe]])m[pe]=p[pe],p[pe]=L;else if(m[pe]<0||n&&K<n[m[pe]])m[pe]=L;continue}let ae=u++;l[ae]=z,f[ae]=j,h[ae]=te,g[ae]=H,p[ae]=L,m[ae]=-1,d.push(Q),A[ae]=E[0],x[ae]=E[2],w[ae]=G;let me=ae*9;if(b[me]=v[0],b[me+1]=v[1],b[me+2]=v[2],b[me+3]=v[3],b[me+4]=v[6],b[me+5]=v[9],b[me+6]=v[5],b[me+7]=v[8],b[me+8]=v[11],M[ae]=Q.full&&E[3]-E[0]<=20*Q.nx&&E[5]-E[2]<=20*Q.nz&&v[4]===0&&v[6]===0&&v[8]===0&&v[10]===0&&_n(v[3],v[5],v[9],v[11])?1:0,D+Ce>r){D=r+1;continue}for(let K=ge;K<=se;K++)for(let le=oe;le<=ie;le++){if(!Ie(G,K,le))continue;let ne=D++;P[ne]=ae,N[ne]=k.put(G,K,le,ne)}}if(D>r)return Yt=y,null;let B=[0,5,-5,5,-5],C=[0,5,5,-5,-5],I=(L,F,v,U)=>{if(!(F-6>=l[L]-0.5&&F+6<=f[L]+0.5&&U-6>=h[L]-0.5&&U+6<=g[L]+0.5))return!1;if(M[L]===1)return!0;let E=L*9,z=d[L],j=A[L],te=x[L],H=F-b[E],G=v-b[E+1],Q=U-b[E+2],ue=b[E+3]*H+b[E+4]*G+b[E+5]*Q,ye=b[E+6]*H+b[E+7]*G+b[E+8]*Q,{nx:xe,nz:we,mask:ge}=z;for(let se=0;se<5;se++){let oe=Math.floor((ue+B[se]-j)/20),ie=Math.floor((ye+C[se]-te)/20);if(oe<0||ie<0||oe>=xe||ie>=we||ge[oe*we+ie]!==1)return!1}return!0},R=NaN,S=NaN,V=NaN,he=-1,ce=-1,Me=(L,F,v,U)=>{let E=Math.round(F*2),z=Math.floor(L/40),j=Math.floor(v/40);if(!Ie(E,z,j))return De;let te=De;if(!n&&ce>=0&&w[ce]===E&&(p[ce]!==U||m[ce]>=0)&&I(ce,L,F,v))return 0;if(E!==R||z!==S||j!==V)R=E,S=z,V=j,he=k.get(E,z,j);for(let H=he;H>=0;H=N[H]){let G=P[H],Q=p[G];if(Q===U&&(Q=m[G])<0)continue;if(!I(G,L,F,v))continue;if(!n)return ce=G,0;let ue=n[Q];if(ue<te)te=ue}return te},re=0;for(let L of e){let F=mt(t,L.part);if(F)re+=F.nStuds}let Te=new Uint8Array(re),be=new Uint8Array(re),ve=0,fe=n?new Ee(re,4):null,ke=n?null:new Int32Array(re),O=n?null:new Int32Array(re),T=n?null:new Int32Array(re),_=0,X=n?new Int32Array(re).fill(De):void 0;for(let L=0,F=0;L<e.length;L++){let v=e[L],U=mt(t,v.part);if(!U)continue;let E=v.m,z=U.studM,j=E[0],te=E[1],H=E[2],G=E[3],Q=E[4],ue=E[5],ye=E[6],xe=E[7],we=E[8],ge=E[9],se=E[10],oe=E[11];for(let ie=0;ie<U.nStuds;ie++,F++){let Ce=ie*12,pe=z[Ce+4],ae=z[Ce+7],me=z[Ce+10];if(!(Math.abs(ye*pe+xe*ae+we*me-1)<0.001&&Math.abs(G*pe+Q*ae+ue*me)<0.001&&Math.abs(ge*pe+se*ae+oe*me)<0.001))continue;be[F]=1;let K=z[Ce],le=z[Ce+1],ne=z[Ce+2],Le=j+G*K+Q*le+ue*ne,Ae=te+ye*K+xe*le+we*ne,de=H+ge*K+se*le+oe*ne,ht=Me(Le,Ae,de,L);if(ht!==De){if(Te[F]=1,ve++,X)X[F]=ht}let Ue=Math.round(Le),Ne=Math.round(Ae),Oe=Math.round(de);if(!Ie(Ue,Ne,Oe))continue;if(!fe){ke[_]=Ue,O[_]=Ne,T[_++]=Oe;continue}let gt=n[L],dt=fe.get(Ue,Ne,Oe);if(dt<0||gt<dt)fe.put(Ue,Ne,Oe,gt)}}let q=fe?null:new Zt(ke,O,T,_),ee=new Uint8Array(e.length),J=n?new Int32Array(e.length).fill(De):void 0;for(let L=0;L<e.length;L++){let F=e[L],v=t.parts[F.part];if(!v||!v.under||!Xt(F.m)||i(F.color))continue;let U=v.bbox,E=Math.round((U[3]-U[0])/20),z=Math.round((U[5]-U[2])/20);if(!E||!z||E*z>4096)continue;let j=F.m,te=Math.round(j[1]+U[4]),H=!0,G=0;for(let Q=0;Q<E&&H;Q++)for(let ue=0;ue<z;ue++){let ye=U[0]+10+20*Q,xe=U[2]+10+20*ue,we=j[0]+j[3]*ye+j[5]*xe,ge=j[2]+j[9]*ye+j[11]*xe,se=Math.round(we),oe=Math.round(ge),ie=!Ie(se,te,oe)?-1:fe?fe.get(se,te,oe):q.has(se,te,oe)?1:-1;if(ie<0){H=!1;break}if(ie>G)G=ie}if(H){if(ee[L]=1,J)J[L]=G}}return{nStuds:re,studHidden:Te,studUp:be,underHidden:ee,studsHidden:ve,studHideStep:X,underHideStep:J}}function Xn(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let f=l.colour;if(!f)return String(l.color);let h=o.get(f);if(h!==void 0)return h;let g=t.colorTable?.[l.color],p=g?.hex??t.colors?.[l.color],m=g?ct({alpha:g.alpha??255,luminance:g.luminance??0,finish:g.finish??{type:"default"}}):"default:op",A=ct(f);if(h=p&&p.toUpperCase()===f.hex.toUpperCase()&&m===A?String(l.color):f.hex.toUpperCase()+"/"+A,h!==String(l.color))s.set(h,f);return o.set(f,h),h},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),{stepOf:a,nSteps:u}=Hn(c);return{all:c,stepOf:a,nSteps:u,localColours:s}}function Hn(e){let t=!0;for(let o=0;o<e.length;o++){let i=e[o].steps;if(i.length!==1){t=!1;break}let c=i[0];if(!(Number.isInteger(c)&&c>=0&&c<1e6)){t=!1;break}}if(t){let o=new Set;for(let a=0;a<e.length;a++)o.add(e[a].steps[0]);let i=[...o].sort((a,u)=>a-u),c=new Map(i.map((a,u)=>[a,u]));return{stepOf:e.map((a)=>c.get(a.steps[0])),nSteps:i.length}}let n=e.map((o)=>Vt(o.steps)),r=[...new Set(n)].sort(),s=new Map(r.map((o,i)=>[o,i]));return{stepOf:n.map((o)=>s.get(o)),nSteps:r.length}}function _e(e,t,n=!0){let r=Xn(e,t,n);return Wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Ke="https://ldr-demo.vercel.app/cdn/v1/",We=new Map,Ge=new Map;function Xe(e=Ke,t=fetch){let n=We.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>We.delete(e)),We.set(e,n);return n}var Kn=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),He=(e,t)=>Kn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>He(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,He(r,t)])):e;function Zn(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let g=h.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let p=new DataView(g).getUint32(0,!0),m=new Uint8Array(g,4+p),A=r;n.push(m),r+=m.byteLength;let x=(4-r%4)%4;if(x)n.push(new Uint8Array(x)),r+=x;for(let[d,w]of Object.entries(h.header.parts??{}))if(!(d in s))s[d]=He(w,A);for(let[d,w]of Object.entries(h.header.studKinds??{}))if(!(d in o))o[d]=He(w,A)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+c.length)%4)%4,u=4+c.length+a,l=new Uint8Array(u+r);new DataView(l.buffer).setUint32(0,c.length+a,!0),l.set(c,4),l.fill(32,4+c.length,u);let f=u;for(let h of n)l.set(h,f),f+=h.byteLength;return Ve(l.buffer)}async function Yn(e,t={}){e=[...e];try{return await Jt(e,t)}catch(n){let r=t.cdn??Ke,s=t.fetch??fetch;We.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await Jt(e,{...t,fetch:o})}catch{throw n}}}async function Jt(e,t){let n=t.cdn??Ke,r=t.fetch??fetch,s=t.gap??16384,o=await Xe(n,r),i=[...new Set([...new Set(e)].map(Y))],c=[],a=[];for(let d of i){if(Ge.has(n+d))continue;let w=o.parts[d];if(w)a.push({name:d,off:w[0],len:w[1],file:w[2]??0});else c.push(d)}a.sort((d,w)=>d.file-w.file||d.off-w.off);let u=[];for(let d of a){let w=u[u.length-1];if(w&&w.file===d.file&&d.off-w.end<=s)w.end=Math.max(w.end,d.off+d.len),w.items.push(d);else u.push({file:d.file,start:d.off,end:d.off+d.len,items:[d]})}let l=0,f=0,h=0,g=new Map,p=async()=>{while(h<u.length){let d=u[h++],w=g.get(d.file);if(w)w=w.subarray(d.start,d.end);else{let b=await r(new URL(o.archives[d.file],n).href,{headers:{Range:`bytes=${d.start}-${d.end-1}`,"Accept-Encoding":"identity"}});if(!b.ok)throw Error(`ldr: parts CDN ${b.status}`);if(f++,w=new Uint8Array(await b.arrayBuffer()),l+=w.byteLength,b.status===200)g.set(d.file,w),w=w.subarray(d.start,d.end)}for(let b of d.items){let M=je(w.subarray(b.off-d.start,b.off-d.start+b.len)),k=M.buffer.slice(M.byteOffset,M.byteOffset+M.byteLength);Ge.set(n+b.name,Ve(k))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,u.length)},p));let m=i.filter((d)=>Ge.has(n+d)).map((d)=>Ge.get(n+d)),A={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:m.length?Zn(m,A):Ve(Jn(A)),missing:c,requests:f,bytes:l}}function Jn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function Qn(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function Qt(e,t,n){let r=0,s=0,o=!1,i=new Set,c=new Map;for(let a of e){let u;if(a.embedded)u=t.get(a.part);else if(u=c.get(a.part),u===void 0)c.set(a.part,u=Y(a.part));let l=u?n.parts[u]:void 0;if(!l)continue;if(l[3]!=null)o=!0,r+=l[3];if(!i.has(u))i.add(u),s+=l[1]}return{bodyTris:r,packBytes:s,known:o}}class Ze extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function qt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Xe(t.cdn??Ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(y)=>{if(!y.ok)throw Error(`ldr: ${y.status} fetching ${e}`);return xt(await y.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":wt(e)),a=Gt(o,c,{looseGeometry:!1,callouts:t.callouts}),u=performance.now();t.onParsed?.(a),await s;let l=Wt(o,new Set(a.filter((y)=>y.embedded).map((y)=>y.part)),c),f=(y,B)=>t.maxBodyTris!=null&&y>t.maxBodyTris||t.maxPackBytes!=null&&B>t.maxPackBytes,h=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(y)=>new Ze({...y,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),p="full";if(h){let y=Qt(a,l,await s);if(f(y.known?y.bodyTris:0,y.packBytes)){if(!t.lowCdn)throw g(y);let B=await Xe(t.lowCdn,r).catch(()=>null);if(!B)throw g(y);let C=Qt(a,l,B);if(f(C.known?C.bodyTris:0,C.packBytes))throw g(C);p="low"}}let m=[...a.filter((y)=>!y.embedded).map((y)=>y.part),...l.values()],A=async()=>{let y=await Yn(m,p==="low"?{...t,cdn:t.lowCdn}:t);for(let[B,C]of l){let I=y.pack.header.parts[C];if(I)y.pack.header.parts[B]=I}return{...y,packBytes:y.pack.buffer?.byteLength??y.pack.bytes??0,bodyTris:Qn(a,y.pack)}},x=await A();if(h&&f(x.bodyTris,x.packBytes)&&p==="full"&&t.lowCdn&&await Xe(t.lowCdn,r).then(()=>!0,()=>!1)){p="low";let y=x;x=await A(),x.requests+=y.requests,x.bytes+=y.bytes}if(h&&f(x.bodyTris,x.packBytes))throw g(x);let{pack:d,missing:w,requests:b,bytes:M}=x,k=new Map([...l].map(([y,B])=>[B,y])),N=w.map((y)=>k.get(y)??y),P=performance.now(),D=t.cull?_e(a,d.header,t.textures!==!1):void 0;return{insts:a,pack:d,tier:p,missing:N,requests:b,bytes:M,cull:D,timings:{fetchModel:i-n,parse:u-i,parts:P-u,...D?{cull:performance.now()-P}:{}}}}var qn=new Set(["part","color","m","step","steps","localStep","path"]);function en(e){let t=e.length,n=0;for(let p of e){if(typeof p.part!=="string"||typeof p.path!=="string"||typeof p.color!=="number"||typeof p.step!=="number"||typeof p.localStep!=="number"||!Array.isArray(p.m)||p.m.length!==12||!Array.isArray(p.steps))return null;n+=p.steps.length}let r=[],s=new Map,o=(p)=>{let m=s.get(p);if(m===void 0)s.set(p,m=r.length),r.push(p);return m},i=new Uint32Array(t),c=new Uint32Array(t),a=new Float64Array(t*3),u=new Float64Array(t*12),l=new Uint32Array(t+1),f=new Float64Array(n),h=[],g=0;for(let p=0;p<t;p++){let m=e[p];i[p]=o(m.part),c[p]=o(m.path),a[p*3]=m.color,a[p*3+1]=m.step,a[p*3+2]=m.localStep;let A=m.m,x=p*12;for(let b=0;b<12;b++)u[x+b]=A[b];let d=m.steps;for(let b=0;b<d.length;b++)f[g++]=d[b];l[p+1]=g;let w=null;for(let b in m)if(!qn.has(b))(w??={})[b]=m[b];if(w)h.push([p,w])}return{n:t,strs:r,part:i,path:c,num:a,m:u,so:l,steps:f,extra:h}}var tn=(e)=>[e.part.buffer,e.path.buffer,e.num.buffer,e.m.buffer,e.so.buffer,e.steps.buffer];self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await qt(n,{...r,cull:!1,onParsed:(l)=>{let f=en(l);if(f)self.postMessage({id:t,packed:f},tn(f));else self.postMessage({id:t,insts:l})}}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),c=_e(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,u=[];for(let l of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(l)u.push(l.buffer);self.postMessage({id:t,cull:c,ms:a},u)}catch(s){if(s instanceof Ze||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
5404
5404
 
5405
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/inst-io.ts
5405
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/inst-io.ts
5406
5406
  var CORE = new Set(["part", "color", "m", "step", "steps", "localStep", "path"]);
5407
5407
  function unpackInstances(p) {
5408
5408
  const { n, strs, part, path, num, m, so, steps, extra } = p;
@@ -5427,7 +5427,7 @@ function unpackInstances(p) {
5427
5427
  return out;
5428
5428
  }
5429
5429
 
5430
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/cdn.ts
5430
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/cdn.ts
5431
5431
  var worker;
5432
5432
  var seq = 0;
5433
5433
  var pending = new Map;
@@ -5541,7 +5541,11 @@ async function loadModel(source, o = {}) {
5541
5541
  timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
5542
5542
  });
5543
5543
  }
5544
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/usdz.ts
5544
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/usdz.ts
5545
+ var IDENT = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
5546
+ var MAX_ERR = 8;
5547
+ var REL_ERR = 0.1;
5548
+ var OCC_ERR = 4;
5545
5549
  var BOX_W = 5.317;
5546
5550
  var boxStud = null;
5547
5551
  function studBox() {
@@ -5569,7 +5573,6 @@ var geoOf = (b, arr) => {
5569
5573
  const idx = b.idx ? arr(b.idx) : null;
5570
5574
  return { pos, nrm: b.nrm ? arr(b.nrm) : null, col, idx, u8: col instanceof Uint8Array, tris: (idx ? idx.length : pos.length / 3) / 3 };
5571
5575
  };
5572
- var level = (b, L) => !b ? null : L <= 0 || !b.lod?.length ? b : b.lod[Math.min(L, b.lod.length) - 1];
5573
5576
  var srgbToLinear = (c) => c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
5574
5577
  var f = (x, d) => {
5575
5578
  const s = x.toFixed(d);
@@ -5582,39 +5585,6 @@ function toUSDZ(instances, pack, options = {}) {
5582
5585
  const { all, localColours } = sceneInstances(instances, H, false);
5583
5586
  const insts = all.filter((i) => H.parts[i.part]);
5584
5587
  const cull = cullCore(insts, H);
5585
- const studs = [];
5586
- forEachStud(insts, H, (j, _i, w, kind, color) => {
5587
- if (!cull.studHidden[j])
5588
- studs.push({ w: Float64Array.from(w), kind, color });
5589
- });
5590
- const maxL = Math.max(0, ...insts.map((i) => H.parts[i.part].body?.lod?.length ?? 0));
5591
- const cands = [[0, "full"], [0, "box"]];
5592
- for (let L = 1;L <= maxL; L++)
5593
- cands.push([L, "box"]);
5594
- for (let L = 1;L <= maxL; L++)
5595
- cands.push([L, "none"]);
5596
- const triCount = (L, sm) => {
5597
- let t = 0;
5598
- insts.forEach((it, k) => {
5599
- const p = H.parts[it.part];
5600
- t += level(p.body, L)?.tris ?? 0;
5601
- if (!cull.underHidden[k])
5602
- t += level(p.under, L)?.tris ?? 0;
5603
- });
5604
- if (sm === "full")
5605
- for (const s of studs)
5606
- t += H.studKinds?.[s.kind]?.body?.tris ?? 0;
5607
- else if (sm === "box")
5608
- t += studs.length * 10;
5609
- return t;
5610
- };
5611
- let pick = cands[cands.length - 1];
5612
- for (const c of cands)
5613
- if (triCount(c[0], c[1]) <= maxT) {
5614
- pick = c;
5615
- break;
5616
- }
5617
- const [L, sm] = pick;
5618
5588
  const table = H.colorTable ?? {};
5619
5589
  const hexOf = (c) => {
5620
5590
  const o = options.color?.(c);
@@ -5647,93 +5617,297 @@ function toUSDZ(instances, pack, options = {}) {
5647
5617
  const t = table[c]?.finish?.type;
5648
5618
  return t === "chrome" || t === "metal" ? 1 : 0;
5649
5619
  };
5650
- const buckets = new Map;
5651
- const bucketFor = (hex, a, metal) => {
5652
- const k = hex + "/" + a.toFixed(2) + "/" + metal;
5653
- let b = buckets.get(k);
5620
+ const bucketIn = (sink, hex, a, metal, inst = false) => {
5621
+ const k = inst ? "inst" : hex + "/" + a.toFixed(2) + "/" + metal;
5622
+ let b = sink.get(k);
5654
5623
  if (!b)
5655
- buckets.set(k, b = { hex, a, metal, P: [], N: [], I: [] });
5624
+ sink.set(k, b = { hex, a, metal, inst, P: [], N: [], I: [] });
5656
5625
  return b;
5657
5626
  };
5658
- const sy = options.yUp ? 1 : -1;
5627
+ const SY = options.yUp ? 1 : -1;
5628
+ const diagCache = new Map;
5629
+ const diag = (b) => {
5630
+ let d = diagCache.get(b);
5631
+ if (d === undefined) {
5632
+ const q = arr(b.pos);
5633
+ let a0 = Infinity, a1 = Infinity, a2 = Infinity, b0 = -Infinity, b1 = -Infinity, b2 = -Infinity;
5634
+ for (let i = 0;i < q.length; i += 3) {
5635
+ a0 = Math.min(a0, q[i]);
5636
+ a1 = Math.min(a1, q[i + 1]);
5637
+ a2 = Math.min(a2, q[i + 2]);
5638
+ b0 = Math.max(b0, q[i]);
5639
+ b1 = Math.max(b1, q[i + 1]);
5640
+ b2 = Math.max(b2, q[i + 2]);
5641
+ }
5642
+ diagCache.set(b, d = q.length ? Math.hypot(b0 - a0, b1 - a1, b2 - a2) : 0);
5643
+ }
5644
+ return d;
5645
+ };
5646
+ const pickLevel = (b, E) => {
5647
+ if (!b)
5648
+ return null;
5649
+ let best = b;
5650
+ if (E > 0) {
5651
+ for (const l of b.lod ?? [])
5652
+ if (l.err <= Math.min(E, REL_ERR * diag(b)) && l.tris < best.tris)
5653
+ best = l;
5654
+ }
5655
+ return best;
5656
+ };
5657
+ const items = [];
5658
+ insts.forEach((it, k) => {
5659
+ const p = H.parts[it.part];
5660
+ const unc = !!p.uncert;
5661
+ if (p.body)
5662
+ items.push({ k, key: "body", b: p.body, m: it.m, color: it.color, uncert: unc });
5663
+ if (p.under && !cull.underHidden[k])
5664
+ items.push({ k, key: "under", b: p.under, m: it.m, color: it.color, uncert: unc });
5665
+ });
5666
+ const studItems = [];
5667
+ forEachStud(insts, H, (j, i, w, kind, color) => {
5668
+ const b = H.studKinds?.[kind]?.body;
5669
+ if (!cull.studHidden[j] && b)
5670
+ studItems.push({ k: i, key: "stud", b, m: Float64Array.from(w), color, uncert: false });
5671
+ });
5672
+ const hidden = options.occlusion === false ? null : hiddenInstances(insts.length, [...items, ...studItems], (it) => geoOf(pickLevel(it.b, OCC_ERR), arr), (c) => alphaOf(c) < 1);
5673
+ const live = items.filter((it) => !hidden?.[it.k]), liveStuds = studItems.filter((it) => !hidden?.[it.k]);
5674
+ const count = (E, sm) => {
5675
+ let t = 0;
5676
+ for (const it of live)
5677
+ t += pickLevel(it.b, E).tris * (it.uncert ? 2 : 0) + pickLevel(it.b, E).tris * (it.uncert ? 0 : 1);
5678
+ if (sm === "full")
5679
+ for (const it of liveStuds)
5680
+ t += it.b.tris;
5681
+ else
5682
+ t += liveStuds.length * 10;
5683
+ return t;
5684
+ };
5685
+ let E = 0, sm = "full";
5686
+ search:
5687
+ for (const s of ["full", "box"])
5688
+ for (const e of [0, 0.5, 1, 2, 4, MAX_ERR]) {
5689
+ E = e;
5690
+ sm = s;
5691
+ if (count(e, s) <= maxT)
5692
+ break search;
5693
+ }
5659
5694
  let tris = 0;
5660
- const emit = (g, m, color) => {
5661
- const inst = bucketFor(hexOf(color), alphaOf(color), metalOf(color));
5695
+ const emit = (sink, g, m, color, twoSided, sy) => {
5696
+ const inst = color === null ? bucketIn(sink, "", 1, 0, true) : bucketIn(sink, hexOf(color), alphaOf(color), metalOf(color));
5662
5697
  const det = m[3] * (m[7] * m[11] - m[8] * m[10]) - m[4] * (m[6] * m[11] - m[8] * m[9]) + m[5] * (m[6] * m[10] - m[7] * m[9]);
5663
5698
  const flip = det < 0;
5664
5699
  const nv = g.pos.length / 3;
5700
+ const cs = g.u8 ? 1 / 255 : 1;
5701
+ const W = new Float64Array(nv * 3);
5702
+ for (let i = 0;i < nv; i++) {
5703
+ const x = g.pos[i * 3], y = g.pos[i * 3 + 1], z = g.pos[i * 3 + 2];
5704
+ W[i * 3] = m[0] + m[3] * x + m[4] * y + m[5] * z;
5705
+ W[i * 3 + 1] = sy * (m[1] + m[6] * x + m[7] * y + m[8] * z);
5706
+ W[i * 3 + 2] = sy * (m[2] + m[9] * x + m[10] * y + m[11] * z);
5707
+ }
5665
5708
  const maps = new Map;
5666
- const vtx = (i, b) => {
5709
+ const shared = (i, b) => {
5667
5710
  let mp = maps.get(b);
5668
5711
  if (!mp)
5669
5712
  maps.set(b, mp = new Int32Array(nv).fill(-1));
5670
5713
  if (mp[i] >= 0)
5671
5714
  return mp[i];
5672
- const x = g.pos[i * 3], y = g.pos[i * 3 + 1], z = g.pos[i * 3 + 2];
5673
5715
  const o = b.P.length / 3;
5674
5716
  mp[i] = o;
5675
- b.P.push(m[0] + m[3] * x + m[4] * y + m[5] * z, sy * (m[1] + m[6] * x + m[7] * y + m[8] * z), sy * (m[2] + m[9] * x + m[10] * y + m[11] * z));
5676
- let nx = 0, ny = 1, nz = 0;
5677
- if (g.nrm) {
5678
- const ax = g.nrm[i * 3], ay = g.nrm[i * 3 + 1], az = g.nrm[i * 3 + 2];
5679
- nx = m[3] * ax + m[4] * ay + m[5] * az;
5680
- ny = m[6] * ax + m[7] * ay + m[8] * az;
5681
- nz = m[9] * ax + m[10] * ay + m[11] * az;
5682
- }
5717
+ b.P.push(W[i * 3], W[i * 3 + 1], W[i * 3 + 2]);
5718
+ const ax = g.nrm[i * 3], ay = g.nrm[i * 3 + 1], az = g.nrm[i * 3 + 2];
5719
+ const nx = m[3] * ax + m[4] * ay + m[5] * az, ny = m[6] * ax + m[7] * ay + m[8] * az, nz = m[9] * ax + m[10] * ay + m[11] * az;
5683
5720
  const l = Math.hypot(nx, ny, nz) || 1;
5684
5721
  b.N.push(nx / l, sy * ny / l, sy * nz / l);
5685
5722
  return o;
5686
5723
  };
5687
- const nt = g.tris;
5688
- const cs = g.u8 ? 1 / 255 : 1;
5689
- for (let t = 0;t < nt; t++) {
5724
+ const flatMaps = new Map;
5725
+ const put = (b, v, n, s) => {
5726
+ let fm = flatMaps.get(b);
5727
+ if (!fm)
5728
+ flatMaps.set(b, fm = new Map);
5729
+ const nk = Math.round(n[0] * s * 100) + "," + Math.round(n[1] * s * 100) + "," + Math.round(n[2] * s * 100);
5730
+ return v.map((i) => {
5731
+ const k = i + "|" + nk;
5732
+ let o = fm.get(k);
5733
+ if (o === undefined) {
5734
+ o = b.P.length / 3;
5735
+ fm.set(k, o);
5736
+ b.P.push(W[i * 3], W[i * 3 + 1], W[i * 3 + 2]);
5737
+ b.N.push(n[0] * s, n[1] * s, n[2] * s);
5738
+ }
5739
+ return o;
5740
+ });
5741
+ };
5742
+ for (let t = 0;t < g.tris; t++) {
5690
5743
  const a = g.idx ? g.idx[t * 3] : t * 3, bb = g.idx ? g.idx[t * 3 + 1] : t * 3 + 1, c = g.idx ? g.idx[t * 3 + 2] : t * 3 + 2;
5691
5744
  let b = inst;
5692
5745
  if (g.col && g.col[a * 4 + 3] * cs > 0.5) {
5693
5746
  const h = "#" + [0, 1, 2].map((k) => Math.round(g.col[a * 4 + k] * cs * 255).toString(16).padStart(2, "0")).join("");
5694
- b = bucketFor(h, 1, 0);
5747
+ b = bucketIn(sink, h, 1, 0);
5748
+ }
5749
+ const [p, q, r] = flip ? [a, c, bb] : [a, bb, c];
5750
+ let fn = null;
5751
+ if (!g.nrm || twoSided) {
5752
+ const ux = W[q * 3] - W[p * 3], uy = W[q * 3 + 1] - W[p * 3 + 1], uz = W[q * 3 + 2] - W[p * 3 + 2], vx = W[r * 3] - W[p * 3], vy = W[r * 3 + 1] - W[p * 3 + 1], vz = W[r * 3 + 2] - W[p * 3 + 2];
5753
+ const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
5754
+ const l = Math.hypot(nx, ny, nz);
5755
+ if (!(l > 0.000000001))
5756
+ continue;
5757
+ fn = [nx / l, ny / l, nz / l];
5695
5758
  }
5696
- const A = vtx(a, b), B = vtx(bb, b), C = vtx(c, b);
5697
- if (flip)
5698
- b.I.push(A, C, B);
5699
- else
5759
+ if (g.nrm) {
5760
+ const A = shared(p, b), B = shared(q, b), C = shared(r, b);
5700
5761
  b.I.push(A, B, C);
5762
+ } else
5763
+ b.I.push(...put(b, [p, q, r], fn, 1));
5701
5764
  tris++;
5765
+ if (twoSided) {
5766
+ b.I.push(...put(b, [p, r, q], fn, -1));
5767
+ tris++;
5768
+ }
5702
5769
  }
5703
5770
  };
5704
- insts.forEach((it, k) => {
5705
- const p = H.parts[it.part];
5706
- const body = geoOf(level(p.body, L), arr);
5707
- if (body)
5708
- emit(body, it.m, it.color);
5709
- if (!cull.underHidden[k]) {
5710
- const u = geoOf(level(p.under, L), arr);
5711
- if (u)
5712
- emit(u, it.m, it.color);
5713
- }
5714
- });
5715
- if (sm !== "none")
5716
- for (const s of studs) {
5717
- const g = sm === "box" ? studBox() : geoOf(H.studKinds?.[s.kind]?.body, arr);
5718
- if (g)
5719
- emit(g, s.w, s.color);
5720
- }
5771
+ const box = studBox();
5772
+ const levelId = new Map;
5773
+ const lid = (l) => {
5774
+ let i = levelId.get(l);
5775
+ if (i === undefined)
5776
+ levelId.set(l, i = levelId.size);
5777
+ return i;
5778
+ };
5779
+ const protos = new Map;
5780
+ const placed = [];
5781
+ const MIRROR = [0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0, 1];
5782
+ const byInst = new Map;
5783
+ for (const it of live) {
5784
+ let l = byInst.get(it.k);
5785
+ if (!l)
5786
+ byInst.set(it.k, l = []);
5787
+ l.push(it);
5788
+ }
5789
+ for (const [k, its] of byInst) {
5790
+ const m = insts[k].m;
5791
+ const det = m[3] * (m[7] * m[11] - m[8] * m[10]) - m[4] * (m[6] * m[11] - m[8] * m[9]) + m[5] * (m[6] * m[10] - m[7] * m[9]);
5792
+ const mir = det < 0;
5793
+ const lv = its.map((it) => pickLevel(it.b, E));
5794
+ const key = lv.map(lid).join("+") + (its[0].uncert ? "u" : "") + (mir ? "m" : "");
5795
+ let pr = protos.get(key);
5796
+ if (!pr) {
5797
+ pr = { sink: new Map, lo: [Infinity, Infinity, Infinity], hi: [-Infinity, -Infinity, -Infinity], tris: 0 };
5798
+ protos.set(key, pr);
5799
+ const t0 = tris;
5800
+ its.forEach((it, j) => {
5801
+ const g = geoOf(lv[j], arr);
5802
+ if (g)
5803
+ emit(pr.sink, g, mir ? MIRROR : IDENT, null, it.uncert, 1);
5804
+ });
5805
+ pr.tris = tris - t0;
5806
+ for (const b of pr.sink.values())
5807
+ for (let i = 0;i < b.P.length; i++) {
5808
+ const a = i % 3;
5809
+ if (b.P[i] < pr.lo[a])
5810
+ pr.lo[a] = b.P[i];
5811
+ if (b.P[i] > pr.hi[a])
5812
+ pr.hi[a] = b.P[i];
5813
+ }
5814
+ } else
5815
+ tris += pr.tris;
5816
+ const M = Array.from(m);
5817
+ if (mir) {
5818
+ M[3] = -M[3];
5819
+ M[6] = -M[6];
5820
+ M[9] = -M[9];
5821
+ }
5822
+ placed.push({ proto: key, m: M, color: insts[k].color });
5823
+ }
5824
+ const studSink = new Map;
5825
+ for (const it of liveStuds) {
5826
+ const g = sm === "box" ? box : geoOf(it.b, arr);
5827
+ if (g)
5828
+ emit(studSink, g, it.m, it.color, false, 1);
5829
+ }
5721
5830
  let x0 = Infinity, y0 = Infinity, z0 = Infinity, x1 = -Infinity, z1 = -Infinity;
5722
- for (const b of buckets.values())
5723
- for (let i = 0;i < b.P.length; i += 3) {
5724
- const x = b.P[i], y = b.P[i + 1], z = b.P[i + 2];
5725
- if (x < x0)
5726
- x0 = x;
5727
- if (x > x1)
5728
- x1 = x;
5729
- if (y < y0)
5730
- y0 = y;
5731
- if (z < z0)
5732
- z0 = z;
5733
- if (z > z1)
5734
- z1 = z;
5831
+ const addPt = (x, y, z) => {
5832
+ y *= SY;
5833
+ z *= SY;
5834
+ if (x < x0)
5835
+ x0 = x;
5836
+ if (x > x1)
5837
+ x1 = x;
5838
+ if (y < y0)
5839
+ y0 = y;
5840
+ if (z < z0)
5841
+ z0 = z;
5842
+ if (z > z1)
5843
+ z1 = z;
5844
+ };
5845
+ for (const pl of placed) {
5846
+ const pr = protos.get(pl.proto);
5847
+ if (!isFinite(pr.lo[0]))
5848
+ continue;
5849
+ const m = pl.m;
5850
+ for (let c = 0;c < 8; c++) {
5851
+ const x = c & 1 ? pr.hi[0] : pr.lo[0], y = c & 2 ? pr.hi[1] : pr.lo[1], z = c & 4 ? pr.hi[2] : pr.lo[2];
5852
+ addPt(m[0] + m[3] * x + m[4] * y + m[5] * z, m[1] + m[6] * x + m[7] * y + m[8] * z, m[2] + m[9] * x + m[10] * y + m[11] * z);
5735
5853
  }
5854
+ }
5855
+ for (const b of studSink.values())
5856
+ for (let i = 0;i < b.P.length; i += 3)
5857
+ addPt(b.P[i], b.P[i + 1], b.P[i + 2]);
5736
5858
  const cx = isFinite(x0) ? (x0 + x1) / 2 : 0, cz = isFinite(z0) ? (z0 + z1) / 2 : 0, by = isFinite(y0) ? y0 : 0;
5859
+ const looks = new Map;
5860
+ const lookFor = (c) => {
5861
+ const hex = hexOf(c), a = alphaOf(c), metal = metalOf(c);
5862
+ const k = hex + "/" + a.toFixed(2) + "/" + metal;
5863
+ let l = looks.get(k);
5864
+ if (!l)
5865
+ looks.set(k, l = { name: `C${looks.size}`, hex, a, metal });
5866
+ return l;
5867
+ };
5868
+ const material = (ind, path, name, hex, a, metal) => {
5869
+ const rgb = [1, 3, 5].map((o) => f(srgbToLinear(parseInt(hex.slice(o, o + 2), 16) / 255), 4));
5870
+ return `${ind}def Material "${name}"
5871
+ ${ind}{
5872
+ ${ind} token outputs:surface.connect = <${path}/${name}/PBR.outputs:surface>
5873
+ ${ind} def Shader "PBR"
5874
+ ${ind} {
5875
+ ${ind} uniform token info:id = "UsdPreviewSurface"
5876
+ ${ind} color3f inputs:diffuseColor = (${rgb.join(", ")})
5877
+ ${ind} float inputs:roughness = ${metal ? 0.2 : 0.35}
5878
+ ${ind} float inputs:metallic = ${metal}
5879
+ ${ind} float inputs:clearcoat = ${metal ? 0 : 0.5}
5880
+ ${a < 1 ? `${ind} float inputs:opacity = ${f(a, 3)}
5881
+ ` : ""}${ind} token outputs:surface
5882
+ ${ind} }
5883
+ ${ind}}
5884
+ `;
5885
+ };
5886
+ let meshes = 0;
5887
+ const meshText = (ind, name, b, bind) => {
5888
+ meshes++;
5889
+ const nt = b.I.length / 3;
5890
+ const pts = new Array(b.P.length / 3);
5891
+ for (let i = 0;i < pts.length; i++)
5892
+ pts[i] = `(${f(b.P[i * 3], 1)},${f(b.P[i * 3 + 1], 1)},${f(b.P[i * 3 + 2], 1)})`;
5893
+ const nrm = new Array(pts.length);
5894
+ for (let i = 0;i < nrm.length; i++)
5895
+ nrm[i] = `(${f(b.N[i * 3], 2)},${f(b.N[i * 3 + 1], 2)},${f(b.N[i * 3 + 2], 2)})`;
5896
+ return `${ind}def Mesh "${name}"${bind ? ` (
5897
+ ${ind} prepend apiSchemas = ["MaterialBindingAPI"]
5898
+ ${ind})` : ""}
5899
+ ${ind}{
5900
+ ${bind ? `${ind} rel material:binding = <${bind}>
5901
+ ` : ""}${ind} uniform token subdivisionScheme = "none"
5902
+ ${ind} int[] faceVertexCounts = [${"3,".repeat(nt - 1)}3]
5903
+ ${ind} int[] faceVertexIndices = [${b.I.join(",")}]
5904
+ ${ind} point3f[] points = [${pts.join(",")}]
5905
+ ${ind} normal3f[] normals = [${nrm.join(",")}] (
5906
+ ${ind} interpolation = "vertex"
5907
+ ${ind} )
5908
+ ${ind}}
5909
+ `;
5910
+ };
5737
5911
  const out = [`#usda 1.0
5738
5912
  (
5739
5913
  customLayerData = { string creator = "ldr toUSDZ" }
@@ -5742,74 +5916,95 @@ function toUSDZ(instances, pack, options = {}) {
5742
5916
  upAxis = "Y"
5743
5917
  )
5744
5918
 
5745
- def Xform "Model" (
5746
- kind = "component"
5747
- )
5748
- {
5749
- double3 xformOp:scale = (${S}, ${S}, ${S})
5750
- uniform token[] xformOpOrder = ["xformOp:scale"]
5751
5919
  `];
5752
- let mi = 0;
5753
- for (const b of buckets.values()) {
5754
- if (!b.I.length)
5755
- continue;
5756
- const name = `C${mi++}`;
5757
- out.push(` def Mesh "${name}" (
5758
- prepend apiSchemas = ["MaterialBindingAPI"]
5759
- )
5760
- {
5761
- uniform bool doubleSided = 1
5762
- rel material:binding = </Model/Looks/${name}>
5763
- uniform token subdivisionScheme = "none"
5920
+ const protoName = new Map;
5921
+ out.push(`class "Protos"
5922
+ {
5764
5923
  `);
5765
- const nt = b.I.length / 3;
5766
- out.push(` int[] faceVertexCounts = [${"3,".repeat(nt - 1)}3]
5767
- int[] faceVertexIndices = [${b.I.join(",")}]
5924
+ for (const [key, pr] of protos) {
5925
+ const n = `P${protoName.size}`;
5926
+ protoName.set(key, n);
5927
+ const base = `/Protos/${n}`;
5928
+ out.push(` def Xform "${n}"
5929
+ {
5768
5930
  `);
5769
- const pts = new Array(b.P.length / 3);
5770
- for (let i = 0;i < pts.length; i++)
5771
- pts[i] = `(${f(b.P[i * 3] - cx, 1)},${f(b.P[i * 3 + 1] - by, 1)},${f(b.P[i * 3 + 2] - cz, 1)})`;
5772
- const nrm = new Array(pts.length);
5773
- for (let i = 0;i < nrm.length; i++)
5774
- nrm[i] = `(${f(b.N[i * 3], 2)},${f(b.N[i * 3 + 1], 2)},${f(b.N[i * 3 + 2], 2)})`;
5775
- out.push(` point3f[] points = [${pts.join(",")}]
5776
- normal3f[] normals = [${nrm.join(",")}] (
5777
- interpolation = "vertex"
5778
- )
5931
+ let j = 0;
5932
+ const mats = [];
5933
+ for (const b of pr.sink.values()) {
5934
+ if (!b.I.length)
5935
+ continue;
5936
+ const mn = `m${j++}`;
5937
+ if (b.inst)
5938
+ out.push(meshText(" ", mn, b, null));
5939
+ else {
5940
+ mats.push(material(" ", `${base}/Looks`, mn, b.hex, b.a, b.metal));
5941
+ out.push(meshText(" ", mn, b, `${base}/Looks/${mn}`));
5942
+ }
5779
5943
  }
5944
+ if (mats.length)
5945
+ out.push(` def Scope "Looks"
5946
+ {
5947
+ ${mats.join("")} }
5948
+ `);
5949
+ out.push(` }
5780
5950
  `);
5781
5951
  }
5782
- out.push(` def Scope "Looks"
5952
+ out.push(`}
5953
+
5954
+ `);
5955
+ const mat = (m) => {
5956
+ const r = (x) => f(x, 4), t = (x) => f(x, 2);
5957
+ return `( (${r(m[3])}, ${r(m[6])}, ${r(m[9])}, 0), (${r(m[4])}, ${r(m[7])}, ${r(m[10])}, 0), (${r(m[5])}, ${r(m[8])}, ${r(m[11])}, 0), (${t(m[0])}, ${t(m[1])}, ${t(m[2])}, 1) )`;
5958
+ };
5959
+ out.push(`def Xform "Model" (
5960
+ kind = "component"
5961
+ )
5962
+ {
5963
+ double3 xformOp:scale = (${S}, ${S}, ${S})
5964
+ uniform token[] xformOpOrder = ["xformOp:scale"]
5965
+ `);
5966
+ out.push(` def Xform "World"
5783
5967
  {
5968
+ matrix4d xformOp:transform = ( (1, 0, 0, 0), (0, ${SY}, 0, 0), (0, 0, ${SY}, 0), (${f(-cx, 2)}, ${f(-by, 2)}, ${f(-cz, 2)}, 1) )
5969
+ uniform token[] xformOpOrder = ["xformOp:transform"]
5784
5970
  `);
5785
- mi = 0;
5786
- for (const b of buckets.values()) {
5787
- if (!b.I.length)
5788
- continue;
5789
- const name = `C${mi++}`;
5790
- const rgb = [1, 3, 5].map((o) => f(srgbToLinear(parseInt(b.hex.slice(o, o + 2), 16) / 255), 4));
5791
- const p = `/Model/Looks/${name}`;
5792
- out.push(` def Material "${name}"
5971
+ placed.forEach((pl, i) => {
5972
+ const pr = protos.get(pl.proto);
5973
+ if (!pr.tris)
5974
+ return;
5975
+ const hasInst = [...pr.sink.values()].some((b) => b.inst && b.I.length);
5976
+ out.push(` def Xform "i${i}" (
5977
+ prepend references = </Protos/${protoName.get(pl.proto)}>${hasInst ? `
5978
+ prepend apiSchemas = ["MaterialBindingAPI"]` : ""}
5979
+ )
5793
5980
  {
5794
- token outputs:surface.connect = <${p}/PBR.outputs:surface>
5795
- def Shader "PBR"
5796
- {
5797
- uniform token info:id = "UsdPreviewSurface"
5798
- color3f inputs:diffuseColor = (${rgb.join(", ")})
5799
- float inputs:roughness = ${b.metal ? 0.2 : 0.35}
5800
- float inputs:metallic = ${b.metal}
5801
- float inputs:clearcoat = ${b.metal ? 0 : 0.5}
5802
- ${b.a < 1 ? ` float inputs:opacity = ${f(b.a, 3)}
5803
- ` : ""} token outputs:surface
5804
- }
5981
+ ${hasInst ? ` rel material:binding = </Model/Looks/${lookFor(pl.color).name}>
5982
+ ` : ""} matrix4d xformOp:transform = ${mat(pl.m)}
5983
+ uniform token[] xformOpOrder = ["xformOp:transform"]
5805
5984
  }
5806
5985
  `);
5986
+ });
5987
+ let si = 0;
5988
+ for (const b of studSink.values()) {
5989
+ if (!b.I.length)
5990
+ continue;
5991
+ const k = b.hex + "/" + b.a.toFixed(2) + "/" + b.metal;
5992
+ let l = looks.get(k);
5993
+ if (!l)
5994
+ looks.set(k, l = { name: `C${looks.size}`, hex: b.hex, a: b.a, metal: b.metal });
5995
+ out.push(meshText(" ", `S${si++}`, b, `/Model/Looks/${l.name}`));
5807
5996
  }
5808
5997
  out.push(` }
5998
+ def Scope "Looks"
5999
+ {
6000
+ `);
6001
+ for (const l of looks.values())
6002
+ out.push(material(" ", "/Model/Looks", l.name, l.hex, l.a, l.metal));
6003
+ out.push(` }
5809
6004
  }
5810
6005
  `);
5811
6006
  const usda = new TextEncoder().encode(out.join(""));
5812
- return { data: zipStored([{ name: "model.usda", data: usda }]), triangles: tris, meshes: mi, level: { body: L, studs: sm } };
6007
+ return { data: zipStored([{ name: "model.usda", data: usda }]), triangles: tris, meshes, prototypes: protos.size, level: { maxErr: E, studs: sm }, hiddenParts: hidden ? hidden.reduce((a, x) => a + x, 0) : 0 };
5813
6008
  }
5814
6009
  var crcT = null;
5815
6010
  function crc32(d) {
@@ -5883,7 +6078,102 @@ function zipStored(files) {
5883
6078
  }
5884
6079
  return out;
5885
6080
  }
5886
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/library.ts
6081
+ function hiddenInstances(n, items, geo, clear, RES = 512) {
6082
+ const seen = new Uint8Array(n);
6083
+ const tri = [], ids = [];
6084
+ let lo = [Infinity, Infinity, Infinity], hi = [-Infinity, -Infinity, -Infinity];
6085
+ for (const it of items) {
6086
+ if (clear(it.color)) {
6087
+ seen[it.k] = 1;
6088
+ continue;
6089
+ }
6090
+ const g = geo(it);
6091
+ if (!g)
6092
+ continue;
6093
+ const m = it.m;
6094
+ const T = new Float32Array(g.tris * 9);
6095
+ for (let t = 0;t < g.tris * 3; t++) {
6096
+ const i = g.idx ? g.idx[t] : t;
6097
+ const x = g.pos[i * 3], y = g.pos[i * 3 + 1], z = g.pos[i * 3 + 2];
6098
+ const wx = m[0] + m[3] * x + m[4] * y + m[5] * z, wy = m[1] + m[6] * x + m[7] * y + m[8] * z, wz = m[2] + m[9] * x + m[10] * y + m[11] * z;
6099
+ T[t * 3] = wx;
6100
+ T[t * 3 + 1] = wy;
6101
+ T[t * 3 + 2] = wz;
6102
+ if (wx < lo[0])
6103
+ lo[0] = wx;
6104
+ if (wy < lo[1])
6105
+ lo[1] = wy;
6106
+ if (wz < lo[2])
6107
+ lo[2] = wz;
6108
+ if (wx > hi[0])
6109
+ hi[0] = wx;
6110
+ if (wy > hi[1])
6111
+ hi[1] = wy;
6112
+ if (wz > hi[2])
6113
+ hi[2] = wz;
6114
+ }
6115
+ tri.push(T);
6116
+ ids.push(it.k);
6117
+ }
6118
+ if (!tri.length)
6119
+ return new Uint8Array(n);
6120
+ const c = [0, 1, 2].map((a) => (lo[a] + hi[a]) / 2), rad = Math.hypot(hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]) / 2 || 1;
6121
+ const dirs = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]];
6122
+ for (const sx of [-1, 1])
6123
+ for (const sy of [-1, 1])
6124
+ for (const sz of [-1, 1])
6125
+ dirs.push([sx, sy, sz].map((v) => v / Math.sqrt(3)));
6126
+ const Z = new Float32Array(RES * RES), ID = new Int32Array(RES * RES);
6127
+ const sc = (RES / 2 - 1) / rad;
6128
+ for (const d of dirs) {
6129
+ const up = Math.abs(d[1]) > 0.9 ? [1, 0, 0] : [0, 1, 0];
6130
+ const u = [up[1] * d[2] - up[2] * d[1], up[2] * d[0] - up[0] * d[2], up[0] * d[1] - up[1] * d[0]];
6131
+ const ul = Math.hypot(u[0], u[1], u[2]);
6132
+ u[0] /= ul;
6133
+ u[1] /= ul;
6134
+ u[2] /= ul;
6135
+ const v = [d[1] * u[2] - d[2] * u[1], d[2] * u[0] - d[0] * u[2], d[0] * u[1] - d[1] * u[0]];
6136
+ Z.fill(Infinity);
6137
+ ID.fill(-1);
6138
+ for (let q = 0;q < tri.length; q++) {
6139
+ const T = tri[q], id = ids[q];
6140
+ for (let t = 0;t < T.length; t += 9) {
6141
+ const P = [0, 3, 6].map((o) => {
6142
+ const x = T[t + o] - c[0], y = T[t + o + 1] - c[1], z = T[t + o + 2] - c[2];
6143
+ return [(x * u[0] + y * u[1] + z * u[2]) * sc + RES / 2, (x * v[0] + y * v[1] + z * v[2]) * sc + RES / 2, -(x * d[0] + y * d[1] + z * d[2])];
6144
+ });
6145
+ const [A, B, C] = P;
6146
+ const area = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
6147
+ if (area === 0)
6148
+ continue;
6149
+ const x0 = Math.max(0, Math.floor(Math.min(A[0], B[0], C[0]))), x1 = Math.min(RES - 1, Math.ceil(Math.max(A[0], B[0], C[0])));
6150
+ const y0 = Math.max(0, Math.floor(Math.min(A[1], B[1], C[1]))), y1 = Math.min(RES - 1, Math.ceil(Math.max(A[1], B[1], C[1])));
6151
+ const ia = 1 / area;
6152
+ for (let y = y0;y <= y1; y++)
6153
+ for (let x = x0;x <= x1; x++) {
6154
+ const px = x + 0.5, py = y + 0.5;
6155
+ const w0 = ((B[0] - px) * (C[1] - py) - (B[1] - py) * (C[0] - px)) * ia, w1 = ((C[0] - px) * (A[1] - py) - (C[1] - py) * (A[0] - px)) * ia, w2 = 1 - w0 - w1;
6156
+ if (w0 < 0 || w1 < 0 || w2 < 0)
6157
+ continue;
6158
+ const z = w0 * A[2] + w1 * B[2] + w2 * C[2];
6159
+ const o = y * RES + x;
6160
+ if (z < Z[o]) {
6161
+ Z[o] = z;
6162
+ ID[o] = id;
6163
+ }
6164
+ }
6165
+ }
6166
+ }
6167
+ for (let o = 0;o < ID.length; o++)
6168
+ if (ID[o] >= 0)
6169
+ seen[ID[o]] = 1;
6170
+ }
6171
+ const hidden = new Uint8Array(n);
6172
+ for (let k = 0;k < n; k++)
6173
+ hidden[k] = seen[k] ? 0 : 1;
6174
+ return hidden;
6175
+ }
6176
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/library.ts
5887
6177
  import { existsSync, readFileSync, statSync } from "fs";
5888
6178
  import { join } from "path";
5889
6179
  var xf = (m, x, y, z) => [m[3] * x + m[4] * y + m[5] * z + m[0], m[6] * x + m[7] * y + m[8] * z + m[1], m[9] * x + m[10] * y + m[11] * z + m[2]];
@@ -6233,11 +6523,11 @@ class Library {
6233
6523
  return insts;
6234
6524
  }
6235
6525
  }
6236
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/build-pack.ts
6526
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/build-pack.ts
6237
6527
  import fs3 from "node:fs";
6238
6528
  import path3 from "node:path";
6239
6529
 
6240
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/resolver.ts
6530
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/resolver.ts
6241
6531
  import fs from "node:fs";
6242
6532
  import path from "node:path";
6243
6533
  var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
@@ -6270,7 +6560,7 @@ function compose(a, b) {
6270
6560
  const t = xf2(a, [b[0], b[1], b[2]]);
6271
6561
  return [t[0], t[1], t[2], r(0, 0), r(0, 1), r(0, 2), r(1, 0), r(1, 1), r(1, 2), r(2, 0), r(2, 1), r(2, 2)];
6272
6562
  }
6273
- var IDENT = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
6563
+ var IDENT2 = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
6274
6564
 
6275
6565
  class Library2 {
6276
6566
  root;
@@ -6566,11 +6856,11 @@ function collectDeps(lib, refs) {
6566
6856
  return out;
6567
6857
  }
6568
6858
 
6569
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/compile.ts
6859
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/compile.ts
6570
6860
  import fs2 from "node:fs";
6571
6861
  import path2 from "node:path";
6572
6862
 
6573
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/lod.ts
6863
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/lod.ts
6574
6864
  import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
6575
6865
  await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
6576
6866
  function reorderMesh(P, N, C, I) {
@@ -6876,7 +7166,7 @@ function levelLines(P, I, E, err, always, tol = 0.01) {
6876
7166
  return out;
6877
7167
  }
6878
7168
 
6879
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/compile.ts
7169
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/compile.ts
6880
7170
  class BfcState {
6881
7171
  accum;
6882
7172
  ccw = true;
@@ -7015,7 +7305,7 @@ class Compiler {
7015
7305
  }
7016
7306
  return true;
7017
7307
  };
7018
- const r = walk(key, IDENT, 0);
7308
+ const r = walk(key, IDENT2, 0);
7019
7309
  this.flat.set(key, r);
7020
7310
  return r;
7021
7311
  }
@@ -7164,7 +7454,7 @@ class Compiler {
7164
7454
  const fullKind = new Map;
7165
7455
  let culled = 0;
7166
7456
  const back = { body: { pos: [], col: [] }, under: { pos: [], col: [] } };
7167
- walk(key, IDENT, "16", false, "body", 0);
7457
+ walk(key, IDENT2, "16", false, "body", 0);
7168
7458
  if (back.body.pos.length || back.under.pos.length) {
7169
7459
  if (!culled)
7170
7460
  out.uncertified = true;
@@ -7397,7 +7687,7 @@ class Compiler {
7397
7687
  }
7398
7688
  open.delete(fk);
7399
7689
  };
7400
- walk(key, IDENT, "16", false, "body", 0, null);
7690
+ walk(key, IDENT2, "16", false, "body", 0, null);
7401
7691
  if (texb.size) {
7402
7692
  out.tbody = tbody;
7403
7693
  out.texb = texb;
@@ -7820,7 +8110,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
7820
8110
  return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
7821
8111
  }
7822
8112
 
7823
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/build-pack.ts
8113
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/build-pack.ts
7824
8114
  function packCompilerOpts(o) {
7825
8115
  return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures, ...o.partWorkLimit ? { workLimit: o.partWorkLimit } : {} };
7826
8116
  }
@@ -7892,7 +8182,7 @@ function buildPack(o) {
7892
8182
  const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
7893
8183
  return { data: encodePack(parts, kinds, comp.opts.weld, extra, { texture, lod: o.lod !== false, reorder: !!o.reorder }), parts: parts.size, studKinds: kinds.size, missing: [...missing], ...warnings.length ? { warnings } : {} };
7894
8184
  }
7895
- // ../../../../../../../tmp/ldr-build-UFH0qj/src/node/promote.ts
8185
+ // ../../../../../../../tmp/ldr-build-tT1uYu/src/node/promote.ts
7896
8186
  var GEOM = /^\s*[2-5]\s/;
7897
8187
  var REF = /^\s*1\s/;
7898
8188
  var FILE = /^\s*0\s+FILE\s+(\S.*?)\s*$/i;