ldr 0.33.1 → 0.33.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-78cdvu/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-5tVh0D/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;
@@ -25,6 +25,8 @@ function parseColor(tok) {
25
25
  }
26
26
  var MOVED_RE = /^~?\s*moved\s+to\s+(.+)$/i;
27
27
  var SPECIAL0 = new Set(["FILE", "NOFILE", "!DATA", "!:", "STEP", "BFC", "ROTSTEP", "BUFEXCHG", "!TEXMAP"]);
28
+ var BLOCK0 = new Set(["FILE", "NOFILE", "!DATA"]);
29
+ var MAX_COORD = 1000000000000000;
28
30
  var PART_ORG = new Set(["part", "subpart", "primitive", "8_primitive", "48_primitive", "shortcut", "helper"]);
29
31
  var MODEL_ORG = new Set(["model", "submodel", "configuration"]);
30
32
  var ORG_RE = /^(?:!?LDRAW_ORG|Unofficial|Official\s+LCAD)\s+(\S+)/i;
@@ -75,7 +77,9 @@ function parseTexMap(tail, next = false) {
75
77
  if (parts.length < n + 1)
76
78
  return null;
77
79
  const v = parts.slice(0, n).map(Number);
78
- if (!v.every(Number.isFinite))
80
+ if (!v.every((x) => Number.isFinite(x) && Math.abs(x) <= 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))
81
+ return null;
82
+ if (n >= 10 && !(Math.abs(v[9]) >= 0.000001) || n === 11 && !(Math.abs(v[10]) >= 0.000001))
79
83
  return null;
80
84
  let rest = m[2].trim();
81
85
  for (let k = 0;k < n; k++)
@@ -96,7 +100,9 @@ function parseTexMap(tail, next = false) {
96
100
  return t;
97
101
  }
98
102
  var b64 = (s) => {
99
- const clean = s.replace(/[^A-Za-z0-9+/]/g, "");
103
+ let clean = s.replace(/[^A-Za-z0-9+/]/g, "");
104
+ if (clean.length % 4 === 1)
105
+ clean = clean.slice(0, -1);
100
106
  const pad = clean + "=".repeat((4 - clean.length % 4) % 4);
101
107
  const bin = atob(pad);
102
108
  const out = new Uint8Array(bin.length);
@@ -124,7 +130,10 @@ function type1Fast(line) {
124
130
  const t = next();
125
131
  if (t === null)
126
132
  return null;
127
- m[k] = +t;
133
+ const v = +t;
134
+ if (!Number.isFinite(v))
135
+ return null;
136
+ m[k] = v;
128
137
  }
129
138
  while (i < n && ws(line.charCodeAt(i)))
130
139
  i++;
@@ -132,23 +141,37 @@ function type1Fast(line) {
132
141
  return null;
133
142
  const rest = line.slice(i);
134
143
  const file = /[ \t]{2,}|\t/.test(rest) ? rest.split(/\s+/).join(" ") : rest;
135
- return { t: 1, color: parseColor(ct), m, file: norm(file) };
144
+ const color = parseColor(ct);
145
+ if (!Number.isFinite(color))
146
+ return null;
147
+ return { t: 1, color, m, file: norm(file) };
136
148
  }
149
+ var NUMS = [0, 12, 6, 9, 12, 12];
137
150
  function geomLine(tk) {
138
151
  const t = +tk[0];
139
- if (!(t >= 1 && t <= 5) || tk.length < 2)
152
+ if (!(t >= 1 && t <= 5 && Number.isInteger(t)) || tk.length < 2)
140
153
  return null;
141
- const color = parseColor(tk[1]);
142
- const nums = tk.slice(2).map(Number);
143
- if (t === 1)
144
- return { t: 1, color, m: nums.slice(0, 12), file: norm(tk.slice(14).join(" ")) };
154
+ const color = parseColor(tk[1]), n = NUMS[t];
155
+ if (!Number.isFinite(color) || tk.length < 2 + n + (t === 1 ? 1 : 0))
156
+ return null;
157
+ const nums = new Array(n);
158
+ for (let k = 0;k < n; k++) {
159
+ const v = +tk[2 + k];
160
+ if (!Number.isFinite(v))
161
+ return null;
162
+ nums[k] = v;
163
+ }
164
+ if (t === 1) {
165
+ const file = norm(tk.slice(14).join(" "));
166
+ return file ? { t: 1, color, m: nums, file } : null;
167
+ }
145
168
  if (t === 2)
146
- return { t: 2, color, p: nums.slice(0, 6) };
169
+ return { t: 2, color, p: nums };
147
170
  if (t === 3)
148
- return { t: 3, color, p: nums.slice(0, 9) };
171
+ return { t: 3, color, p: nums };
149
172
  if (t === 4)
150
- return { t: 4, color, p: nums.slice(0, 12) };
151
- return { t: 5, color, p: nums.slice(0, 12) };
173
+ return { t: 4, color, p: nums };
174
+ return { t: 5, color, p: nums };
152
175
  }
153
176
  function parse(src, name = "main.ldr", popts = {}) {
154
177
  const gtext = !!popts.geometryText;
@@ -228,7 +251,8 @@ function parse(src, name = "main.ldr", popts = {}) {
228
251
  while (b < line.length && line.charCodeAt(b) !== 32 && line.charCodeAt(b) !== 9)
229
252
  b++;
230
253
  const kw = line.slice(a, b);
231
- if (!SPECIAL0.has(kw)) {
254
+ const k2 = /[^\x21-\x7e]/.test(kw) ? line.slice(a).trim().split(/\s+/)[0] : kw;
255
+ if (!SPECIAL0.has(k2) && !(k2.length >= 4 && k2.length <= 6 && BLOCK0.has(k2.toUpperCase()))) {
232
256
  if (skip || dataCur)
233
257
  continue;
234
258
  if (!cur)
@@ -269,19 +293,23 @@ function parse(src, name = "main.ldr", popts = {}) {
269
293
  const t = +tk[0];
270
294
  if (t === 0) {
271
295
  const text = line.slice(1).trim();
272
- if (tk[1] === "FILE") {
273
- firstBlock();
274
- skip = false;
275
- start(text.slice(5));
276
- continue;
296
+ const k1 = tk.length > 1 && tk[1].length >= 4 && tk[1].length <= 6 ? tk[1].toUpperCase() : tk[1];
297
+ if (k1 === "FILE") {
298
+ const fn = text.slice(5).trimStart().split("\r")[0].trim();
299
+ if (fn) {
300
+ firstBlock();
301
+ skip = false;
302
+ start(fn);
303
+ continue;
304
+ }
277
305
  }
278
- if (tk[1] === "NOFILE") {
306
+ if (k1 === "NOFILE") {
279
307
  closeData();
280
308
  cur = null;
281
309
  skip = true;
282
310
  continue;
283
311
  }
284
- if (tk[1] === "!DATA") {
312
+ if (k1 === "!DATA") {
285
313
  firstBlock();
286
314
  closeData();
287
315
  cur = null;
@@ -314,7 +342,11 @@ function parse(src, name = "main.ldr", popts = {}) {
314
342
  c.rotstep = { x: 0, y: 0, z: 0, mode: "END" };
315
343
  else {
316
344
  const mode = (tk[5] ?? "REL").toUpperCase();
317
- c.rotstep = { x: +tk[2] || 0, y: +tk[3] || 0, z: +tk[4] || 0, mode: ["REL", "ABS", "ADD"].includes(mode) ? mode : "REL" };
345
+ const ang = (s) => {
346
+ const v = Number(s);
347
+ return Number.isFinite(v) ? v : 0;
348
+ };
349
+ c.rotstep = { x: ang(tk[2]), y: ang(tk[3]), z: ang(tk[4]), mode: ["REL", "ABS", "ADD"].includes(mode) ? mode : "REL" };
318
350
  }
319
351
  } else if (tk[1] === "BUFEXCHG") {
320
352
  c.meta = "BUFEXCHG";
@@ -373,8 +405,11 @@ function parse(src, name = "main.ldr", popts = {}) {
373
405
  if (!cur)
374
406
  start(name);
375
407
  const g = geomLine(tk);
376
- if (!g)
408
+ if (!g) {
409
+ if (/^[2-5][ \t]/.test(line))
410
+ inHeader = false;
377
411
  continue;
412
+ }
378
413
  annotate(g, false);
379
414
  cur.cmds.push(g);
380
415
  inHeader = false;
@@ -449,12 +484,18 @@ function texmapTriangleUV(map, pts) {
449
484
  } else {
450
485
  const pd = unit3(sub3(p, p1));
451
486
  const c = dot3(pd, n);
487
+ const q = radial(p, p1, n);
452
488
  if (Math.abs(c) > 1 - 0.000000001) {
453
489
  miss.push(i);
454
490
  out[i * 2 + 1] = 0.5 + (c > 0 ? -Math.PI / 2 : Math.PI / 2) / B;
455
491
  return;
456
492
  }
457
- const a = sAng(radial(p, p1, n));
493
+ if (!q) {
494
+ miss.push(i);
495
+ out[i * 2 + 1] = 0.5;
496
+ return;
497
+ }
498
+ const a = sAng(q);
458
499
  uSum += a;
459
500
  out[i * 2] = 0.5 + a / A;
460
501
  const th = -a, ct = Math.cos(th), st = Math.sin(th), cr = cross3(n, pd), k = dot3(n, pd) * (1 - ct);
@@ -529,18 +570,48 @@ function smoothNormals(pos, edges, cond, creaseDeg = 35) {
529
570
  };
530
571
  for (const [key, corners] of byV) {
531
572
  const faces = corners.map((c) => c / 3 | 0), par = faces.map((_, i) => i);
532
- const f = (i) => par[i] === i ? i : par[i] = f(par[i]);
533
- for (let i = 0;i < faces.length; i++)
534
- for (let j = i + 1;j < faces.length; j++) {
535
- const A = faces[i], B = faces[j];
536
- const va = [0, 1, 2].map((k) => vk[A * 3 + k]), vb = new Set([0, 1, 2].map((k) => vk[B * 3 + k]));
537
- for (const o of va)
538
- if (o !== key && vb.has(o)) {
539
- const e = ek(key, o);
540
- if ((edgeFaces.get(e)?.length ?? 0) >= 2 && joinable(e, A, B))
541
- par[f(i)] = f(j);
542
- }
573
+ const f = (i) => {
574
+ let r = i;
575
+ while (par[r] !== r)
576
+ r = par[r];
577
+ while (par[i] !== r) {
578
+ const n = par[i];
579
+ par[i] = r;
580
+ i = n;
543
581
  }
582
+ return r;
583
+ };
584
+ const byO = new Map;
585
+ for (let i = 0;i < faces.length; i++) {
586
+ const A = faces[i];
587
+ for (let k = 0;k < 3; k++) {
588
+ const o = vk[A * 3 + k];
589
+ if (o === key)
590
+ continue;
591
+ const l = byO.get(o);
592
+ if (!l)
593
+ byO.set(o, [i]);
594
+ else if (l[l.length - 1] !== i)
595
+ l.push(i);
596
+ }
597
+ }
598
+ for (const [o, L] of byO) {
599
+ if (L.length < 2)
600
+ continue;
601
+ const e = ek(key, o);
602
+ if ((edgeFaces.get(e)?.length ?? 0) < 2)
603
+ continue;
604
+ if (L.length > 256) {
605
+ for (let a = 0;a + 1 < L.length; a++)
606
+ if (joinable(e, faces[L[a]], faces[L[a + 1]]))
607
+ par[f(L[a])] = f(L[a + 1]);
608
+ continue;
609
+ }
610
+ for (let a = 0;a < L.length; a++)
611
+ for (let b = a + 1;b < L.length; b++)
612
+ if (joinable(e, faces[L[a]], faces[L[b]]))
613
+ par[f(L[a])] = f(L[b]);
614
+ }
544
615
  const acc = new Map;
545
616
  faces.forEach((F, i) => {
546
617
  const r = f(i), s = acc.get(r) ?? [0, 0, 0];
@@ -657,6 +728,29 @@ function invert(m) {
657
728
  const r = [A * k, -(b * i - c * h) * k, (b * f - c * e) * k, B * k, (a * i - c * g) * k, -(a * f - c * d) * k, C * k, -(a * h - b * g) * k, (a * e - b * d) * k];
658
729
  return [-(r[0] * x + r[1] * y + r[2] * z), -(r[3] * x + r[4] * y + r[5] * z), -(r[6] * x + r[7] * y + r[8] * z), ...r];
659
730
  }
731
+ function singularFix(m, flatY) {
732
+ const det = (q) => q[3] * (q[7] * q[11] - q[8] * q[10]) - q[4] * (q[6] * q[11] - q[8] * q[9]) + q[5] * (q[6] * q[10] - q[7] * q[9]);
733
+ const rows = Math.hypot(m[3], m[4], m[5]) * Math.hypot(m[6], m[7], m[8]) * Math.hypot(m[9], m[10], m[11]);
734
+ if (!(Math.abs(det(m)) <= 0.000000001 * rows))
735
+ return null;
736
+ if (!flatY())
737
+ return { m, cull: false };
738
+ const q = [...m];
739
+ const ok = () => Math.abs(det(q)) > 0.000000001 * Math.hypot(q[3], q[4], q[5]) * Math.hypot(q[6], q[7], q[8]) * Math.hypot(q[9], q[10], q[11]);
740
+ for (let i = 0;i < 3; i++)
741
+ if (q[3 + 3 * i] === 0 && q[4 + 3 * i] === 0 && q[5 + 3 * i] === 0) {
742
+ q[4 + 3 * i] = 1;
743
+ if (ok())
744
+ return { m: q, cull: true };
745
+ }
746
+ if (q[4] === 0 && q[7] === 0 && q[10] === 0)
747
+ for (let i = 0;i < 3; i++) {
748
+ q[4 + 3 * i] = 1;
749
+ if (ok())
750
+ return { m: q, cull: true };
751
+ }
752
+ return { m, cull: false };
753
+ }
660
754
  var num = (x) => String(+x.toFixed(6) || 0);
661
755
  var quote = (s) => '"' + s.replace(/\\/g, "\\\\").replace(/"/g, "\\\"") + '"';
662
756
  function texWrapper(part, map) {
@@ -708,7 +802,22 @@ function fileStepViews(f) {
708
802
  viewMemo.set(f, out);
709
803
  return out;
710
804
  }
711
- // ../../../../../../../tmp/ldr-build-78cdvu/src/model.ts
805
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/model.ts
806
+ class ModelLimitError extends Error {
807
+ limit;
808
+ code = "ldr-model-limit";
809
+ constructor(what, limit) {
810
+ super(`ldr: ${what} expands past ${limit.toLocaleString("en-US")} (see maxInstances)`);
811
+ this.limit = limit;
812
+ this.name = "ModelLimitError";
813
+ }
814
+ }
815
+ var inRange12 = (m) => {
816
+ for (let i = 0;i < 12; i++)
817
+ if (!(Math.abs(m[i]) <= MAX_COORD))
818
+ return false;
819
+ return true;
820
+ };
712
821
  var CALLOUT_END = 999999;
713
822
  var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
714
823
  var defLine = new WeakMap;
@@ -743,6 +852,9 @@ function flatten(doc, opts = {}) {
743
852
  const loose = opts.looseGeometry !== false, tx = !!opts.textures, co = !!opts.callouts;
744
853
  const src = new Map;
745
854
  let subs = 0;
855
+ const open = new Set;
856
+ const maxN = opts.maxInstances ?? 2000000;
857
+ let work = 0;
746
858
  const lazy = (f, k) => {
747
859
  const key = f.name + "#" + k;
748
860
  let fn = src.get(key);
@@ -755,8 +867,11 @@ function flatten(doc, opts = {}) {
755
867
  };
756
868
  const walk = (d, fname, m, color, path, stepPath, depth, texIn, fixed = null, subPath = [], subMats = [], colour = undefined, scope0 = null) => {
757
869
  const f = d.files.get(fname);
758
- if (!f || depth > maxDepth)
870
+ if (!f || depth > maxDepth || open.has(f))
759
871
  return;
872
+ if (++work > maxN)
873
+ throw new ModelLimitError("model", maxN);
874
+ open.add(f);
760
875
  let scope = scope0;
761
876
  let s = 0;
762
877
  const subId = depth > 0 ? ++subs : 0;
@@ -784,6 +899,8 @@ function flatten(doc, opts = {}) {
784
899
  const emit = (part, col, mm, sp, k, embedded, tex, cd, sc) => {
785
900
  if (fixed)
786
901
  sp = fixed;
902
+ if (++work > maxN)
903
+ throw new ModelLimitError("model", maxN);
787
904
  const i = { part, color: col, m: mm, step: sp[0], steps: sp, localStep: k, path };
788
905
  if (cd)
789
906
  i.colour = cd;
@@ -845,7 +962,10 @@ function flatten(doc, opts = {}) {
845
962
  continue;
846
963
  if (tx && c.fallback)
847
964
  continue;
848
- const col = c.color === 16 ? color : c.color, cd = c.color === 16 ? colour : scope?.get(c.color), mm = mul(m, c.m), sp = [...stepPath, s];
965
+ const mm = mul(m, c.m);
966
+ if (!inRange12(mm))
967
+ continue;
968
+ const col = c.color === 16 ? color : c.color, cd = c.color === 16 ? colour : scope?.get(c.color), sp = [...stepPath, s];
849
969
  const tex = tx ? c.tex ?? texIn : null;
850
970
  const local = tex ? invert(c.m) : null;
851
971
  const lt = tex && local ? transformTexMap(tex, local) : null;
@@ -865,6 +985,7 @@ function flatten(doc, opts = {}) {
865
985
  emit(c.file, col, mm, sp, s, false, lt, cd, scope);
866
986
  }
867
987
  flushLoose(Infinity);
988
+ open.delete(f);
868
989
  if (groups) {
869
990
  for (const g of groups.values())
870
991
  if (g.n > 1)
@@ -1122,7 +1243,7 @@ function blendedColourHex(code) {
1122
1243
  const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
1123
1244
  return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
1124
1245
  }
1125
- // ../../../../../../../tmp/ldr-build-78cdvu/src/instructions.ts
1246
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/instructions.ts
1126
1247
  var MIN_VIS = 0.5;
1127
1248
  var REORIENT = 0.35;
1128
1249
  var deg = Math.PI / 180;
@@ -1490,10 +1611,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1490
1611
  }
1491
1612
  };
1492
1613
  }
1493
- // ../../../../../../../tmp/ldr-build-78cdvu/src/render.ts
1614
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/render.ts
1494
1615
  import * as THREE from "three";
1495
1616
 
1496
- // ../../../../../../../tmp/ldr-build-78cdvu/src/pack-io.ts
1617
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/pack-io.ts
1497
1618
  import { decompress } from "fzstd";
1498
1619
  async function decompressPack(data) {
1499
1620
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1516,7 +1637,7 @@ function decodePack(buf) {
1516
1637
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1517
1638
  }
1518
1639
 
1519
- // ../../../../../../../tmp/ldr-build-78cdvu/src/cull.ts
1640
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/cull.ts
1520
1641
  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;
1521
1642
  var prepCache = new WeakMap;
1522
1643
  function prepPart(H, part) {
@@ -1562,6 +1683,7 @@ function mul12To(a, b, bo, w, ao = 0) {
1562
1683
  w[3 + i * 3 + j] = a[ao + 3 + i * 3] * b[bo + 3 + j] + a[ao + 4 + i * 3] * b[bo + 6 + j] + a[ao + 5 + i * 3] * b[bo + 9 + j];
1563
1684
  }
1564
1685
  var det12 = (m) => 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]);
1686
+ var singular12 = (m, d = det12(m)) => d * d <= 0.000000000000000001 * (m[3] * m[3] + m[4] * m[4] + m[5] * m[5]) * (m[6] * m[6] + m[7] * m[7] + m[8] * m[8]) * (m[9] * m[9] + m[10] * m[10] + m[11] * m[11]);
1565
1687
  var BIG = 1073741824;
1566
1688
 
1567
1689
  class Int3Table {
@@ -1671,7 +1793,7 @@ function cullCore(insts, H, steps) {
1671
1793
  clear.set(c, v = seeThrough(H, c));
1672
1794
  return v;
1673
1795
  };
1674
- const rx0 = [], rx1 = [], rz0 = [], rz1 = [], rInst = [], rPrep = [], rBx = [], rBz = [];
1796
+ const rx0 = [], rx1 = [], rz0 = [], rz1 = [], rInst = [], rInst2 = [], rPrep = [], rBx = [], rBz = [];
1675
1797
  const cells = new Int3Table(insts.length * 2);
1676
1798
  const nextE = [], rectE = [];
1677
1799
  for (let idx = 0;idx < insts.length; idx++) {
@@ -1695,18 +1817,49 @@ function cullCore(insts, H, steps) {
1695
1817
  if (wz > z1)
1696
1818
  z1 = wz;
1697
1819
  }
1820
+ const lv2 = Math.round((m[1] + b[4]) * 2);
1821
+ const pp = prepPart(H, it.part);
1822
+ const cx0 = Math.floor(x0 / CELL), cx1 = Math.floor(x1 / CELL), cz0 = Math.floor(z0 / CELL), cz1 = Math.floor(z1 / CELL);
1823
+ if (!((cx1 - cx0 + 1) * (cz1 - cz0 + 1) <= 65536) || !inRange(lv2, cx0, cz0) || !inRange(lv2, cx1, cz1))
1824
+ continue;
1825
+ let dup = -1;
1826
+ for (let e = cells.get(lv2, cx0, cz0), k = 0;e >= 0 && k < 8; e = nextE[e], k++) {
1827
+ const q = rectE[e];
1828
+ if (rx0[q] !== x0 || rx1[q] !== x1 || rz0[q] !== z0 || rz1[q] !== z1 || rPrep[q] !== pp)
1829
+ continue;
1830
+ const qm = insts[rInst[q]].m;
1831
+ let same = true;
1832
+ for (let i = 0;i < 12; i++)
1833
+ if (qm[i] !== m[i]) {
1834
+ same = false;
1835
+ break;
1836
+ }
1837
+ if (same) {
1838
+ dup = q;
1839
+ break;
1840
+ }
1841
+ }
1842
+ if (dup >= 0) {
1843
+ const st = steps ? steps[idx] : 0;
1844
+ if (steps && st < steps[rInst[dup]]) {
1845
+ rInst2[dup] = rInst[dup];
1846
+ rInst[dup] = idx;
1847
+ } else if (rInst2[dup] < 0 || steps && st < steps[rInst2[dup]])
1848
+ rInst2[dup] = idx;
1849
+ continue;
1850
+ }
1698
1851
  const ri = rInst.length;
1699
1852
  rx0.push(x0);
1700
1853
  rx1.push(x1);
1701
1854
  rz0.push(z0);
1702
1855
  rz1.push(z1);
1703
1856
  rInst.push(idx);
1704
- rPrep.push(prepPart(H, it.part));
1857
+ rInst2.push(-1);
1858
+ rPrep.push(pp);
1705
1859
  rBx.push(b[0]);
1706
1860
  rBz.push(b[2]);
1707
- const lv2 = Math.round((m[1] + b[4]) * 2);
1708
- for (let cx = Math.floor(x0 / CELL);cx <= Math.floor(x1 / CELL); cx++)
1709
- for (let cz = Math.floor(z0 / CELL);cz <= Math.floor(z1 / CELL); cz++) {
1861
+ for (let cx = cx0;cx <= cx1; cx++)
1862
+ for (let cz = cz0;cz <= cz1; cz++) {
1710
1863
  if (!inRange(lv2, cx, cz))
1711
1864
  continue;
1712
1865
  const e = rectE.length;
@@ -1729,7 +1882,10 @@ function cullCore(insts, H, steps) {
1729
1882
  }
1730
1883
  for (let e = ke;e >= 0; e = nextE[e]) {
1731
1884
  const ri = rectE[e];
1732
- if (rInst[ri] === self || !(x - 6 >= rx0[ri] - 0.5 && x + 6 <= rx1[ri] + 0.5 && z - 6 >= rz0[ri] - 0.5 && z + 6 <= rz1[ri] + 0.5))
1885
+ let by = rInst[ri];
1886
+ if (by === self && (by = rInst2[ri]) < 0)
1887
+ continue;
1888
+ if (!(x - 6 >= rx0[ri] - 0.5 && x + 6 <= rx1[ri] + 0.5 && z - 6 >= rz0[ri] - 0.5 && z + 6 <= rz1[ri] + 0.5))
1733
1889
  continue;
1734
1890
  const m = insts[rInst[ri]].m;
1735
1891
  const pp = rPrep[ri];
@@ -1748,7 +1904,7 @@ function cullCore(insts, H, steps) {
1748
1904
  if (ok) {
1749
1905
  if (!steps)
1750
1906
  return 0;
1751
- const st = steps[rInst[ri]];
1907
+ const st = steps[by];
1752
1908
  if (st < best)
1753
1909
  best = st;
1754
1910
  }
@@ -1864,7 +2020,7 @@ function precomputeCull(instances, H, useTex = true) {
1864
2020
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
1865
2021
  }
1866
2022
 
1867
- // ../../../../../../../tmp/ldr-build-78cdvu/src/render.ts
2023
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/render.ts
1868
2024
  async function loadPack(url) {
1869
2025
  const res = await fetch(url);
1870
2026
  if (!res.ok)
@@ -1883,10 +2039,13 @@ var toU8 = (a) => {
1883
2039
  o[i] = Math.round(Math.max(0, Math.min(1, a[i])) * 255);
1884
2040
  return o;
1885
2041
  };
2042
+ var F16_MAX = 65504;
1886
2043
  var toF16 = (a) => {
1887
2044
  const o = new Uint16Array(a.length);
1888
- for (let i = 0;i < a.length; i++)
1889
- o[i] = THREE.DataUtils.toHalfFloat(a[i]);
2045
+ for (let i = 0;i < a.length; i++) {
2046
+ const v = a[i];
2047
+ o[i] = THREE.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
2048
+ }
1890
2049
  return o;
1891
2050
  };
1892
2051
  function keepHalf(bm) {
@@ -2964,8 +3123,8 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
2964
3123
  const p = H.parts[it.part];
2965
3124
  if (!p)
2966
3125
  continue;
2967
- const mirror = det12(it.m) < 0;
2968
- const mat = materialFor(String(it.color), mirror, !!p.uncert);
3126
+ const d = det12(it.m), mirror = d < 0;
3127
+ const mat = materialFor(String(it.color), mirror, !!p.uncert || singular12(it.m, d));
2969
3128
  const k = it.part + "\x00" + mat.uuid + (mirror ? "\x00m" : "");
2970
3129
  let b = byPart.get(k);
2971
3130
  if (!b) {
@@ -3855,7 +4014,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
3855
4014
  await new Promise((r) => setTimeout(r, 0));
3856
4015
  }
3857
4016
  }
3858
- // ../../../../../../../tmp/ldr-build-78cdvu/src/scene.ts
4017
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/scene.ts
3859
4018
  import * as THREE2 from "three";
3860
4019
  var _box = new THREE2.Box3;
3861
4020
  var _m4 = new THREE2.Matrix4;
@@ -4210,32 +4369,35 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4210
4369
  return finish();
4211
4370
  })();
4212
4371
  }
4213
- // ../../../../../../../tmp/ldr-build-78cdvu/src/parts-cdn.ts
4372
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/parts-cdn.ts
4214
4373
  import { decompress as decompress2 } from "fzstd";
4215
4374
 
4216
- // ../../../../../../../tmp/ldr-build-78cdvu/src/embedded.ts
4375
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/embedded.ts
4217
4376
  function splitFiles(text, fallback) {
4218
4377
  const files = new Map;
4219
- let cur = null, saw = false;
4378
+ let cur = null, saw = false, skip = false;
4220
4379
  for (const raw of text.split(/\r?\n/)) {
4221
- const m = /^\s*0\s+FILE\s+(.+)$/i.exec(raw);
4380
+ const m = /^\s*0\s+FILE\s+(\S[^\r]*)/i.exec(raw);
4222
4381
  if (m) {
4223
4382
  if (!saw)
4224
4383
  files.clear();
4225
4384
  saw = true;
4385
+ skip = false;
4226
4386
  cur = [];
4227
4387
  files.set(norm(m[1]), cur);
4228
4388
  continue;
4229
4389
  }
4230
4390
  if (/^\s*0\s+(NOFILE|!DATA)(\s|$)/i.test(raw)) {
4231
- if (!saw)
4391
+ if (!saw && /!DATA/i.test(raw)) {
4232
4392
  files.clear();
4233
- saw = true;
4393
+ saw = true;
4394
+ }
4234
4395
  cur = null;
4396
+ skip = true;
4235
4397
  continue;
4236
4398
  }
4237
4399
  if (!cur) {
4238
- if (saw)
4400
+ if (saw || skip)
4239
4401
  continue;
4240
4402
  cur = [];
4241
4403
  files.set(norm(fallback), cur);
@@ -4285,7 +4447,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
4285
4447
  return out;
4286
4448
  }
4287
4449
 
4288
- // ../../../../../../../tmp/ldr-build-78cdvu/src/parts-cdn.ts
4450
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/parts-cdn.ts
4289
4451
  var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
4290
4452
  var indexCache = new Map;
4291
4453
  var shardCache = new Map;
@@ -4539,10 +4701,10 @@ async function prepareModel(source, o = {}) {
4539
4701
  return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
4540
4702
  }
4541
4703
 
4542
- // ../../../../../../../tmp/ldr-build-78cdvu/src/load-worker.gen.ts
4543
- var load_worker_gen_default = 'var Pt=ArrayBuffer,Y=Uint8Array,be=Uint16Array,kt=Int16Array;var ye=Int32Array,Pe=function(e,t,n){if(Y.prototype.slice)return Y.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 Y(n-t);return r.set(e.subarray(t,n)),r},fe=function(e,t,n,r){if(Y.prototype.fill)return Y.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},It=function(e,t,n,r){if(Y.prototype.copyWithin)return Y.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 Rt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],q=function(e,t,n){var r=Error(t||Rt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,q);if(!n)throw r;return r},Ye=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Bt=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ft=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,l=r>>6;if(r&8)q(0);var f=6-s,c=i==3?4:i,u=Ye(e,f,c);f+=c;var a=l?1<<l:s,p=Ye(e,f,a)+(l==1&&256),d=p;if(!s){var y=1<<10+(e[5]>>3);d=y+(y>>3)*(e[5]&7)}if(d>2145386496)q(1);var b=new Y((t==1?p||d:t?0:d)+12);return b[0]=1,b[4]=4,b[8]=8,{b:f+a,y:0,l:0,d:u,w:t&&t!=1?t:b.subarray(12),e:d,o:new ye(b.buffer,0,3),u:p,c:o,m:Math.min(131072,d)}}else if((n>>4|e[3]<<20)==25481893)return Bt(e,4)+8;q(0)},oe=function(e){var t=0;for(;1<<t<=e;++t);return t-1},pe=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)q(3);var o=1<<s,i=o,l=-1,f=-1,c=-1,u=o,a=new Pt(512+(o<<2)),p=new kt(a,0,256),d=new be(a,0,256),y=new be(a,512,o),b=512+(o<<1),C=new Y(a,b,o),v=new Y(a,b+o);while(l<255&&i>0){var m=oe(i+1),g=r>>3,w=(1<<m+1)-1,F=(e[g]|e[g+1]<<8|e[g+2]<<16)>>(r&7)&w,A=(1<<m)-1,T=w-i-1,M=F&A;if(M<T)r+=m,F=M;else if(r+=m+1,F>A)F-=T;if(p[++l]=--F,F==-1)i+=F,C[--u]=l;else i-=F;if(!F)do{var k=r>>3;f=(e[k]|e[k+1]<<8)>>(r&7)&3,r+=2,l+=f}while(f==3)}if(l>255||i)q(0);var h=0,S=(o>>1)+(o>>3)+3,_=o-1;for(var j=0;j<=l;++j){var D=p[j];if(D<1){d[j]=-D;continue}for(c=0;c<D;++c){C[h]=j;do h=h+S&_;while(h>=u)}}if(h)q(0);for(c=0;c<o;++c){var E=d[C[c]]++,L=v[c]=s-oe(E);y[c]=(E<<L)-o}return[r+7>>3,{b:s,s:C,n:v,t:y}]},Dt=function(e,t){var n=0,r=-1,s=new Y(292),o=e[t],i=s.subarray(0,256),l=s.subarray(256,268),f=new be(s.buffer,268);if(o<128){var c=pe(e,t+1,6),u=c[0],a=c[1];t+=o;var p=u<<3,d=e[t];if(!d)q(0);var y=0,b=0,C=a.b,v=C,m=(++t<<3)-8+oe(d);for(;;){if(m-=C,m<p)break;var g=m>>3;if(y+=(e[g]|e[g+1]<<8)>>(m&7)&(1<<C)-1,i[++r]=a.s[y],m-=v,m<p)break;g=m>>3,b+=(e[g]|e[g+1]<<8)>>(m&7)&(1<<v)-1,i[++r]=a.s[b],C=a.n[y],y=a.t[y],v=a.n[b],b=a.t[b]}if(++r>255)q(0)}else{r=o-127;for(;n<r;n+=2){var w=e[++t];i[n]=w>>4,i[n+1]=w&15}++t}var F=0;for(n=0;n<r;++n){var A=i[n];if(A>11)q(0);F+=A&&1<<A-1}var T=oe(F)+1,M=1<<T,k=M-F;if(k&k-1)q(0);i[r++]=oe(k)+1;for(n=0;n<r;++n){var A=i[n];++l[i[n]=A&&T+1-A]}var h=new Y(M<<1),S=h.subarray(0,M),_=h.subarray(M);f[T]=0;for(n=T;n>0;--n){var j=f[n];fe(_,n,j,f[n-1]=j+l[n]*(1<<T-n))}if(f[0]!=M)q(0);for(n=0;n<r;++n){var D=i[n];if(D){var E=f[D];fe(S,n,E,f[D]=E+(1<<T-D))}}return[t,{n:_,b:T,s:S}]},Ut=pe(new Y([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],Ot=pe(new Y([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],Nt=pe(new Y([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],qe=function(e,t){var n=e.length,r=new ye(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},ke=new Y(new ye([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),zt=qe(ke,0),Ie=new Y(new ye([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),$t=qe(Ie,3),ue=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,l=-n.b;if(!o)q(0);var f=0,c=n.b,u=(r<<3)-8+oe(o)-c,a=-1;for(;u>l&&a<s;){var p=u>>3,d=(e[p]|e[p+1]<<8|e[p+2]<<16)>>(u&7);f=(f<<c|d)&i,t[++a]=n.s[f],u-=c=n.n[f]}if(u!=l||a+1!=s)q(0)},jt=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,l=o+i;ue(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),ue(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),ue(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,l),n),ue(e.subarray(r),t.subarray(l),n)},Vt=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var l=o>>3|e[s+1]<<5|e[s+2]<<13,f=(s+=3)+l;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return fe(n,e[s],t.y,t.y+=l),n;return fe(new Y(l),e[s])}if(f>e.length)return;if(i==0){if(t.b=f,n)return n.set(e.subarray(s,f),t.y),t.y+=l,n;return Pe(e,s,f)}if(i==2){var c=e[s],u=c&3,a=c>>2&3,p=c>>4,d=0,y=0;if(u<2)if(a&1)p|=e[++s]<<4|(a&2&&e[++s]<<12);else p=c>>3;else if(y=a,a<2)p|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(a==2)p|=e[++s]<<4|(e[++s]&3)<<12,d=e[s]>>2|e[++s]<<6;else p|=e[++s]<<4|(e[++s]&63)<<12,d=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new Y(t.m),C=b.length-p;if(u==0)b.set(e.subarray(s,s+=p),C);else if(u==1)fe(b,e[s++],C);else{var v=t.h;if(u==2){var m=Dt(e,s);d+=s-(s=m[0]),t.h=v=m[1]}else if(!v)q(0);(y?jt:ue)(e.subarray(s,s+=d),b.subarray(C),v)}var g=e[s++];if(g){if(g==255)g=(e[s++]|e[s++]<<8)+32512;else if(g>127)g=g-128<<8|e[s++];var w=e[s++];if(w&3)q(0);var F=[Ot,Nt,Ut];for(var A=2;A>-1;--A){var T=w>>(A<<1)+2&3;if(T==1){var M=new Y([0,0,e[s++]]);F[A]={s:M.subarray(2,3),n:M.subarray(0,1),t:new be(M.buffer,0,1),b:0}}else if(T==2)r=pe(e,s,9-(A&1)),s=r[0],F[A]=r[1];else if(T==3){if(!t.t)q(0);F[A]=t.t[A]}}var k=t.t=F,h=k[0],S=k[1],_=k[2],j=e[f-1];if(!j)q(0);var D=(f<<3)-8+oe(j)-_.b,E=D>>3,L=0,O=(e[E]|e[E+1]<<8)>>(D&7)&(1<<_.b)-1;E=(D-=S.b)>>3;var H=(e[E]|e[E+1]<<8)>>(D&7)&(1<<S.b)-1;E=(D-=h.b)>>3;var W=(e[E]|e[E+1]<<8)>>(D&7)&(1<<h.b)-1;for(++g;--g;){var R=_.s[O],G=_.n[O],K=h.s[W],P=h.n[W],x=S.s[H],N=S.n[H];E=(D-=x)>>3;var U=1<<x,I=U+((e[E]|e[E+1]<<8|e[E+2]<<16|e[E+3]<<24)>>>(D&7)&U-1);E=(D-=Ie[K])>>3;var z=$t[K]+((e[E]|e[E+1]<<8|e[E+2]<<16)>>(D&7)&(1<<Ie[K])-1);E=(D-=ke[R])>>3;var X=zt[R]+((e[E]|e[E+1]<<8|e[E+2]<<16)>>(D&7)&(1<<ke[R])-1);if(E=(D-=G)>>3,O=_.t[O]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<G)-1),E=(D-=P)>>3,W=h.t[W]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<P)-1),E=(D-=N)>>3,H=S.t[H]+((e[E]|e[E+1]<<8)>>(D&7)&(1<<N)-1),I>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=I-=3;else{var Z=I-(X!=0);if(Z){if(I=Z==3?t.o[0]-1:t.o[Z],Z>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=I}else I=t.o[0]}for(var A=0;A<X;++A)b[L+A]=b[C+A];L+=X,C+=X;var V=L-I;if(V<0){var B=-V,Q=t.e+V;if(B>z)B=z;for(var A=0;A<B;++A)b[L+A]=t.w[Q+A];L+=B,z-=B,V=0}for(var A=0;A<z;++A)b[L+A]=b[V+A];L+=z}if(L!=C)while(C<b.length)b[L++]=b[C++];else L=b.length;if(n)t.y+=L;else b=Pe(b,0,L)}else if(n){if(t.y+=p,C)for(var A=0;A<p;++A)b[A]=b[C+A]}else if(C)b=Pe(b,C);return t.b=f,b}q(2)},_t=function(e,t){if(e.length==1)return e[0];var n=new Y(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 xe(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Ft(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 l=Vt(e,i,t);if(!l)q(5);if(t)i.e=i.y;else n.push(l),o+=l.length,It(i.w,0,l.length),i.w.set(l,i.w.length-l.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return _t(n,o)}async function Ht(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(xe(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 Je(e){return new TextDecoder().decode(await Ht(e))}var Qe=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function we(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 J=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),Be=/^[A-Za-z][A-Za-z0-9_]*$/,Re=new Map;function Fe(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(!Re.has(r))Re.set(r,t);return r}function De(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&Be.test(e))return Fe(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var et=/^~?\\s*moved\\s+to\\s+(.+)$/i,Gt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),lt=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Wt=new Set(["model","submodel","configuration"]),Kt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function tt(e){let t=Kt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return lt.has(n)||Wt.has(n)?n:void 0}function Xt(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 Zt(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(Number.isFinite))return null;let l=n[2].trim();for(let a=0;a<s;a++)l=l.replace(/^\\S+\\s*/,"");let f=Xt(l);if(!f.length)return null;let c={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:f[0]};if(s>=10)c.a=i[9];if(s===11)c.b=i[10];let u=f.findIndex((a,p)=>p>0&&a.toUpperCase()==="GLOSSMAP");if(u>0&&f[u+1])c.glossmap=f[u+1];if(t)c.next=!0;return c}var Yt=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,""),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 qt(e){let t=e.length,n=1,r=(c)=>c===32||c===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let c=n;while(n<t&&!r(e.charCodeAt(n)))n++;return c<n?e.slice(c,n):null},o=s();if(o===null)return null;let i=Array(12);for(let c=0;c<12;c++){let u=s();if(u===null)return null;i[c]=+u}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let l=e.slice(n),f=/[ \\t]{2,}|\\t/.test(l)?l.split(/\\s+/).join(" "):l;return{t:1,color:De(o),m:i,file:J(f)}}function nt(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=De(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:J(e.slice(14).join(" "))};if(t===2)return{t:2,color:n,p:r.slice(0,6)};if(t===3)return{t:3,color:n,p:r.slice(0,9)};if(t===4)return{t:4,color:n,p:r.slice(0,12)};return{t:5,color:n,p:r.slice(0,12)}}function ct(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,f=null,c=[],u=null,a=()=>{if(!f)return;let m=Yt(f.chunks.join("")),g=m[0]===137&&m[1]===80&&m[2]===78&&m[3]===71;(l??=new Map).set(J(f.name),{name:f.name,bytes:m,...g?{mime:"image/png"}:{}}),f=null},p=!0,d=(m)=>{if(a(),o={name:J(m),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],u=null,p=!0},y=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},v=(m,g)=>{if(u){m.tex=u,u=null;return}let w=c[c.length-1];if(!w)return;if(w.fallback){if(!g)m.fallback=!0}else m.tex=w.map};for(let m of e.split(`\n`)){let g=m.trim();if(!g)continue;if(r&&g.charCodeAt(0)>=50&&g.charCodeAt(0)<=53&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)){if(f||y)continue;if(!o)d(t);let T=g.slice(2).trimStart(),M=T.search(/\\s/),k={t:g.charCodeAt(0)-48,color:De(M<0?T:T.slice(0,M)),p:[],src:g};v(k,!1),o.cmds.push(k),p=!1;continue}if(g.charCodeAt(0)===48&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)){let T=2;while(g.charCodeAt(T)===32||g.charCodeAt(T)===9)T++;let M=T;while(M<g.length&&g.charCodeAt(M)!==32&&g.charCodeAt(M)!==9)M++;let k=g.slice(T,M);if(!Gt.has(k)){if(y||f)continue;if(!o)d(t);let h=g.slice(T),S={t:0,text:h};if(k.charCodeAt(0)===33)S.meta=k;if(u=null,p&&!o.org){let j=tt(h);if(j)o.org=j}let _=h.match(et);if(_&&!o.movedTo){let j=_[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(j))j+=".dat";o.movedTo=J(j)}o.cmds.push(S);continue}}if(g.charCodeAt(0)===49&&(g.charCodeAt(1)===32||g.charCodeAt(1)===9)&&!f&&!y){let T=qt(g);if(T){if(!o)d(t);v(T,!1),o.cmds.push(T),p=!1;continue}}let w=g.split(/\\s+/);if(+w[0]===0){let T=g.slice(1).trim();if(w[1]==="FILE"){C(),y=!1,d(T.slice(5));continue}if(w[1]==="NOFILE"){a(),o=null,y=!0;continue}if(w[1]==="!DATA"){C(),a(),o=null,y=!1,f={name:T.slice(5).trim(),chunks:[]};continue}if(y)continue;if(f){if(w[1]==="!:")f.chunks.push(w.slice(2).join(""));continue}if(!o)d(t);let M={t:0,text:T};if(w[1]==="STEP")M.step=!0,c=[],u=null;else if(w[1]==="BFC")M.bfc=w.slice(2).join(" ");else if(w[1]==="ROTSTEP")if(M.meta="ROTSTEP",M.step=!0,c=[],u=null,(w[2]??"").toUpperCase()==="END")M.rotstep={x:0,y:0,z:0,mode:"END"};else{let h=(w[5]??"REL").toUpperCase();M.rotstep={x:+w[2]||0,y:+w[3]||0,z:+w[4]||0,mode:["REL","ABS","ADD"].includes(h)?h:"REL"}}else if(w[1]==="BUFEXCHG"){M.meta="BUFEXCHG";let h=(w[2]??"").toUpperCase();M.bufexchg={op:h==="RETRIEVE"?"RETRIEVE":"STORE",buf:w[3]??"A"}}else if(w[1]?.startsWith("!"))M.meta=w[1];if(p&&!o.org){let h=tt(T);if(h)o.org=h}if(w[1]==="!TEXMAP"){let h=(w[2]??"").toUpperCase();if(u=null,h==="START"||h==="NEXT"){let S=Zt(T.replace(/^!TEXMAP\\s+\\S+/i,""),h==="NEXT");if(M.texmap={op:h,...S?{map:S}:{}},S)if((o.texmaps??=[]).push(S),h==="START")c.push({map:S,fallback:!1});else u=S}else if(h==="FALLBACK"){M.texmap={op:h};let S=c[c.length-1];if(S)S.fallback=!0}else if(h==="END")M.texmap={op:h},c.pop()}else if(w[1]==="!:"){u=null;let h=nt(w.slice(2));if(h)v(h,!0),M.geom=h}else u=null;let k=T.match(et);if(k&&!o.movedTo){let h=k[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(h))h+=".dat";o.movedTo=J(h)}o.cmds.push(M);continue}if(f||y)continue;if(!o)d(t);let A=nt(w);if(!A)continue;v(A,!1),o.cmds.push(A),p=!1}return a(),l?{main:i,files:s,data:l}:{main:i,files:s}}var Cn=Math.PI/180;function ut(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 ft(e,t){let[n,r,s,o,i,l,f,c,u,a,p,d]=e,[y,b,C,v,m,g,w,F,A,T,M,k]=t;return[o*y+i*b+l*C+n,f*y+c*b+u*C+r,a*y+p*b+d*C+s,o*v+i*w+l*T,o*m+i*F+l*M,o*g+i*A+l*k,f*v+c*w+u*T,f*m+c*F+u*M,f*g+c*A+u*k,a*v+p*w+d*T,a*m+p*F+d*M,a*g+p*A+d*k]}var Ue=[0,0,0,1,0,0,0,1,0,0,0,1];var rt=new WeakMap,Jt=/^(s|8|48)\\//;function Oe(e,t){let n=e.files.get(J(t));if(!n)return"part";let r=rt.get(n);if(r)return r;if(n.org)r=lt.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&&Jt.test(s.file))?"part":"model";return rt.set(n,r),r}var st=new WeakMap;function pt(e){let t=st.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 st.set(e,t),t}var ot=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Re.get(e)??String(e):String(e),Qt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${ot(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${ot(e.color)} ${e.p.join(" ")}`,Ne=(e,t)=>`${J(e)}#${t}`;function en(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:Ne(e.name,t),cmds:n}}function mt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...en(e,t).cmds.map(Qt)].join(`\n`)+`\n`}function ze(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 ht(e){let[t,n,r,s,o,i,l,f,c,u,a,p]=e,d=f*p-c*a,y=-(l*p-c*u),b=l*a-f*u,C=s*d+o*y+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let v=1/C,m=[d*v,-(o*p-i*a)*v,(o*c-i*f)*v,y*v,(s*p-i*u)*v,-(s*c-i*l)*v,b*v,-(s*a-o*u)*v,(s*f-o*l)*v];return[-(m[0]*t+m[1]*n+m[2]*r),-(m[3]*t+m[4]*n+m[5]*r),-(m[6]*t+m[7]*n+m[8]*r),...m]}var tn=(e)=>String(+e.toFixed(6)||0),it=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function gt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(tn).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${it(t.texture)}${t.glossmap?" GLOSSMAP "+it(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${J(e)}\n0 !TEXMAP END\n`;return{name:`${J(e)}#tex-${ze(r)}`,source:r}}var nn=(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),l=Math.cos(t*r),f=Math.sin(n*r),c=Math.cos(n*r);return[l*c,-l*f,i,o*f+s*i*c,o*c-s*i*f,-s*l,s*f-o*i*c,s*c+o*i*f,o*l]}var at=new WeakMap;function dt(e){let t=at.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:nn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),at.set(e,n),n}var bt=999999,wt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Mt=new WeakMap,yt=new WeakMap;function sn(e,t){let n=yt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Mt.get(o)??"",l=i.indexOf("!COLOUR");return l<0?"":"0 "+i.slice(l).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},yt.set(t,n);let r=n.parts.get(e);if(!r){let s=J(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-${ze(o)}`,source:o},n.parts.set(e,r)}return r}function on(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,f=0,c=(a,p)=>{let d=a.name+"#"+p,y=l.get(d);if(!y){let b;y=Object.assign(()=>b??=mt(a,p),{file:a,step:p}),l.set(d,y)}return y},u=(a,p,d,y,b,C,v,m,g=null,w=[],F=[],A=void 0,T=null)=>{let M=a.files.get(p);if(!M||v>r)return;let k=T,h=0,S=v>0?++f:0,_=i&&S?[...w,S]:w,j=i&&S?[...F,d]:F,D=i&&!g?new Map:null,E=-1,L=0,O=(P,x,N,U,I,z,X)=>{if(E!==h)E=h,L=0;let Z=D?.get(h+"|"+x);if(Z)return Z.n++,u(P,P===a?x:P.main,N,U,b+"/"+x,[...I,bt],v+1,z,[...I,bt],_,j,X,k);let V=[...I,L++],B=n.length;u(P,P===a?x:P.main,N,U,b+"/"+x,V,v+1,z,g,_,j,X,k),D?.set(h+"|"+x,{n:1,from:B,to:n.length})},H=dt(M),W=s?pt(M):[],R=0,G=(P,x,N,U,I,z,X,Z,V)=>{if(g)U=g;let B={part:P,color:x,m:N,step:U[0],steps:U,localStep:I,path:b};if(Z)B.colour=Z;if(S){if(B.sub=S,i)B.subPath=_,B.subMats=j}if(z)B.embedded=!0;if(X){let ee=gt(P,X);B.texPart=ee.name,B.texSource=ee.source}else if(V){let ee=sn(P,V);B.colPart=ee.name,B.colSource=ee.source}let Q=H[I];if(Q)B.view=Q;return n.push(B),B},K=(P)=>{while(R<W.length&&W[R]<=P){let x=W[R++];G(Ne(M.name,x),y,d,[...C,x],x,!1,null,A,T).source=c(M,x)}};for(let P of M.cmds){if(P.t===0&&P.step){h++;continue}let x=P;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){K(h);continue}if(x.t===0){if(x.meta==="!COLOUR"){let Q=ln(x.text);if(Q&&Q.code!==16&&Q.code!==24)Mt.set(Q,x.text),(k=new Map(k??[])).set(Q.code,Q);continue}if(o&&x.geom?.t===1)x=x.geom;else continue}if(x.t!==1)continue;if(o&&x.fallback)continue;let N=x.color===16?y:x.color,U=x.color===16?A:k?.get(x.color),I=ft(d,x.m),z=[...C,h],X=o?x.tex??m:null,Z=X?ht(x.m):null,V=X&&Z?ut(X,Z):null;if(a.files.has(x.file)){if(Oe(a,x.file)==="model"){O(a,x.file,I,N,z,V,U);continue}G(x.file,N,I,z,h,!0,V,U,k);continue}let B=t.resolveModel?.(x.file);if(B){O(B,x.file,I,N,z,V,U);continue}G(x.file,N,I,z,h,!1,V,U,k)}if(K(1/0),D){for(let P of D.values())if(P.n>1)for(let x=P.from;x<P.to;x++)n[x].mult??=P.n}};if(Oe(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ue],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return u(e,e.main,Ue,16,e.main,[],0,null),n}function At(e,t="main.ldr",n){return on(ct(e,t,{geometryText:!0}),n)}var an=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function $e(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 xt(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=$e(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 ln(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",l=255,f=0,c={type:"default"},u=1;while(u<n.length){let a=n[u].toUpperCase(),p=n[u+1];if(a==="CODE")s=p!==void 0&&Be.test(p)?Fe(p):p!==void 0&&/^\\d+$/.test(p)?+p:NaN,u+=2;else if(a==="VALUE"){let d=$e(p);if(d)o=d;u+=2}else if(a==="EDGE")i=$e(p)??p,u+=2;else if(a==="ALPHA")l=+p,u+=2;else if(a==="LUMINANCE")f=+p,u+=2;else if(a==="CHROME")c={type:"chrome"},u+=1;else if(a==="PEARLESCENT")c={type:"pearlescent"},u+=1;else if(a==="RUBBER")c={type:"rubber"},u+=1;else if(a==="MATTE_METALLIC")c={type:"matte_metallic"},u+=1;else if(a==="METAL")c={type:"metal"},u+=1;else if(a==="MATERIAL"){let d=(n[u+1]||"").toUpperCase();if(d==="GLITTER"){let{grain:y,next:b}=xt(n,u+2);c={type:"glitter",material:y},u=b}else if(d==="SPECKLE"){let{grain:y,next:b}=xt(n,u+2);c={type:"speckle",material:y},u=b}else if(d==="FABRIC"){let y=(n[u+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(y)?y.toLowerCase():void 0;c={type:"fabric",kind:b},u+=b?3:2}else u=n.length}else if(an.has(a))u+=1;else u+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(l)?l:255,luminance:Number.isFinite(f)?f:0,finish:c}}function cn(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,l=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:l,finish:"glitter"}}case"speckle":{let i=e.finish.material,l=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:l,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 je(e){let t=cn(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 un(e,t){let n=new Map,r=null,s=!1;for(let o of e.split(/\\r?\\n/)){let i=/^\\s*0\\s+FILE\\s+(.+)$/i.exec(o);if(i){if(!s)n.clear();s=!0,r=[],n.set(J(i[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(o)){if(!s)n.clear();s=!0,r=null;continue}if(!r){if(s)continue;r=[],n.set(J(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var fn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?J(t.slice(14).join(" ")):null};function pn(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 vt(e,t,n="main.ldr"){let r=un(e,n),s=new Map;for(let o of t){let i=J(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),f=[i];while(f.length)for(let u of r.get(f.pop())){let a=fn(u);if(a&&r.has(a)&&!l.has(a))l.add(a),f.push(a)}let c=[i,...[...l].filter((u)=>u!==i).sort()].map((u)=>"0 FILE "+(u===i?"":u)+`\n`+r.get(u).join(`\n`)).join(`\n`);s.set(i,`emb/${pn(c)}.dat`)}return s}var Ct=(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,Tt=new WeakMap;function Ve(e,t){let n=Tt.get(e);if(!n)Tt.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),l=[],f=[];s.studs.forEach((p,d)=>{l.push(p[0]),f.push(p[1]);for(let y=0;y<12;y++)i[d*12+y]=p[2+y]});let c=null,u=0,a=0;if(s.mask){u=s.mask[0],a=s.mask[1];let p=s.mask[2];c=new Uint8Array(p.length);for(let d=0;d<p.length;d++)c[d]=p.charCodeAt(d)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:l,color:f,mask:c,nx:u,nz:a}),r}var le=1073741824;class _e{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,l=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&l[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,l=this.b,f=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,l[s]=t,f[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&l[s]===t&&f[s]===n){let c=this.vals[s];return this.vals[s]=r,c}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var Me=(e,t,n)=>e>-le&&e<le&&t>-le&&t<le&&n>-le&&n<le,me=2147483647;function mn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function hn(e,t,n){let s=new Map,o=(L)=>{let O=s.get(L);if(O===void 0)s.set(L,O=mn(t,L));return O},i=[],l=[],f=[],c=[],u=[],a=[],p=[],d=[],y=new _e(e.length*2),b=[],C=[];for(let L=0;L<e.length;L++){let O=e[L],H=O.m,W=t.parts[O.part];if(!W||!W.mask||!Ct(H)||o(O.color))continue;let R=W.bbox,G=1/0,K=-1/0,P=1/0,x=-1/0;for(let I=0;I<2;I++)for(let z=0;z<2;z++){let X=I?R[3]:R[0],Z=z?R[5]:R[2],V=H[0]+H[3]*X+H[5]*Z,B=H[2]+H[9]*X+H[11]*Z;if(V<G)G=V;if(V>K)K=V;if(B<P)P=B;if(B>x)x=B}let N=u.length;i.push(G),l.push(K),f.push(P),c.push(x),u.push(L),a.push(Ve(t,O.part)),p.push(R[0]),d.push(R[2]);let U=Math.round((H[1]+R[4])*2);for(let I=Math.floor(G/40);I<=Math.floor(K/40);I++)for(let z=Math.floor(P/40);z<=Math.floor(x/40);z++){if(!Me(U,I,z))continue;let X=C.length;C.push(N),b.push(y.put(U,I,z,X))}}let v=[0,5,-5,5,-5],m=[0,5,5,-5,-5],g=NaN,w=NaN,F=NaN,A=-1,T=(L,O,H,W)=>{let R=Math.round(O*2),G=Math.floor(L/40),K=Math.floor(H/40);if(!Me(R,G,K))return me;let P=me;if(R!==g||G!==w||K!==F)g=R,w=G,F=K,A=y.get(R,G,K);for(let x=A;x>=0;x=b[x]){let N=C[x];if(u[N]===W||!(L-6>=i[N]-0.5&&L+6<=l[N]+0.5&&H-6>=f[N]-0.5&&H+6<=c[N]+0.5))continue;let U=e[u[N]].m,I=a[N],z=p[N],X=d[N],Z=L-U[0],V=O-U[1],B=H-U[2],Q=U[3]*Z+U[6]*V+U[9]*B,ee=U[5]*Z+U[8]*V+U[11]*B,{nx:ne,nz:ie,mask:ce}=I,ae=!0;for(let te=0;te<5;te++){let re=Math.floor((Q+v[te]-z)/20),se=Math.floor((ee+m[te]-X)/20);if(re<0||se<0||re>=ne||se>=ie||ce[re*ie+se]!==1){ae=!1;break}}if(ae){if(!n)return 0;let te=n[u[N]];if(te<P)P=te}}return P},M=0;for(let L of e){let O=Ve(t,L.part);if(O)M+=O.nStuds}let k=new Uint8Array(M),h=new Uint8Array(M),S=new _e(M),_=0,j=n?new Int32Array(M).fill(me):void 0;for(let L=0,O=0;L<e.length;L++){let H=e[L],W=Ve(t,H.part);if(!W)continue;let R=H.m,G=W.studM,K=R[0],P=R[1],x=R[2],N=R[3],U=R[4],I=R[5],z=R[6],X=R[7],Z=R[8],V=R[9],B=R[10],Q=R[11];for(let ee=0;ee<W.nStuds;ee++,O++){let ne=ee*12,ie=G[ne+4],ce=G[ne+7],ae=G[ne+10];if(!(Math.abs(z*ie+X*ce+Z*ae-1)<0.001&&Math.abs(N*ie+U*ce+I*ae)<0.001&&Math.abs(V*ie+B*ce+Q*ae)<0.001))continue;h[O]=1;let te=G[ne],re=G[ne+1],se=G[ne+2],He=K+N*te+U*re+I*se,Ge=P+z*te+X*re+Z*se,We=x+V*te+B*re+Q*se,Ke=T(He,Ge,We,L);if(Ke!==me){if(k[O]=1,_++,j)j[O]=Ke}let he=Math.round(He),ge=Math.round(Ge),de=Math.round(We);if(!Me(he,ge,de))continue;if(!n){S.put(he,ge,de,1);continue}let Xe=n[L],Ze=S.get(he,ge,de);if(Ze<0||Xe<Ze)S.put(he,ge,de,Xe)}}let D=new Uint8Array(e.length),E=n?new Int32Array(e.length).fill(me):void 0;for(let L=0;L<e.length;L++){let O=e[L],H=t.parts[O.part];if(!H||!H.under||!Ct(O.m)||o(O.color))continue;let W=H.bbox,R=Math.round((W[3]-W[0])/20),G=Math.round((W[5]-W[2])/20);if(!R||!G||R*G>4096)continue;let K=O.m,P=!0,x=0;for(let N=0;N<R&&P;N++)for(let U=0;U<G;U++){let I=W[0]+10+20*N,z=W[2]+10+20*U,X=K[0]+K[3]*I+K[5]*z,Z=K[2]+K[9]*I+K[11]*z,V=Math.round(X),B=Math.round(K[1]+W[4]),Q=Math.round(Z),ee=Me(V,B,Q)?S.get(V,B,Q):-1;if(ee<0){P=!1;break}if(ee>x)x=ee}if(P){if(D[L]=1,E)E[L]=x}}return{nStuds:M,studHidden:k,studUp:h,underHidden:D,studsHidden:_,studHideStep:j,underHideStep:E}}function gn(e,t,n){let r=(a)=>a.colPart&&t.parts[a.colPart]?a.colPart:n&&a.texPart&&t.parts[a.texPart]?a.texPart:a.part,s=new Map,o=new Map,i=(a)=>{let p=a.colour;if(!p)return String(a.color);let d=o.get(p);if(d!==void 0)return d;let y=t.colorTable?.[a.color],b=y?.hex??t.colors?.[a.color],C=y?je({alpha:y.alpha??255,luminance:y.luminance??0,finish:y.finish??{type:"default"}}):"default:op",v=je(p);if(d=b&&b.toUpperCase()===p.hex.toUpperCase()&&C===v?String(a.color):p.hex.toUpperCase()+"/"+v,d!==String(a.color))s.set(d,p);return o.set(p,d),d},l=e.map((a)=>({part:r(a),color:i(a),m:a.m,steps:a.steps})),f=l.map((a)=>wt(a.steps)),c=[...new Set(f)].sort(),u=new Map(c.map((a,p)=>[a,p]));return{all:l,stepOf:f.map((a)=>u.get(a)),nSteps:c.length,localColours:s}}function Ae(e,t,n=!0){let r=gn(e,t,n);return hn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Se="https://ldr-demo.vercel.app/cdn/v1/",Ce=new Map,ve=new Map;function Te(e=Se,t=fetch){let n=Ce.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(()=>Ce.delete(e)),Ce.set(e,n);return n}var dn=(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"),Le=(e,t)=>dn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Le(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Le(r,t)])):e;function bn(e,t={}){let n=[],r=0,s={},o={};for(let p of e){let d=p.buffer;if(!d)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let y=new DataView(d).getUint32(0,!0),b=new Uint8Array(d,4+y),C=r;n.push(b),r+=b.byteLength;let v=(4-r%4)%4;if(v)n.push(new Uint8Array(v)),r+=v;for(let[m,g]of Object.entries(p.header.parts??{}))if(!(m in s))s[m]=Le(g,C);for(let[m,g]of Object.entries(p.header.studKinds??{}))if(!(m in o))o[m]=Le(g,C)}let i=e[0]?.header??{version:1,weld:!0},l=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),f=(4-(4+l.length)%4)%4,c=4+l.length+f,u=new Uint8Array(c+r);new DataView(u.buffer).setUint32(0,l.length+f,!0),u.set(l,4),u.fill(32,4+l.length,c);let a=c;for(let p of n)u.set(p,a),a+=p.byteLength;return we(u.buffer)}async function yn(e,t={}){e=[...e];try{return await Lt(e,t)}catch(n){let r=t.cdn??Se,s=t.fetch??fetch;Ce.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await Lt(e,{...t,fetch:o})}catch{throw n}}}async function Lt(e,t){let n=t.cdn??Se,r=t.fetch??fetch,s=t.gap??16384,o=await Te(n,r),i=[...new Set([...e].map(J))],l=[],f=[];for(let m of i){if(ve.has(n+m))continue;let g=o.parts[m];if(g)f.push({name:m,off:g[0],len:g[1],file:g[2]??0});else l.push(m)}f.sort((m,g)=>m.file-g.file||m.off-g.off);let c=[];for(let m of f){let g=c[c.length-1];if(g&&g.file===m.file&&m.off-g.end<=s)g.end=Math.max(g.end,m.off+m.len),g.items.push(m);else c.push({file:m.file,start:m.off,end:m.off+m.len,items:[m]})}let u=0,a=0,p=0,d=new Map,y=async()=>{while(p<c.length){let m=c[p++],g=d.get(m.file);if(g)g=g.subarray(m.start,m.end);else{let w=await r(new URL(o.archives[m.file],n).href,{headers:{Range:`bytes=${m.start}-${m.end-1}`,"Accept-Encoding":"identity"}});if(!w.ok)throw Error(`ldr: parts CDN ${w.status}`);if(a++,g=new Uint8Array(await w.arrayBuffer()),u+=g.byteLength,w.status===200)d.set(m.file,g),g=g.subarray(m.start,m.end)}for(let w of m.items){let F=xe(g.subarray(w.off-m.start,w.off-m.start+w.len)),A=F.buffer.slice(F.byteOffset,F.byteOffset+F.byteLength);ve.set(n+w.name,we(A))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},y));let b=i.filter((m)=>ve.has(n+m)).map((m)=>ve.get(n+m)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?bn(b,C):we(xn(C)),missing:l,requests:a,bytes:u}}function xn(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 wn(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 St(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let l of e){let f=l.embedded?t.get(l.part):J(l.part),c=f?n.parts[f]:void 0;if(!c)continue;if(c[3]!=null)o=!0,r+=c[3];if(!i.has(f))i.add(f),s+=c[1]}return{bodyTris:r,packBytes:s,known:o}}class Ee 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 Et(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Te(t.cdn??Se,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(h)=>{if(!h.ok)throw Error(`ldr: ${h.status} fetching ${e}`);return Je(await h.arrayBuffer())}),i=performance.now(),l=t.name??(t.text?"main.ldr":Qe(e)),f=At(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(f),await s;let u=vt(o,new Set(f.filter((h)=>h.embedded).map((h)=>h.part)),l),a=(h,S)=>t.maxBodyTris!=null&&h>t.maxBodyTris||t.maxPackBytes!=null&&S>t.maxPackBytes,p=t.maxBodyTris!=null||t.maxPackBytes!=null,d=(h)=>new Ee({...h,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),y="full";if(p){let h=St(f,u,await s);if(a(h.known?h.bodyTris:0,h.packBytes)){if(!t.lowCdn)throw d(h);let S=await Te(t.lowCdn,r).catch(()=>null);if(!S)throw d(h);let _=St(f,u,S);if(a(_.known?_.bodyTris:0,_.packBytes))throw d(_);y="low"}}let b=[...f.filter((h)=>!h.embedded).map((h)=>h.part),...u.values()],C=async()=>{let h=await yn(b,y==="low"?{...t,cdn:t.lowCdn}:t);for(let[S,_]of u){let j=h.pack.header.parts[_];if(j)h.pack.header.parts[S]=j}return{...h,packBytes:h.pack.buffer?.byteLength??h.pack.bytes??0,bodyTris:wn(f,h.pack)}},v=await C();if(p&&a(v.bodyTris,v.packBytes)&&y==="full"&&t.lowCdn&&await Te(t.lowCdn,r).then(()=>!0,()=>!1)){y="low";let h=v;v=await C(),v.requests+=h.requests,v.bytes+=h.bytes}if(p&&a(v.bodyTris,v.packBytes))throw d(v);let{pack:m,missing:g,requests:w,bytes:F}=v,A=new Map([...u].map(([h,S])=>[S,h])),T=g.map((h)=>A.get(h)??h),M=performance.now(),k=t.cull?Ae(f,m.header,t.textures!==!1):void 0;return{insts:f,pack:m,tier:y,missing:T,requests:w,bytes:F,cull:k,timings:{fetchModel:i-n,parse:c-i,parts:M-c,...k?{cull:performance.now()-M}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await Et(n,{...r,cull:!1,onParsed:(u)=>self.postMessage({id:t,insts:u})}),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(),l=Ae(s.insts,s.pack.header,r.textures!==!1),f=performance.now()-i,c=[];for(let u of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(u)c.push(u.buffer);self.postMessage({id:t,cull:l,ms:f},c)}catch(s){if(s instanceof Ee||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';
4704
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/load-worker.gen.ts
4705
+ var load_worker_gen_default = 'var Ft=ArrayBuffer,ee=Uint8Array,we=Uint16Array,Rt=Int16Array;var Me=Int32Array,Ie=function(e,t,n){if(ee.prototype.slice)return ee.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 ee(n-t);return r.set(e.subarray(t,n)),r},he=function(e,t,n,r){if(ee.prototype.fill)return ee.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},Bt=function(e,t,n,r){if(ee.prototype.copyWithin)return ee.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 Dt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],te=function(e,t,n){var r=Error(t||Dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,te);if(!n)throw r;return r},Qe=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Ut=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ot=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)te(0);var u=6-s,f=i==3?4:i,a=Qe(e,u,f);u+=f;var l=c?1<<c:s,m=Qe(e,u,l)+(c==1&&256),g=m;if(!s){var d=1<<10+(e[5]>>3);g=d+(d>>3)*(e[5]&7)}if(g>2145386496)te(1);var b=new ee((t==1?m||g:t?0:g)+12);return b[0]=1,b[4]=4,b[8]=8,{b:u+l,y:0,l:0,d:a,w:t&&t!=1?t:b.subarray(12),e:g,o:new Me(b.buffer,0,3),u:m,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return Ut(e,4)+8;te(0)},le=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ge=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)te(3);var o=1<<s,i=o,c=-1,u=-1,f=-1,a=o,l=new Ft(512+(o<<2)),m=new Rt(l,0,256),g=new we(l,0,256),d=new we(l,512,o),b=512+(o<<1),C=new ee(l,b,o),A=new ee(l,b+o);while(c<255&&i>0){var p=le(i+1),h=r>>3,M=(1<<p+1)-1,D=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(r&7)&M,v=(1<<p)-1,L=M-i-1,R=D&v;if(R<L)r+=p,D=R;else if(r+=p+1,D>v)D-=L;if(m[++c]=--D,D==-1)i+=D,C[--a]=c;else i-=D;if(!D)do{var T=r>>3;u=(e[T]|e[T+1]<<8)>>(r&7)&3,r+=2,c+=u}while(u==3)}if(c>255||i)te(0);var x=0,w=(o>>1)+(o>>3)+3,E=o-1;for(var z=0;z<=c;++z){var k=m[z];if(k<1){g[z]=-k;continue}for(f=0;f<k;++f){C[x]=z;do x=x+w&E;while(x>=a)}}if(x)te(0);for(f=0;f<o;++f){var P=g[C[f]]++,Y=A[f]=s-le(P);d[f]=(P<<Y)-o}return[r+7>>3,{b:s,s:C,n:A,t:d}]},Nt=function(e,t){var n=0,r=-1,s=new ee(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),u=new we(s.buffer,268);if(o<128){var f=ge(e,t+1,6),a=f[0],l=f[1];t+=o;var m=a<<3,g=e[t];if(!g)te(0);var d=0,b=0,C=l.b,A=C,p=(++t<<3)-8+le(g);for(;;){if(p-=C,p<m)break;var h=p>>3;if(d+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<C)-1,i[++r]=l.s[d],p-=A,p<m)break;h=p>>3,b+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<A)-1,i[++r]=l.s[b],C=l.n[d],d=l.t[d],A=l.n[b],b=l.t[b]}if(++r>255)te(0)}else{r=o-127;for(;n<r;n+=2){var M=e[++t];i[n]=M>>4,i[n+1]=M&15}++t}var D=0;for(n=0;n<r;++n){var v=i[n];if(v>11)te(0);D+=v&&1<<v-1}var L=le(D)+1,R=1<<L,T=R-D;if(T&T-1)te(0);i[r++]=le(T)+1;for(n=0;n<r;++n){var v=i[n];++c[i[n]=v&&L+1-v]}var x=new ee(R<<1),w=x.subarray(0,R),E=x.subarray(R);u[L]=0;for(n=L;n>0;--n){var z=u[n];he(E,n,z,u[n-1]=z+c[n]*(1<<L-n))}if(u[0]!=R)te(0);for(n=0;n<r;++n){var k=i[n];if(k){var P=u[k];he(w,n,P,u[k]=P+(1<<L-k))}}return[t,{n:E,b:L,s:w}]},zt=ge(new ee([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],$t=ge(new ee([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],jt=ge(new ee([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],qe=function(e,t){var n=e.length,r=new Me(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Fe=new ee(new Me([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),Vt=qe(Fe,0),Re=new ee(new Me([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),_t=qe(Re,3),me=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)te(0);var u=0,f=n.b,a=(r<<3)-8+le(o)-f,l=-1;for(;a>c&&l<s;){var m=a>>3,g=(e[m]|e[m+1]<<8|e[m+2]<<16)>>(a&7);u=(u<<f|g)&i,t[++l]=n.s[u],a-=f=n.n[u]}if(a!=c||l+1!=s)te(0)},Ht=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;me(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),me(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),me(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),me(e.subarray(r),t.subarray(c),n)},Gt=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,u=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return he(n,e[s],t.y,t.y+=c),n;return he(new ee(c),e[s])}if(u>e.length)return;if(i==0){if(t.b=u,n)return n.set(e.subarray(s,u),t.y),t.y+=c,n;return Ie(e,s,u)}if(i==2){var f=e[s],a=f&3,l=f>>2&3,m=f>>4,g=0,d=0;if(a<2)if(l&1)m|=e[++s]<<4|(l&2&&e[++s]<<12);else m=f>>3;else if(d=l,l<2)m|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(l==2)m|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else m|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new ee(t.m),C=b.length-m;if(a==0)b.set(e.subarray(s,s+=m),C);else if(a==1)he(b,e[s++],C);else{var A=t.h;if(a==2){var p=Nt(e,s);g+=s-(s=p[0]),t.h=A=p[1]}else if(!A)te(0);(d?Ht:me)(e.subarray(s,s+=g),b.subarray(C),A)}var h=e[s++];if(h){if(h==255)h=(e[s++]|e[s++]<<8)+32512;else if(h>127)h=h-128<<8|e[s++];var M=e[s++];if(M&3)te(0);var D=[$t,jt,zt];for(var v=2;v>-1;--v){var L=M>>(v<<1)+2&3;if(L==1){var R=new ee([0,0,e[s++]]);D[v]={s:R.subarray(2,3),n:R.subarray(0,1),t:new we(R.buffer,0,1),b:0}}else if(L==2)r=ge(e,s,9-(v&1)),s=r[0],D[v]=r[1];else if(L==3){if(!t.t)te(0);D[v]=t.t[v]}}var T=t.t=D,x=T[0],w=T[1],E=T[2],z=e[u-1];if(!z)te(0);var k=(u<<3)-8+le(z)-E.b,P=k>>3,Y=0,I=(e[P]|e[P+1]<<8)>>(k&7)&(1<<E.b)-1;P=(k-=w.b)>>3;var j=(e[P]|e[P+1]<<8)>>(k&7)&(1<<w.b)-1;P=(k-=x.b)>>3;var H=(e[P]|e[P+1]<<8)>>(k&7)&(1<<x.b)-1;for(++h;--h;){var Z=E.s[I],O=E.n[I],G=x.s[H],K=x.n[H],J=w.s[j],Q=w.n[j];P=(k-=J)>>3;var S=1<<J,y=S+((e[P]|e[P+1]<<8|e[P+2]<<16|e[P+3]<<24)>>>(k&7)&S-1);P=(k-=Re[G])>>3;var B=_t[G]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Re[G])-1);P=(k-=Fe[Z])>>3;var _=Vt[Z]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Fe[Z])-1);if(P=(k-=O)>>3,I=E.t[I]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<O)-1),P=(k-=K)>>3,H=x.t[H]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<K)-1),P=(k-=Q)>>3,j=w.t[j]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<Q)-1),y>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=y-=3;else{var W=y-(_!=0);if(W){if(y=W==3?t.o[0]-1:t.o[W],W>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=y}else y=t.o[0]}for(var v=0;v<_;++v)b[Y+v]=b[C+v];Y+=_,C+=_;var X=Y-y;if(X<0){var N=-X,q=t.e+X;if(N>B)N=B;for(var v=0;v<N;++v)b[Y+v]=t.w[q+v];Y+=N,B-=N,X=0}for(var v=0;v<B;++v)b[Y+v]=b[X+v];Y+=B}if(Y!=C)while(C<b.length)b[Y++]=b[C++];else Y=b.length;if(n)t.y+=Y;else b=Ie(b,0,Y)}else if(n){if(t.y+=m,C)for(var v=0;v<m;++v)b[v]=b[C+v]}else if(C)b=Ie(b,C);return t.b=u,b}te(2)},Wt=function(e,t){if(e.length==1)return e[0];var n=new ee(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 Ae(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Ot(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=Gt(e,i,t);if(!c)te(5);if(t)i.e=i.y;else n.push(c),o+=c.length,Bt(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 Wt(n,o)}async function Kt(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(Ae(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 et(e){return new TextDecoder().decode(await Kt(e))}var tt=(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 ne=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),De=/^[A-Za-z][A-Za-z0-9_]*$/,Be=new Map;function Ue(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(!Be.has(r))Be.set(r,t);return r}function Oe(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&De.test(e))return Ue(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var nt=/^~?\\s*moved\\s+to\\s+(.+)$/i,Xt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Zt=new Set(["FILE","NOFILE","!DATA"]),ut=1000000000000000,ft=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Yt=new Set(["model","submodel","configuration"]),Jt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function rt(e){let t=Jt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return ft.has(n)||Yt.has(n)?n:void 0}function Qt(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 qt(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((l)=>Number.isFinite(l)&&Math.abs(l)<=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 l=0;l<s;l++)c=c.replace(/^\\S+\\s*/,"");let u=Qt(c);if(!u.length)return null;let f={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:u[0]};if(s>=10)f.a=i[9];if(s===11)f.b=i[10];let a=u.findIndex((l,m)=>m>0&&l.toUpperCase()==="GLOSSMAP");if(a>0&&u[a+1])f.glossmap=u[a+1];if(t)f.next=!0;return f}var en=(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){let t=e.length,n=1,r=(a)=>a===32||a===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let a=n;while(n<t&&!r(e.charCodeAt(n)))n++;return a<n?e.slice(a,n):null},o=s();if(o===null)return null;let i=Array(12);for(let a=0;a<12;a++){let l=s();if(l===null)return null;let m=+l;if(!Number.isFinite(m))return null;i[a]=m}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let c=e.slice(n),u=/[ \\t]{2,}|\\t/.test(c)?c.split(/\\s+/).join(" "):c,f=Oe(o);if(!Number.isFinite(f))return null;return{t:1,color:f,m:i,file:ne(u)}}var nn=[0,12,6,9,12,12];function st(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=Oe(e[1]),r=nn[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=ne(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 pt(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,u=null,f=[],a=null,l=()=>{if(!u)return;let p=en(u.chunks.join("")),h=p[0]===137&&p[1]===80&&p[2]===78&&p[3]===71;(c??=new Map).set(ne(u.name),{name:u.name,bytes:p,...h?{mime:"image/png"}:{}}),u=null},m=!0,g=(p)=>{if(l(),o={name:ne(p),cmds:[]},s.set(o.name,o),!i)i=o.name;f=[],a=null,m=!0},d=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},A=(p,h)=>{if(a){p.tex=a,a=null;return}let M=f[f.length-1];if(!M)return;if(M.fallback){if(!h)p.fallback=!0}else p.tex=M.map};for(let p of e.split(`\n`)){let h=p.trim();if(!h)continue;if(r&&h.charCodeAt(0)>=50&&h.charCodeAt(0)<=53&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){if(u||d)continue;if(!o)g(t);let L=h.slice(2).trimStart(),R=L.search(/\\s/),T={t:h.charCodeAt(0)-48,color:Oe(R<0?L:L.slice(0,R)),p:[],src:h};A(T,!1),o.cmds.push(T),m=!1;continue}if(h.charCodeAt(0)===48&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){let L=2;while(h.charCodeAt(L)===32||h.charCodeAt(L)===9)L++;let R=L;while(R<h.length&&h.charCodeAt(R)!==32&&h.charCodeAt(R)!==9)R++;let T=h.slice(L,R),x=/[^\\x21-\\x7e]/.test(T)?h.slice(L).trim().split(/\\s+/)[0]:T;if(!Xt.has(x)&&!(x.length>=4&&x.length<=6&&Zt.has(x.toUpperCase()))){if(d||u)continue;if(!o)g(t);let w=h.slice(L),E={t:0,text:w};if(T.charCodeAt(0)===33)E.meta=T;if(a=null,m&&!o.org){let k=rt(w);if(k)o.org=k}let z=w.match(nt);if(z&&!o.movedTo){let k=z[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(k))k+=".dat";o.movedTo=ne(k)}o.cmds.push(E);continue}}if(h.charCodeAt(0)===49&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)&&!u&&!d){let L=tn(h);if(L){if(!o)g(t);A(L,!1),o.cmds.push(L),m=!1;continue}}let M=h.split(/\\s+/);if(+M[0]===0){let L=h.slice(1).trim(),R=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(R==="FILE"){let w=L.slice(5).trimStart().split("\\r")[0].trim();if(w){C(),d=!1,g(w);continue}}if(R==="NOFILE"){l(),o=null,d=!0;continue}if(R==="!DATA"){C(),l(),o=null,d=!1,u={name:L.slice(5).trim(),chunks:[]};continue}if(d)continue;if(u){if(M[1]==="!:")u.chunks.push(M.slice(2).join(""));continue}if(!o)g(t);let T={t:0,text:L};if(M[1]==="STEP")T.step=!0,f=[],a=null;else if(M[1]==="BFC")T.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(T.meta="ROTSTEP",T.step=!0,f=[],a=null,(M[2]??"").toUpperCase()==="END")T.rotstep={x:0,y:0,z:0,mode:"END"};else{let w=(M[5]??"REL").toUpperCase(),E=(z)=>{let k=Number(z);return Number.isFinite(k)?k:0};T.rotstep={x:E(M[2]),y:E(M[3]),z:E(M[4]),mode:["REL","ABS","ADD"].includes(w)?w:"REL"}}else if(M[1]==="BUFEXCHG"){T.meta="BUFEXCHG";let w=(M[2]??"").toUpperCase();T.bufexchg={op:w==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))T.meta=M[1];if(m&&!o.org){let w=rt(L);if(w)o.org=w}if(M[1]==="!TEXMAP"){let w=(M[2]??"").toUpperCase();if(a=null,w==="START"||w==="NEXT"){let E=qt(L.replace(/^!TEXMAP\\s+\\S+/i,""),w==="NEXT");if(T.texmap={op:w,...E?{map:E}:{}},E)if((o.texmaps??=[]).push(E),w==="START")f.push({map:E,fallback:!1});else a=E}else if(w==="FALLBACK"){T.texmap={op:w};let E=f[f.length-1];if(E)E.fallback=!0}else if(w==="END")T.texmap={op:w},f.pop()}else if(M[1]==="!:"){a=null;let w=st(M.slice(2));if(w)A(w,!0),T.geom=w}else a=null;let x=L.match(nt);if(x&&!o.movedTo){let w=x[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(w))w+=".dat";o.movedTo=ne(w)}o.cmds.push(T);continue}if(u||d)continue;if(!o)g(t);let v=st(M);if(!v){if(/^[2-5][ \\t]/.test(h))m=!1;continue}A(v,!1),o.cmds.push(v),m=!1}return l(),c?{main:i,files:s,data:c}:{main:i,files:s}}var Pn=Math.PI/180;function mt(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 ht(e,t){let[n,r,s,o,i,c,u,f,a,l,m,g]=e,[d,b,C,A,p,h,M,D,v,L,R,T]=t;return[o*d+i*b+c*C+n,u*d+f*b+a*C+r,l*d+m*b+g*C+s,o*A+i*M+c*L,o*p+i*D+c*R,o*h+i*v+c*T,u*A+f*M+a*L,u*p+f*D+a*R,u*h+f*v+a*T,l*A+m*M+g*L,l*p+m*D+g*R,l*h+m*v+g*T]}var Ne=[0,0,0,1,0,0,0,1,0,0,0,1];var ot=new WeakMap,rn=/^(s|8|48)\\//;function ze(e,t){let n=e.files.get(ne(t));if(!n)return"part";let r=ot.get(n);if(r)return r;if(n.org)r=ft.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&&rn.test(s.file))?"part":"model";return ot.set(n,r),r}var it=new WeakMap;function gt(e){let t=it.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 it.set(e,t),t}var at=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Be.get(e)??String(e):String(e),sn=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${at(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${at(e.color)} ${e.p.join(" ")}`,$e=(e,t)=>`${ne(e)}#${t}`;function on(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:$e(e.name,t),cmds:n}}function dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...on(e,t).cmds.map(sn)].join(`\n`)+`\n`}function je(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 bt(e){let[t,n,r,s,o,i,c,u,f,a,l,m]=e,g=u*m-f*l,d=-(c*m-f*a),b=c*l-u*a,C=s*g+o*d+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let A=1/C,p=[g*A,-(o*m-i*l)*A,(o*f-i*u)*A,d*A,(s*m-i*a)*A,-(s*f-i*c)*A,b*A,-(s*l-o*a)*A,(s*u-o*c)*A];return[-(p[0]*t+p[1]*n+p[2]*r),-(p[3]*t+p[4]*n+p[5]*r),-(p[6]*t+p[7]*n+p[8]*r),...p]}var an=(e)=>String(+e.toFixed(6)||0),lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function yt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(an).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 ${ne(e)}\n0 !TEXMAP END\n`;return{name:`${ne(e)}#tex-${je(r)}`,source:r}}var ln=(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 cn(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),u=Math.sin(n*r),f=Math.cos(n*r);return[c*f,-c*u,i,o*u+s*i*f,o*f-s*i*u,-s*c,s*u-o*i*f,s*f+o*i*u,o*c]}var ct=new WeakMap;function xt(e){let t=ct.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=cn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:ln(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),ct.set(e,n),n}class Ve 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 un=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=ut))return!1;return!0},wt=999999,vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Ct=new WeakMap,Mt=new WeakMap;function fn(e,t){let n=Mt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Ct.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},Mt.set(t,n);let r=n.parts.get(e);if(!r){let s=ne(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-${je(o)}`,source:o},n.parts.set(e,r)}return r}function pn(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,u=0,f=new Set,a=t.maxInstances??2000000,l=0,m=(d,b)=>{let C=d.name+"#"+b,A=c.get(C);if(!A){let p;A=Object.assign(()=>p??=dt(d,b),{file:d,step:b}),c.set(C,A)}return A},g=(d,b,C,A,p,h,M,D,v=null,L=[],R=[],T=void 0,x=null)=>{let w=d.files.get(b);if(!w||M>r||f.has(w))return;if(++l>a)throw new Ve("model",a);f.add(w);let E=x,z=0,k=M>0?++u:0,P=i&&k?[...L,k]:L,Y=i&&k?[...R,C]:R,I=i&&!v?new Map:null,j=-1,H=0,Z=(S,y,B,_,W,X,N)=>{if(j!==z)j=z,H=0;let q=I?.get(z+"|"+y);if(q)return q.n++,g(S,S===d?y:S.main,B,_,p+"/"+y,[...W,wt],M+1,X,[...W,wt],P,Y,N,E);let U=[...W,H++],F=n.length;g(S,S===d?y:S.main,B,_,p+"/"+y,U,M+1,X,v,P,Y,N,E),I?.set(z+"|"+y,{n:1,from:F,to:n.length})},O=xt(w),G=s?gt(w):[],K=0,J=(S,y,B,_,W,X,N,q,U)=>{if(v)_=v;if(++l>a)throw new Ve("model",a);let F={part:S,color:y,m:B,step:_[0],steps:_,localStep:W,path:p};if(q)F.colour=q;if(k){if(F.sub=k,i)F.subPath=P,F.subMats=Y}if(X)F.embedded=!0;if(N){let re=yt(S,N);F.texPart=re.name,F.texSource=re.source}else if(U){let re=fn(S,U);F.colPart=re.name,F.colSource=re.source}let V=O[W];if(V)F.view=V;return n.push(F),F},Q=(S)=>{while(K<G.length&&G[K]<=S){let y=G[K++];J($e(w.name,y),A,C,[...h,y],y,!1,null,T,x).source=m(w,y)}};for(let S of w.cmds){if(S.t===0&&S.step){z++;continue}let y=S;if(y.t>=2||y.t===0&&y.geom&&y.geom.t>=2){Q(z);continue}if(y.t===0){if(y.meta==="!COLOUR"){let V=hn(y.text);if(V&&V.code!==16&&V.code!==24)Ct.set(V,y.text),(E=new Map(E??[])).set(V.code,V);continue}if(o&&y.geom?.t===1)y=y.geom;else continue}if(y.t!==1)continue;if(o&&y.fallback)continue;let B=ht(C,y.m);if(!un(B))continue;let _=y.color===16?A:y.color,W=y.color===16?T:E?.get(y.color),X=[...h,z],N=o?y.tex??D:null,q=N?bt(y.m):null,U=N&&q?mt(N,q):null;if(d.files.has(y.file)){if(ze(d,y.file)==="model"){Z(d,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!0,U,W,E);continue}let F=t.resolveModel?.(y.file);if(F){Z(F,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!1,U,W,E)}if(Q(1/0),f.delete(w),I){for(let S of I.values())if(S.n>1)for(let y=S.from;y<S.to;y++)n[y].mult??=S.n}};if(ze(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ne],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,Ne,16,e.main,[],0,null),n}function Tt(e,t="main.ldr",n){return pn(pt(e,t,{geometryText:!0}),n)}var mn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function _e(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 At(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=_e(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 hn(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,u=0,f={type:"default"},a=1;while(a<n.length){let l=n[a].toUpperCase(),m=n[a+1];if(l==="CODE")s=m!==void 0&&De.test(m)?Ue(m):m!==void 0&&/^\\d+$/.test(m)?+m:NaN,a+=2;else if(l==="VALUE"){let g=_e(m);if(g)o=g;a+=2}else if(l==="EDGE")i=_e(m)??m,a+=2;else if(l==="ALPHA")c=+m,a+=2;else if(l==="LUMINANCE")u=+m,a+=2;else if(l==="CHROME")f={type:"chrome"},a+=1;else if(l==="PEARLESCENT")f={type:"pearlescent"},a+=1;else if(l==="RUBBER")f={type:"rubber"},a+=1;else if(l==="MATTE_METALLIC")f={type:"matte_metallic"},a+=1;else if(l==="METAL")f={type:"metal"},a+=1;else if(l==="MATERIAL"){let g=(n[a+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:d,next:b}=At(n,a+2);f={type:"glitter",material:d},a=b}else if(g==="SPECKLE"){let{grain:d,next:b}=At(n,a+2);f={type:"speckle",material:d},a=b}else if(g==="FABRIC"){let d=(n[a+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(d)?d.toLowerCase():void 0;f={type:"fabric",kind:b},a+=b?3:2}else a=n.length}else if(mn.has(l))a+=1;else a+=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(u)?u:0,finish:f}}function gn(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 He(e){let t=gn(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 dn(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(ne(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(ne(t),r)}let u=i.trim().replace(/\\s+/g," ");if(u)r.push(u)}return n}var bn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?ne(t.slice(14).join(" ")):null};function yn(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 Lt(e,t,n="main.ldr"){let r=dn(e,n),s=new Map;for(let o of t){let i=ne(o);if(!r.has(i)||s.has(i))continue;let c=new Set([i]),u=[i];while(u.length)for(let a of r.get(u.pop())){let l=bn(a);if(l&&r.has(l)&&!c.has(l))c.add(l),u.push(l)}let f=[i,...[...c].filter((a)=>a!==i).sort()].map((a)=>"0 FILE "+(a===i?"":a)+`\n`+r.get(a).join(`\n`)).join(`\n`);s.set(i,`emb/${yn(f)}.dat`)}return s}var St=(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,Et=new WeakMap;function Ge(e,t){let n=Et.get(e);if(!n)Et.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return 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=[],u=[];s.studs.forEach((m,g)=>{c.push(m[0]),u.push(m[1]);for(let d=0;d<12;d++)i[g*12+d]=m[2+d]});let f=null,a=0,l=0;if(s.mask){a=s.mask[0],l=s.mask[1];let m=s.mask[2];f=new Uint8Array(m.length);for(let g=0;g<m.length;g++)f[g]=m.charCodeAt(g)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:c,color:u,mask:f,nx:a,nz:l}),r}var fe=1073741824;class We{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,c=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&c[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,c=this.b,u=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,c[s]=t,u[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&c[s]===t&&u[s]===n){let f=this.vals[s];return this.vals[s]=r,f}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var pe=(e,t,n)=>e>-fe&&e<fe&&t>-fe&&t<fe&&n>-fe&&n<fe,de=2147483647;function xn(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){let s=new Map,o=(I)=>{let j=s.get(I);if(j===void 0)s.set(I,j=xn(t,I));return j},i=[],c=[],u=[],f=[],a=[],l=[],m=[],g=[],d=[],b=new We(e.length*2),C=[],A=[];for(let I=0;I<e.length;I++){let j=e[I],H=j.m,Z=t.parts[j.part];if(!Z||!Z.mask||!St(H)||o(j.color))continue;let O=Z.bbox,G=1/0,K=-1/0,J=1/0,Q=-1/0;for(let U=0;U<2;U++)for(let F=0;F<2;F++){let V=U?O[3]:O[0],re=F?O[5]:O[2],oe=H[0]+H[3]*V+H[5]*re,se=H[2]+H[9]*V+H[11]*re;if(oe<G)G=oe;if(oe>K)K=oe;if(se<J)J=se;if(se>Q)Q=se}let S=Math.round((H[1]+O[4])*2),y=Ge(t,j.part),B=Math.floor(G/40),_=Math.floor(K/40),W=Math.floor(J/40),X=Math.floor(Q/40);if(!((_-B+1)*(X-W+1)<=65536)||!pe(S,B,W)||!pe(S,_,X))continue;let N=-1;for(let U=b.get(S,B,W),F=0;U>=0&&F<8;U=C[U],F++){let V=A[U];if(i[V]!==G||c[V]!==K||u[V]!==J||f[V]!==Q||m[V]!==y)continue;let re=e[a[V]].m,oe=!0;for(let se=0;se<12;se++)if(re[se]!==H[se]){oe=!1;break}if(oe){N=V;break}}if(N>=0){let U=n?n[I]:0;if(n&&U<n[a[N]])l[N]=a[N],a[N]=I;else if(l[N]<0||n&&U<n[l[N]])l[N]=I;continue}let q=a.length;i.push(G),c.push(K),u.push(J),f.push(Q),a.push(I),l.push(-1),m.push(y),g.push(O[0]),d.push(O[2]);for(let U=B;U<=_;U++)for(let F=W;F<=X;F++){if(!pe(S,U,F))continue;let V=A.length;A.push(q),C.push(b.put(S,U,F,V))}}let p=[0,5,-5,5,-5],h=[0,5,5,-5,-5],M=NaN,D=NaN,v=NaN,L=-1,R=(I,j,H,Z)=>{let O=Math.round(j*2),G=Math.floor(I/40),K=Math.floor(H/40);if(!pe(O,G,K))return de;let J=de;if(O!==M||G!==D||K!==v)M=O,D=G,v=K,L=b.get(O,G,K);for(let Q=L;Q>=0;Q=C[Q]){let S=A[Q],y=a[S];if(y===Z&&(y=l[S])<0)continue;if(!(I-6>=i[S]-0.5&&I+6<=c[S]+0.5&&H-6>=u[S]-0.5&&H+6<=f[S]+0.5))continue;let B=e[a[S]].m,_=m[S],W=g[S],X=d[S],N=I-B[0],q=j-B[1],U=H-B[2],F=B[3]*N+B[6]*q+B[9]*U,V=B[5]*N+B[8]*q+B[11]*U,{nx:re,nz:oe,mask:se}=_,ce=!0;for(let ie=0;ie<5;ie++){let ae=Math.floor((F+p[ie]-W)/20),ue=Math.floor((V+h[ie]-X)/20);if(ae<0||ue<0||ae>=re||ue>=oe||se[ae*oe+ue]!==1){ce=!1;break}}if(ce){if(!n)return 0;let ie=n[y];if(ie<J)J=ie}}return J},T=0;for(let I of e){let j=Ge(t,I.part);if(j)T+=j.nStuds}let x=new Uint8Array(T),w=new Uint8Array(T),E=new We(T),z=0,k=n?new Int32Array(T).fill(de):void 0;for(let I=0,j=0;I<e.length;I++){let H=e[I],Z=Ge(t,H.part);if(!Z)continue;let O=H.m,G=Z.studM,K=O[0],J=O[1],Q=O[2],S=O[3],y=O[4],B=O[5],_=O[6],W=O[7],X=O[8],N=O[9],q=O[10],U=O[11];for(let F=0;F<Z.nStuds;F++,j++){let V=F*12,re=G[V+4],oe=G[V+7],se=G[V+10];if(!(Math.abs(_*re+W*oe+X*se-1)<0.001&&Math.abs(S*re+y*oe+B*se)<0.001&&Math.abs(N*re+q*oe+U*se)<0.001))continue;w[j]=1;let ce=G[V],ie=G[V+1],ae=G[V+2],ue=K+S*ce+y*ie+B*ae,Ke=J+_*ce+W*ie+X*ae,Xe=Q+N*ce+q*ie+U*ae,Ze=R(ue,Ke,Xe,I);if(Ze!==de){if(x[j]=1,z++,k)k[j]=Ze}let be=Math.round(ue),ye=Math.round(Ke),xe=Math.round(Xe);if(!pe(be,ye,xe))continue;if(!n){E.put(be,ye,xe,1);continue}let Ye=n[I],Je=E.get(be,ye,xe);if(Je<0||Ye<Je)E.put(be,ye,xe,Ye)}}let P=new Uint8Array(e.length),Y=n?new Int32Array(e.length).fill(de):void 0;for(let I=0;I<e.length;I++){let j=e[I],H=t.parts[j.part];if(!H||!H.under||!St(j.m)||o(j.color))continue;let Z=H.bbox,O=Math.round((Z[3]-Z[0])/20),G=Math.round((Z[5]-Z[2])/20);if(!O||!G||O*G>4096)continue;let K=j.m,J=!0,Q=0;for(let S=0;S<O&&J;S++)for(let y=0;y<G;y++){let B=Z[0]+10+20*S,_=Z[2]+10+20*y,W=K[0]+K[3]*B+K[5]*_,X=K[2]+K[9]*B+K[11]*_,N=Math.round(W),q=Math.round(K[1]+Z[4]),U=Math.round(X),F=pe(N,q,U)?E.get(N,q,U):-1;if(F<0){J=!1;break}if(F>Q)Q=F}if(J){if(P[I]=1,Y)Y[I]=Q}}return{nStuds:T,studHidden:x,studUp:w,underHidden:P,studsHidden:z,studHideStep:k,underHideStep:Y}}function Mn(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 m=l.colour;if(!m)return String(l.color);let g=o.get(m);if(g!==void 0)return g;let d=t.colorTable?.[l.color],b=d?.hex??t.colors?.[l.color],C=d?He({alpha:d.alpha??255,luminance:d.luminance??0,finish:d.finish??{type:"default"}}):"default:op",A=He(m);if(g=b&&b.toUpperCase()===m.hex.toUpperCase()&&C===A?String(l.color):m.hex.toUpperCase()+"/"+A,g!==String(l.color))s.set(g,m);return o.set(m,g),g},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),u=c.map((l)=>vt(l.steps)),f=[...new Set(u)].sort(),a=new Map(f.map((l,m)=>[l,m]));return{all:c,stepOf:u.map((l)=>a.get(l)),nSteps:f.length,localColours:s}}function Ce(e,t,n=!0){let r=Mn(e,t,n);return wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var ke="https://ldr-demo.vercel.app/cdn/v1/",Le=new Map,Te=new Map;function Se(e=ke,t=fetch){let n=Le.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(()=>Le.delete(e)),Le.set(e,n);return n}var An=(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"),Ee=(e,t)=>An(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Ee(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ee(r,t)])):e;function vn(e,t={}){let n=[],r=0,s={},o={};for(let m of e){let g=m.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let d=new DataView(g).getUint32(0,!0),b=new Uint8Array(g,4+d),C=r;n.push(b),r+=b.byteLength;let A=(4-r%4)%4;if(A)n.push(new Uint8Array(A)),r+=A;for(let[p,h]of Object.entries(m.header.parts??{}))if(!(p in s))s[p]=Ee(h,C);for(let[p,h]of Object.entries(m.header.studKinds??{}))if(!(p in o))o[p]=Ee(h,C)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),u=(4-(4+c.length)%4)%4,f=4+c.length+u,a=new Uint8Array(f+r);new DataView(a.buffer).setUint32(0,c.length+u,!0),a.set(c,4),a.fill(32,4+c.length,f);let l=f;for(let m of n)a.set(m,l),l+=m.byteLength;return ve(a.buffer)}async function Cn(e,t={}){e=[...e];try{return await kt(e,t)}catch(n){let r=t.cdn??ke,s=t.fetch??fetch;Le.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await kt(e,{...t,fetch:o})}catch{throw n}}}async function kt(e,t){let n=t.cdn??ke,r=t.fetch??fetch,s=t.gap??16384,o=await Se(n,r),i=[...new Set([...e].map(ne))],c=[],u=[];for(let p of i){if(Te.has(n+p))continue;let h=o.parts[p];if(h)u.push({name:p,off:h[0],len:h[1],file:h[2]??0});else c.push(p)}u.sort((p,h)=>p.file-h.file||p.off-h.off);let f=[];for(let p of u){let h=f[f.length-1];if(h&&h.file===p.file&&p.off-h.end<=s)h.end=Math.max(h.end,p.off+p.len),h.items.push(p);else f.push({file:p.file,start:p.off,end:p.off+p.len,items:[p]})}let a=0,l=0,m=0,g=new Map,d=async()=>{while(m<f.length){let p=f[m++],h=g.get(p.file);if(h)h=h.subarray(p.start,p.end);else{let M=await r(new URL(o.archives[p.file],n).href,{headers:{Range:`bytes=${p.start}-${p.end-1}`,"Accept-Encoding":"identity"}});if(!M.ok)throw Error(`ldr: parts CDN ${M.status}`);if(l++,h=new Uint8Array(await M.arrayBuffer()),a+=h.byteLength,M.status===200)g.set(p.file,h),h=h.subarray(p.start,p.end)}for(let M of p.items){let D=Ae(h.subarray(M.off-p.start,M.off-p.start+M.len)),v=D.buffer.slice(D.byteOffset,D.byteOffset+D.byteLength);Te.set(n+M.name,ve(v))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,f.length)},d));let b=i.filter((p)=>Te.has(n+p)).map((p)=>Te.get(n+p)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?vn(b,C):ve(Tn(C)),missing:c,requests:l,bytes:a}}function Tn(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 Ln(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 Pt(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let c of e){let u=c.embedded?t.get(c.part):ne(c.part),f=u?n.parts[u]:void 0;if(!f)continue;if(f[3]!=null)o=!0,r+=f[3];if(!i.has(u))i.add(u),s+=f[1]}return{bodyTris:r,packBytes:s,known:o}}class Pe 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 It(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Se(t.cdn??ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(x)=>{if(!x.ok)throw Error(`ldr: ${x.status} fetching ${e}`);return et(await x.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":tt(e)),u=Tt(o,c,{looseGeometry:!1,callouts:t.callouts}),f=performance.now();t.onParsed?.(u),await s;let a=Lt(o,new Set(u.filter((x)=>x.embedded).map((x)=>x.part)),c),l=(x,w)=>t.maxBodyTris!=null&&x>t.maxBodyTris||t.maxPackBytes!=null&&w>t.maxPackBytes,m=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(x)=>new Pe({...x,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),d="full";if(m){let x=Pt(u,a,await s);if(l(x.known?x.bodyTris:0,x.packBytes)){if(!t.lowCdn)throw g(x);let w=await Se(t.lowCdn,r).catch(()=>null);if(!w)throw g(x);let E=Pt(u,a,w);if(l(E.known?E.bodyTris:0,E.packBytes))throw g(E);d="low"}}let b=[...u.filter((x)=>!x.embedded).map((x)=>x.part),...a.values()],C=async()=>{let x=await Cn(b,d==="low"?{...t,cdn:t.lowCdn}:t);for(let[w,E]of a){let z=x.pack.header.parts[E];if(z)x.pack.header.parts[w]=z}return{...x,packBytes:x.pack.buffer?.byteLength??x.pack.bytes??0,bodyTris:Ln(u,x.pack)}},A=await C();if(m&&l(A.bodyTris,A.packBytes)&&d==="full"&&t.lowCdn&&await Se(t.lowCdn,r).then(()=>!0,()=>!1)){d="low";let x=A;A=await C(),A.requests+=x.requests,A.bytes+=x.bytes}if(m&&l(A.bodyTris,A.packBytes))throw g(A);let{pack:p,missing:h,requests:M,bytes:D}=A,v=new Map([...a].map(([x,w])=>[w,x])),L=h.map((x)=>v.get(x)??x),R=performance.now(),T=t.cull?Ce(u,p.header,t.textures!==!1):void 0;return{insts:u,pack:p,tier:d,missing:L,requests:M,bytes:D,cull:T,timings:{fetchModel:i-n,parse:f-i,parts:R-f,...T?{cull:performance.now()-R}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await It(n,{...r,cull:!1,onParsed:(a)=>self.postMessage({id:t,insts:a})}),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=Ce(s.insts,s.pack.header,r.textures!==!1),u=performance.now()-i,f=[];for(let a of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(a)f.push(a.buffer);self.postMessage({id:t,cull:c,ms:u},f)}catch(s){if(s instanceof Pe||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';
4544
4706
 
4545
- // ../../../../../../../tmp/ldr-build-78cdvu/src/cdn.ts
4707
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/cdn.ts
4546
4708
  var worker;
4547
4709
  var seq = 0;
4548
4710
  var pending = new Map;
@@ -4656,11 +4818,20 @@ async function loadModel(source, o = {}) {
4656
4818
  timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
4657
4819
  });
4658
4820
  }
4659
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/library.ts
4660
- import { existsSync, readFileSync } from "fs";
4821
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/library.ts
4822
+ import { existsSync, readFileSync, statSync } from "fs";
4661
4823
  import { join } from "path";
4662
4824
  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]];
4663
4825
  var det = (m) => 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]);
4826
+ var f32 = (x) => Number.isFinite(Math.fround(x));
4827
+ var inRange3 = (x) => Math.abs(x) <= MAX_COORD;
4828
+ var inRange122 = (m) => {
4829
+ for (let i = 0;i < 12; i++)
4830
+ if (!inRange3(m[i]))
4831
+ return false;
4832
+ return true;
4833
+ };
4834
+ var MESH_WORK_LIMIT = 1e6;
4664
4835
  var IDENTITY12 = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
4665
4836
  function isPlainAlias(f, target) {
4666
4837
  if (STUB_OVERRIDES[norm(f.name)] === target)
@@ -4733,8 +4904,10 @@ class Library {
4733
4904
  }
4734
4905
  resolveFile(root, dir, name) {
4735
4906
  const exact = join(root, dir, name);
4736
- if (existsSync(exact))
4737
- return exact;
4907
+ try {
4908
+ if (statSync(exact).isFile())
4909
+ return exact;
4910
+ } catch {}
4738
4911
  return null;
4739
4912
  }
4740
4913
  colors() {
@@ -4761,6 +4934,8 @@ class Library {
4761
4934
  if (hit)
4762
4935
  return hit;
4763
4936
  const pos = [], col = [], edges = [], cond = [];
4937
+ this.work = 0;
4938
+ this.open.clear();
4764
4939
  const tx = opts.texmap ? { uv: [], tri: [], names: [], gloss: [] } : undefined;
4765
4940
  const r = this.where(name);
4766
4941
  if (r)
@@ -4796,10 +4971,38 @@ class Library {
4796
4971
  }
4797
4972
  return null;
4798
4973
  }
4974
+ open = new Set;
4975
+ work = 0;
4976
+ workLimit = MESH_WORK_LIMIT;
4977
+ flatY(doc, fname, m = I, depth = 0, budget = { n: 1e5 }) {
4978
+ const f = doc.files.get(fname);
4979
+ if (!f || depth > 40)
4980
+ return true;
4981
+ if (--budget.n < 0)
4982
+ return false;
4983
+ for (const c of f.cmds) {
4984
+ if (c.t === 1) {
4985
+ const sub = doc.files.has(c.file) ? doc : this.where(c.file)?.doc;
4986
+ if (sub && !this.flatY(sub, sub === doc ? c.file : sub.main, mul(m, c.m), depth + 1, budget))
4987
+ return false;
4988
+ continue;
4989
+ }
4990
+ if (c.t === 0)
4991
+ continue;
4992
+ const p = c.p;
4993
+ for (let i = 0;i < p.length; i += 3)
4994
+ if (Math.abs(m[6] * p[i] + m[7] * p[i + 1] + m[8] * p[i + 2] + m[1]) > 0.000001)
4995
+ return false;
4996
+ }
4997
+ return true;
4998
+ }
4799
4999
  emit(doc, fname, m, color, inv, clip, pos, col, edges, cond, tx, texIn = null, scope0 = null) {
4800
5000
  const f = doc.files.get(fname);
4801
- if (!f)
5001
+ if (!f || this.open.has(f))
4802
5002
  return;
5003
+ if (++this.work > this.workLimit)
5004
+ throw new ModelLimitError("part", this.workLimit);
5005
+ this.open.add(f);
4803
5006
  let ccw = true, invertNext = false, clipLocal = true, certified = null, scope = scope0;
4804
5007
  const flip = inv !== det(m) < 0;
4805
5008
  const cc = (c) => {
@@ -4865,13 +5068,21 @@ class Library {
4865
5068
  const tex = tx ? c.tex ? transformTexMap(c.tex, m) : texIn : null;
4866
5069
  if (c.t === 1) {
4867
5070
  const sub = doc.files.has(c.file) ? doc : this.where(c.file)?.doc;
4868
- if (sub)
4869
- this.emit(sub, sub === doc ? c.file : sub.main, mul(m, c.m), cc(c.color), inv !== invertThis, cull, pos, col, edges, cond, tx, tex, scope);
5071
+ const sf = sub ? sub === doc ? c.file : sub.main : "", fx = sub ? singularFix(c.m, () => this.flatY(sub, sf)) : null;
5072
+ const mm = sub ? mul(m, fx ? fx.m : c.m) : null;
5073
+ if (sub && inRange122(mm))
5074
+ this.emit(sub, sf, mm, cc(c.color), inv !== invertThis, cull && (!fx || fx.cull), pos, col, edges, cond, tx, tex, scope);
4870
5075
  continue;
4871
5076
  }
4872
5077
  const p = c.p, v = [];
4873
- for (let i = 0;i < p.length; i += 3)
4874
- v.push(xf(m, p[i], p[i + 1], p[i + 2]));
5078
+ let ok = p.length >= (c.t === 2 ? 6 : c.t === 3 ? 9 : 12);
5079
+ for (let i = 0;i + 2 < p.length && ok; i += 3) {
5080
+ const q = xf(m, p[i], p[i + 1], p[i + 2]);
5081
+ ok = inRange3(q[0]) && inRange3(q[1]) && inRange3(q[2]);
5082
+ v.push(q);
5083
+ }
5084
+ if (!ok)
5085
+ continue;
4875
5086
  if (c.t === 2) {
4876
5087
  edges.push(...v[0], ...v[1]);
4877
5088
  continue;
@@ -4884,12 +5095,16 @@ class Library {
4884
5095
  const ti = tx && tex ? texIdx(tex) : -1;
4885
5096
  const code = cc(c.color);
4886
5097
  const tri = (a, b, d) => {
5098
+ if (++this.work > this.workLimit)
5099
+ throw new ModelLimitError("part", this.workLimit);
4887
5100
  pos.push(...a, ...b, ...d);
4888
5101
  col.push(code);
4889
5102
  if (tx) {
4890
- tx.tri.push(ti);
4891
- if (tex)
4892
- tx.uv.push(...texmapTriangleUV(tex, [a, b, d]));
5103
+ const w = tex ? texmapTriangleUV(tex, [a, b, d]) : null;
5104
+ const good = !!w && w.every(f32);
5105
+ tx.tri.push(good ? ti : -1);
5106
+ if (good)
5107
+ tx.uv.push(...w);
4893
5108
  else
4894
5109
  tx.uv.push(NaN, NaN, NaN, NaN, NaN, NaN);
4895
5110
  }
@@ -4903,6 +5118,7 @@ class Library {
4903
5118
  if (!cull)
4904
5119
  emitFace([...ordered].reverse());
4905
5120
  }
5121
+ this.open.delete(f);
4906
5122
  }
4907
5123
  flatten(doc, opts = {}) {
4908
5124
  for (const f of doc.files.keys())
@@ -4952,11 +5168,11 @@ class Library {
4952
5168
  return insts;
4953
5169
  }
4954
5170
  }
4955
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/build-pack.ts
5171
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/build-pack.ts
4956
5172
  import fs3 from "node:fs";
4957
5173
  import path3 from "node:path";
4958
5174
 
4959
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/resolver.ts
5175
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/resolver.ts
4960
5176
  import fs from "node:fs";
4961
5177
  import path from "node:path";
4962
5178
  var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
@@ -5175,7 +5391,7 @@ function splitModel(text, fallbackName = "main.ldr") {
5175
5391
  main = null;
5176
5392
  };
5177
5393
  for (const line of text.split(/\r?\n/)) {
5178
- const m = /^\s*0\s+FILE\s+(.+)$/i.exec(line);
5394
+ const m = /^\s*0\s+FILE\s+(\S[^\r]*)/i.exec(line);
5179
5395
  if (m) {
5180
5396
  firstBlock();
5181
5397
  flush();
@@ -5285,11 +5501,11 @@ function collectDeps(lib, refs) {
5285
5501
  return out;
5286
5502
  }
5287
5503
 
5288
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/compile.ts
5504
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/compile.ts
5289
5505
  import fs2 from "node:fs";
5290
5506
  import path2 from "node:path";
5291
5507
 
5292
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/lod.ts
5508
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/lod.ts
5293
5509
  import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
5294
5510
  await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
5295
5511
  function reorderMesh(P, N, C, I) {
@@ -5481,7 +5697,7 @@ function lodChain(P, C, I) {
5481
5697
  return out;
5482
5698
  }
5483
5699
 
5484
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/compile.ts
5700
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/compile.ts
5485
5701
  class BfcState {
5486
5702
  accum;
5487
5703
  ccw = true;
@@ -5562,6 +5778,20 @@ var hexRgba = (hex) => {
5562
5778
  return [(v >> 16) / 255, (v >> 8 & 255) / 255, (v & 255) / 255, 1];
5563
5779
  };
5564
5780
  var det3 = (m) => 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]);
5781
+ var inRangeM = (v) => {
5782
+ for (let i = 0;i < v.length; i++)
5783
+ if (!(Math.abs(v[i]) <= MAX_COORD))
5784
+ return false;
5785
+ return true;
5786
+ };
5787
+ var finiteAll = (v) => {
5788
+ for (let i = 0;i < v.length; i++)
5789
+ if (!Number.isFinite(v[i]))
5790
+ return false;
5791
+ return true;
5792
+ };
5793
+ var f322 = (p) => Math.abs(p[0]) <= MAX_COORD && Math.abs(p[1]) <= MAX_COORD && Math.abs(p[2]) <= MAX_COORD;
5794
+ var PART_WORK_LIMIT = 1e6;
5565
5795
 
5566
5796
  class Compiler {
5567
5797
  lib;
@@ -5573,6 +5803,43 @@ class Compiler {
5573
5803
  this.opts = opts;
5574
5804
  this.colors = loadColors(lib.root);
5575
5805
  }
5806
+ flat = new Map;
5807
+ flatY(key) {
5808
+ const hit = this.flat.get(key);
5809
+ if (hit !== undefined)
5810
+ return hit;
5811
+ let budget = 1e5;
5812
+ const walk = (fk, M, depth) => {
5813
+ if (depth > 40)
5814
+ return true;
5815
+ if (--budget < 0)
5816
+ return false;
5817
+ for (const raw of this.lib.read(fk).split(/\r?\n/)) {
5818
+ const t = raw.trim();
5819
+ const c = t[0];
5820
+ if (c === "1") {
5821
+ const r = parseType1(t);
5822
+ if (!r || !finiteAll(r.m))
5823
+ continue;
5824
+ const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
5825
+ const k = this.resolve(r.name, TOP_STUD_RE.test(base));
5826
+ if (k && !walk(k, compose(M, r.m), depth + 1))
5827
+ return false;
5828
+ continue;
5829
+ }
5830
+ if (c !== "2" && c !== "3" && c !== "4" && c !== "5")
5831
+ continue;
5832
+ const v = t.split(/\s+/).slice(2).map(Number), n = c === "2" ? 2 : c === "3" ? 3 : 4;
5833
+ for (let i = 0;i < n * 3; i += 3)
5834
+ if (Math.abs(M[1] + M[6] * v[i] + M[7] * v[i + 1] + M[8] * v[i + 2]) > 0.000001)
5835
+ return false;
5836
+ }
5837
+ return true;
5838
+ };
5839
+ const r = walk(key, IDENT, 0);
5840
+ this.flat.set(key, r);
5841
+ return r;
5842
+ }
5576
5843
  resolve(ref, isStud) {
5577
5844
  const key = this.lib.resolve(ref);
5578
5845
  if (!key)
@@ -5598,10 +5865,19 @@ class Compiler {
5598
5865
  if (this.cache.has(ck))
5599
5866
  return this.cache.get(ck);
5600
5867
  const out = { body: { pos: [], col: [] }, under: { pos: [], col: [] }, edges: [], condLines: 0, cond: this.opts.cond ? [] : undefined, condUnder: this.opts.cond ? [] : undefined, studs: [], bbox: [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity], fullBottom: false };
5601
- const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
5868
+ const colorOf = (code) => code === "16" ? [1, 1, 1, 0] : code.charCodeAt(1) === 120 && !/^0x2[0-9a-f]{6}/i.test(code) && String(parseColor(code)) !== code ? colorOf(String(parseColor(code))) : [...this.colors.get(code) || (code.startsWith("0x2") ? [parseInt(code.slice(3, 5), 16) / 255, parseInt(code.slice(5, 7), 16) / 255, parseInt(code.slice(7, 9), 16) / 255] : blendedRgb(code) ?? [1, 0, 1]), 1];
5869
+ const open = new Set;
5870
+ let work = 0;
5871
+ const lim = this.opts.workLimit ?? PART_WORK_LIMIT;
5872
+ const step = () => {
5873
+ if (++work > lim)
5874
+ throw new ModelLimitError(`part ${key}`, lim);
5875
+ };
5602
5876
  const walk = (fk, M, color, invert, target, depth, inh = null, scope0 = null, cull = true) => {
5603
- if (depth > 40)
5877
+ if (depth > 40 || open.has(fk))
5604
5878
  return;
5879
+ step();
5880
+ open.add(fk);
5605
5881
  const bfc = new BfcState(cull);
5606
5882
  let scope = scope0;
5607
5883
  for (const raw of this.lib.read(fk).split(/\r?\n/)) {
@@ -5624,7 +5900,7 @@ class Compiler {
5624
5900
  if (c === "1") {
5625
5901
  const invertNext = bfc.takeInvert();
5626
5902
  const r = parseType1(t);
5627
- if (!r)
5903
+ if (!r || !finiteAll(r.m))
5628
5904
  continue;
5629
5905
  const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
5630
5906
  const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
@@ -5632,21 +5908,28 @@ class Compiler {
5632
5908
  if (!ck2)
5633
5909
  continue;
5634
5910
  const childColor = r.color === "16" ? color : r.color, childInh = r.color === "16" ? inh : this.local(r.color, scope);
5635
- const Mc = compose(M, r.m);
5636
- const inv = invert !== invertNext !== det3(r.m) < 0;
5637
- if (isTop && separateStuds) {
5911
+ const fx = singularFix(r.m, () => this.flatY(ck2)), rm = fx ? fx.m : r.m, subCull = bfc.cull && (!fx || fx.cull);
5912
+ const Mc = compose(M, rm);
5913
+ if (!inRangeM(Mc))
5914
+ continue;
5915
+ const inv = invert !== invertNext !== det3(rm) < 0;
5916
+ if (isTop && separateStuds && (!fx || fx.cull)) {
5638
5917
  out.studs.push({ kind: ck2, color: childInh ? this.studToken(childColor, childInh) : childColor, m: Mc });
5639
5918
  fullKind.set(out.studs.length - 1, this.lib.resolve(r.name));
5640
5919
  growBox(out.bbox, Mc, this.compile(ck2, false).bbox);
5641
5920
  continue;
5642
5921
  }
5643
- walk(ck2, Mc, childColor, inv, isUnder ? "under" : target, depth + 1, childInh, scope, bfc.cull);
5922
+ walk(ck2, Mc, childColor, inv, isUnder ? "under" : target, depth + 1, childInh, scope, subCull);
5644
5923
  continue;
5645
5924
  }
5646
5925
  const tok = t.split(/\s+/);
5647
5926
  if (c === "2") {
5648
5927
  const v = tok.slice(2, 8).map(Number);
5649
- out.edges.push(...xf2(M, v.slice(0, 3)), ...xf2(M, v.slice(3, 6)));
5928
+ if (v.length < 6 || !finiteAll(v))
5929
+ continue;
5930
+ const a = xf2(M, v.slice(0, 3)), b = xf2(M, v.slice(3, 6));
5931
+ if (f322(a) && f322(b))
5932
+ out.edges.push(...a, ...b);
5650
5933
  continue;
5651
5934
  }
5652
5935
  if (c === "5") {
@@ -5654,18 +5937,26 @@ class Compiler {
5654
5937
  const dst = target === "under" ? out.condUnder : out.cond;
5655
5938
  if (dst) {
5656
5939
  const v = t.split(/\s+/).slice(2, 14).map(Number);
5657
- if (v.length === 12 && v.every(Number.isFinite))
5658
- for (let i = 0;i < 12; i += 3)
5659
- dst.push(...xf2(M, v.slice(i, i + 3)));
5940
+ if (v.length === 12 && v.every(Number.isFinite)) {
5941
+ const q = [0, 3, 6, 9].map((i) => xf2(M, v.slice(i, i + 3)));
5942
+ if (q.every(f322))
5943
+ for (const p of q)
5944
+ dst.push(...p);
5945
+ }
5660
5946
  }
5661
5947
  continue;
5662
5948
  }
5663
5949
  if (c === "3" || c === "4") {
5664
5950
  const n = c === "3" ? 3 : 4;
5665
5951
  const v = tok.slice(2, 2 + n * 3).map(Number);
5952
+ if (v.length < n * 3 || !finiteAll(v))
5953
+ continue;
5666
5954
  const pts = [];
5667
5955
  for (let i = 0;i < n; i++)
5668
5956
  pts.push(xf2(M, v.slice(i * 3, i * 3 + 3)));
5957
+ if (!pts.every(f322))
5958
+ continue;
5959
+ step();
5669
5960
  for (const p of pts)
5670
5961
  grow(out.bbox, p);
5671
5962
  const flip = !bfc.ccw !== invert, rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf), b = out[target];
@@ -5686,6 +5977,7 @@ class Compiler {
5686
5977
  }
5687
5978
  if (!bfc.certified)
5688
5979
  out.uncertified = true;
5980
+ open.delete(fk);
5689
5981
  };
5690
5982
  const fullKind = new Map;
5691
5983
  let culled = 0;
@@ -5786,9 +6078,11 @@ class Compiler {
5786
6078
  }
5787
6079
  texPass(key, out, separateStuds, colorOf) {
5788
6080
  const tbody = { pos: [], col: [] }, texb = new Map;
6081
+ const open = new Set;
5789
6082
  const walk = (fk, M, color, invert, target, depth, texIn, inh = null, scope0 = null, cull = true) => {
5790
- if (depth > 40)
6083
+ if (depth > 40 || open.has(fk))
5791
6084
  return;
6085
+ open.add(fk);
5792
6086
  const bfc = new BfcState(cull);
5793
6087
  let scope = scope0;
5794
6088
  let stack = [];
@@ -5864,17 +6158,21 @@ class Compiler {
5864
6158
  }
5865
6159
  if (c === "1") {
5866
6160
  const r = parseType1(t);
5867
- if (!r)
6161
+ if (!r || !finiteAll(r.m))
5868
6162
  continue;
5869
6163
  const base = r.name.trim().replace(/\\/g, "/").split("/").pop().toLowerCase();
5870
6164
  const isTop = TOP_STUD_RE.test(base), isUnder = UNDER_STUD_RE.test(base);
5871
6165
  const ck2 = this.resolve(r.name, isTop);
5872
6166
  if (!ck2)
5873
6167
  continue;
5874
- const inv = invert !== invertNext !== det3(r.m) < 0;
5875
- if (isTop && separateStuds)
6168
+ const fx = singularFix(r.m, () => this.flatY(ck2)), rm = fx ? fx.m : r.m, subCull = bfc.cull && (!fx || fx.cull);
6169
+ const inv = invert !== invertNext !== det3(rm) < 0;
6170
+ if (isTop && separateStuds && (!fx || fx.cull))
6171
+ continue;
6172
+ const Mc = compose(M, rm);
6173
+ if (!inRangeM(Mc))
5876
6174
  continue;
5877
- walk(ck2, compose(M, r.m), r.color === "16" ? color : r.color, inv, isUnder ? "under" : target, depth + 1, tex, r.color === "16" ? inh : this.local(r.color, scope), scope, bfc.cull);
6175
+ walk(ck2, Mc, r.color === "16" ? color : r.color, inv, isUnder ? "under" : target, depth + 1, tex, r.color === "16" ? inh : this.local(r.color, scope), scope, subCull);
5878
6176
  continue;
5879
6177
  }
5880
6178
  if (c !== "3" && c !== "4")
@@ -5882,11 +6180,17 @@ class Compiler {
5882
6180
  const tok = t.split(/\s+/);
5883
6181
  const n = c === "3" ? 3 : 4;
5884
6182
  const v = tok.slice(2, 2 + n * 3).map(Number);
6183
+ if (v.length < n * 3 || !finiteAll(v))
6184
+ continue;
5885
6185
  const pts = [];
5886
6186
  for (let i = 0;i < n; i++)
5887
6187
  pts.push(xf2(M, v.slice(i * 3, i * 3 + 3)));
6188
+ if (!pts.every(f322))
6189
+ continue;
5888
6190
  const order = windOrder(n, !bfc.ccw !== invert, bfc.cull || !!out.uncertified);
5889
6191
  const rgba = this.rgbaAt(tok[1], color, inh, scope, colorOf);
6192
+ if (tex && !texmapTriangleUV(tex, pts).every((x) => Number.isFinite(Math.fround(x))))
6193
+ tex = null;
5890
6194
  if (tex) {
5891
6195
  const tk = tex.glossmap ? tex.texture + "\x00" + tex.glossmap : tex.texture;
5892
6196
  let b = texb.get(tk);
@@ -5909,6 +6213,7 @@ class Compiler {
5909
6213
  tbody.col.push(...rgba);
5910
6214
  }
5911
6215
  }
6216
+ open.delete(fk);
5912
6217
  };
5913
6218
  walk(key, IDENT, "16", false, "body", 0, null);
5914
6219
  if (texb.size) {
@@ -6013,23 +6318,79 @@ function seatStuds(out, fullKind, kindBox) {
6013
6318
  if (!out.studs.length)
6014
6319
  return;
6015
6320
  const tris = [out.body.pos, out.under.pos];
6016
- const covered = (c, up) => {
6017
- for (const p of tris)
6321
+ const nTri = (out.body.pos.length + out.under.pos.length) / 9;
6322
+ let nChk = 0;
6323
+ for (let i = 0;i < out.studs.length; i++) {
6324
+ const f = fullKind.get(i);
6325
+ if (f && f !== out.studs[i].kind)
6326
+ nChk++;
6327
+ }
6328
+ let grid = null;
6329
+ if (nChk * 9 * nTri > 4000000) {
6330
+ const box = [];
6331
+ const sz = [];
6332
+ for (let t = 0;t < 2; t++) {
6333
+ const p = tris[t];
6018
6334
  for (let i = 0;i < p.length; i += 9) {
6019
- const ax = p[i], ay = p[i + 1], az = p[i + 2], ux = p[i + 3] - ax, uy = p[i + 4] - ay, uz = p[i + 5] - az, vx = p[i + 6] - ax, vy = p[i + 7] - ay, vz = p[i + 8] - az;
6020
- const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx, nl = Math.hypot(nx, ny, nz);
6021
- if (nl < 0.000000001)
6022
- continue;
6023
- if (!out.uncertified && nx * up[0] + ny * up[1] + nz * up[2] <= 0)
6024
- continue;
6025
- const wx = c[0] - ax, wy = c[1] - ay, wz = c[2] - az;
6026
- if (Math.abs((wx * nx + wy * ny + wz * nz) / nl) > 0.05)
6027
- continue;
6028
- const uu = ux * ux + uy * uy + uz * uz, vv = vx * vx + vy * vy + vz * vz, uv = ux * vx + uy * vy + uz * vz, wu = wx * ux + wy * uy + wz * uz, wv = wx * vx + wy * vy + wz * vz;
6029
- const d = uv * uv - uu * vv, s = (uv * wv - vv * wu) / d, t = (uv * wu - uu * wv) / d, e = 0.0001;
6030
- if (s >= -e && t >= -e && s + t <= 1 + e)
6031
- return true;
6335
+ const L = Math.max(Math.hypot(p[i + 3] - p[i], p[i + 4] - p[i + 1], p[i + 5] - p[i + 2]), Math.hypot(p[i + 6] - p[i], p[i + 7] - p[i + 1], p[i + 8] - p[i + 2]), Math.hypot(p[i + 6] - p[i + 3], p[i + 7] - p[i + 4], p[i + 8] - p[i + 5]));
6336
+ const g = 0.06 + 0.0004 * L;
6337
+ const b = [Math.min(p[i], p[i + 3], p[i + 6]) - g, Math.min(p[i + 1], p[i + 4], p[i + 7]) - g, Math.min(p[i + 2], p[i + 5], p[i + 8]) - g, Math.max(p[i], p[i + 3], p[i + 6]) + g, Math.max(p[i + 1], p[i + 4], p[i + 7]) + g, Math.max(p[i + 2], p[i + 5], p[i + 8]) + g, t, i];
6338
+ box.push(b);
6339
+ sz.push(Math.max(b[3] - b[0], b[4] - b[1], b[5] - b[2]));
6032
6340
  }
6341
+ }
6342
+ sz.sort((x, y) => x - y);
6343
+ const h = Math.max(2 * (sz[sz.length >> 1] ?? 1), 0.5);
6344
+ grid = { h, cells: new Map, big: [] };
6345
+ const G = grid;
6346
+ for (const b of box) {
6347
+ const ref = b[6] * 1073741824 + b[7];
6348
+ const ax = Math.floor(b[0] / h), bx = Math.floor(b[3] / h), ay = Math.floor(b[1] / h), by = Math.floor(b[4] / h), az = Math.floor(b[2] / h), bz = Math.floor(b[5] / h);
6349
+ if (!((bx - ax + 1) * (by - ay + 1) * (bz - az + 1) <= 512)) {
6350
+ G.big.push(ref);
6351
+ continue;
6352
+ }
6353
+ for (let x = ax;x <= bx; x++)
6354
+ for (let y = ay;y <= by; y++)
6355
+ for (let z = az;z <= bz; z++) {
6356
+ const key = x + "," + y + "," + z;
6357
+ let l = G.cells.get(key);
6358
+ if (!l)
6359
+ G.cells.set(key, l = []);
6360
+ l.push(ref);
6361
+ }
6362
+ }
6363
+ }
6364
+ const hit = (p, i, c, up) => {
6365
+ const ax = p[i], ay = p[i + 1], az = p[i + 2], ux = p[i + 3] - ax, uy = p[i + 4] - ay, uz = p[i + 5] - az, vx = p[i + 6] - ax, vy = p[i + 7] - ay, vz = p[i + 8] - az;
6366
+ const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx, nl = Math.hypot(nx, ny, nz);
6367
+ if (nl < 0.000000001)
6368
+ return false;
6369
+ if (!out.uncertified && nx * up[0] + ny * up[1] + nz * up[2] <= 0)
6370
+ return false;
6371
+ const wx = c[0] - ax, wy = c[1] - ay, wz = c[2] - az;
6372
+ if (Math.abs((wx * nx + wy * ny + wz * nz) / nl) > 0.05)
6373
+ return false;
6374
+ const uu = ux * ux + uy * uy + uz * uz, vv = vx * vx + vy * vy + vz * vz, uv = ux * vx + uy * vy + uz * vz, wu = wx * ux + wy * uy + wz * uz, wv = wx * vx + wy * vy + wz * vz;
6375
+ const d = uv * uv - uu * vv, s = (uv * wv - vv * wu) / d, t = (uv * wu - uu * wv) / d, e = 0.0001;
6376
+ return s >= -e && t >= -e && s + t <= 1 + e;
6377
+ };
6378
+ const covered = (c, up) => {
6379
+ if (!grid) {
6380
+ for (const p of tris)
6381
+ for (let i = 0;i < p.length; i += 9)
6382
+ if (hit(p, i, c, up))
6383
+ return true;
6384
+ return false;
6385
+ }
6386
+ const G = grid;
6387
+ const at = (ref) => hit(tris[ref >= 1073741824 ? 1 : 0], ref % 1073741824, c, up);
6388
+ for (const r of G.big)
6389
+ if (at(r))
6390
+ return true;
6391
+ for (const r of G.cells.get(Math.floor(c[0] / G.h) + "," + Math.floor(c[1] / G.h) + "," + Math.floor(c[2] / G.h)) ?? [])
6392
+ if (at(r))
6393
+ return true;
6033
6394
  return false;
6034
6395
  };
6035
6396
  out.studs.forEach((s, i) => {
@@ -6255,9 +6616,9 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
6255
6616
  return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
6256
6617
  }
6257
6618
 
6258
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/build-pack.ts
6619
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/build-pack.ts
6259
6620
  function packCompilerOpts(o) {
6260
- return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures };
6621
+ 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 } : {} };
6261
6622
  }
6262
6623
  function buildPack(o) {
6263
6624
  const lib = new Library2(o.ldrawRoot);
@@ -6327,13 +6688,14 @@ function buildPack(o) {
6327
6688
  const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
6328
6689
  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 } : {} };
6329
6690
  }
6330
- // ../../../../../../../tmp/ldr-build-78cdvu/src/node/promote.ts
6691
+ // ../../../../../../../tmp/ldr-build-5tVh0D/src/node/promote.ts
6331
6692
  var GEOM = /^\s*[2-5]\s/;
6332
6693
  var REF = /^\s*1\s/;
6333
- var FILE = /^\s*0\s+FILE\s+(.+?)\s*$/i;
6694
+ var FILE = /^\s*0\s+FILE\s+(\S.*?)\s*$/i;
6334
6695
  var END = /^\s*0\s+(NOFILE|!DATA)(\s|$)/i;
6335
6696
  var MODEL_ORG2 = /^(\s*0\s+!LDRAW_ORG\s+)(?:Unofficial_)?(?:Model|Submodel)\b/i;
6336
6697
  var PART_ORG2 = /^\s*0\s+!LDRAW_ORG\s+(?:Unofficial_)?Part\b/i;
6698
+ var ANY_ORG = /^\s*0\s+!LDRAW_ORG\s/i;
6337
6699
  var key = (s) => s.trim().toLowerCase().replace(/\\/g, "/");
6338
6700
  function promoteFlexParts(text) {
6339
6701
  const lines = text.split(/(?<=\n)/);
@@ -6342,7 +6704,7 @@ function promoteFlexParts(text) {
6342
6704
  for (let i = 0;i < lines.length; i++) {
6343
6705
  const l = lines[i], f = FILE.exec(l);
6344
6706
  if (f) {
6345
- blocks.push(cur = { name: f[1], org: -1, geom: 0, refs: [] });
6707
+ blocks.push(cur = { name: f[1], org: -1, model: false, geom: 0, refs: [] });
6346
6708
  continue;
6347
6709
  }
6348
6710
  if (END.test(l)) {
@@ -6357,13 +6719,15 @@ function promoteFlexParts(text) {
6357
6719
  const t = l.trim().split(/\s+/);
6358
6720
  if (t.length >= 15)
6359
6721
  cur.refs.push(key(t.slice(14).join(" ")));
6360
- } else if (cur.org < 0 && MODEL_ORG2.test(l))
6722
+ } else if (cur.org < 0 && ANY_ORG.test(l)) {
6361
6723
  cur.org = i;
6724
+ cur.model = MODEL_ORG2.test(l);
6725
+ }
6362
6726
  }
6363
- const plainModel = new Set(blocks.filter((b, i) => i > 0 && b.org >= 0 && !b.geom).map((b) => key(b.name)));
6727
+ const plainModel = new Set(blocks.filter((b, i) => i > 0 && b.model && !b.geom).map((b) => key(b.name)));
6364
6728
  const promoted = [];
6365
6729
  for (const b of blocks.slice(1)) {
6366
- if (b.org < 0 || !b.geom || b.refs.some((r) => plainModel.has(r)))
6730
+ if (!b.model || !b.geom || b.refs.some((r) => plainModel.has(r)))
6367
6731
  continue;
6368
6732
  lines[b.org] = lines[b.org].replace(MODEL_ORG2, "$1Unofficial_Part");
6369
6733
  promoted.push(b.name);
@@ -6574,7 +6938,9 @@ export {
6574
6938
  DEFAULT_PARTS_CDN,
6575
6939
  I as IDENTITY,
6576
6940
  Library,
6941
+ MAX_COORD,
6577
6942
  MIN_VIS,
6943
+ ModelLimitError,
6578
6944
  REORIENT,
6579
6945
  Library2 as ResolverLibrary,
6580
6946
  blendedColourHex,