ldr 0.34.10 → 0.34.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-vpoU1w/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;
@@ -809,7 +809,7 @@ function fileStepViews(f) {
809
809
  viewMemo.set(f, out);
810
810
  return out;
811
811
  }
812
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/model.ts
812
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/model.ts
813
813
  class ModelLimitError extends Error {
814
814
  limit;
815
815
  code = "ldr-model-limit";
@@ -1250,7 +1250,7 @@ function blendedColourHex(code) {
1250
1250
  const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
1251
1251
  return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
1252
1252
  }
1253
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/instructions.ts
1253
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/instructions.ts
1254
1254
  var MIN_VIS = 0.5;
1255
1255
  var REORIENT = 0.35;
1256
1256
  var deg = Math.PI / 180;
@@ -1618,10 +1618,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1618
1618
  }
1619
1619
  };
1620
1620
  }
1621
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/render.ts
1622
- import * as THREE from "three";
1621
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/render.ts
1622
+ import * as THREE2 from "three";
1623
1623
 
1624
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/pack-io.ts
1624
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/pack-io.ts
1625
1625
  import { decompress } from "fzstd";
1626
1626
  async function decompressPack(data) {
1627
1627
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1644,7 +1644,106 @@ function decodePack(buf) {
1644
1644
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1645
1645
  }
1646
1646
 
1647
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/cull.ts
1647
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/stud-decal.ts
1648
+ import * as THREE from "three";
1649
+ function studDecalUniforms(near = 0) {
1650
+ return { center: { value: new THREE.Vector3 }, near: { value: near } };
1651
+ }
1652
+ var _quad = new Map;
1653
+ function studDecalGeom(grid = 1) {
1654
+ const hit = _quad.get(grid);
1655
+ if (hit)
1656
+ return hit;
1657
+ const y = -4 / grid, r = 10;
1658
+ const pos = new Float32Array([-r, y, -r, r, y, -r, r, y, r, -r, y, -r, r, y, r, -r, y, r]);
1659
+ const nrm = new Int8Array(18);
1660
+ for (let i = 0;i < 6; i++)
1661
+ nrm[i * 3 + 1] = -127;
1662
+ const col = new Uint8Array(24);
1663
+ for (let i = 0;i < 6; i++) {
1664
+ col[i * 4] = col[i * 4 + 1] = col[i * 4 + 2] = 255;
1665
+ col[i * 4 + 3] = 0;
1666
+ }
1667
+ const g = new THREE.BufferGeometry;
1668
+ g.setAttribute("position", new THREE.BufferAttribute(pos, 3));
1669
+ g.setAttribute("normal", new THREE.BufferAttribute(nrm, 3, true));
1670
+ g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
1671
+ g.computeBoundingSphere();
1672
+ g.computeBoundingBox();
1673
+ _quad.set(grid, g);
1674
+ return g;
1675
+ }
1676
+ var cache = new WeakMap;
1677
+ function studDecalMaterial(base, U, grid) {
1678
+ let m = cache.get(base);
1679
+ if (!m)
1680
+ cache.set(base, m = new Map);
1681
+ const hit = m.get(grid);
1682
+ if (hit)
1683
+ return hit;
1684
+ const d = base.clone();
1685
+ const prev = base.onBeforeCompile;
1686
+ const key = base.customProgramCacheKey?.() ?? "";
1687
+ d.polygonOffset = true;
1688
+ d.polygonOffsetFactor = -2;
1689
+ d.polygonOffsetUnits = -4;
1690
+ d.onBeforeCompile = (s, r) => {
1691
+ prev.call(base, s, r);
1692
+ s.uniforms.uStudC = U.center;
1693
+ s.uniforms.uStudNear = U.near;
1694
+ s.vertexShader = s.vertexShader.replace("#include <common>", `#include <common>
1695
+ varying vec2 vSt;
1696
+ varying vec3 vSW;
1697
+ varying vec3 vTx;
1698
+ varying vec3 vTz;`).replace("#include <begin_vertex>", `#include <begin_vertex>
1699
+ vSt = position.xz;
1700
+ mat4 sdM = modelMatrix;
1701
+ #ifdef USE_INSTANCING
1702
+ sdM = modelMatrix * instanceMatrix;
1703
+ #endif
1704
+ vSW = (sdM * vec4(position, 1.0)).xyz;
1705
+ vTx = normalize((viewMatrix * sdM * vec4(1.0, 0.0, 0.0, 0.0)).xyz);
1706
+ vTz = normalize((viewMatrix * sdM * vec4(0.0, 0.0, 1.0, 0.0)).xyz);`);
1707
+ s.fragmentShader = s.fragmentShader.replace("#include <common>", `#include <common>
1708
+ uniform vec3 uStudC;
1709
+ uniform float uStudNear;
1710
+ varying vec2 vSt;
1711
+ varying vec3 vSW;
1712
+ varying vec3 vTx;
1713
+ varying vec3 vTz;`).replace("#include <roughnessmap_fragment>", `#include <roughnessmap_fragment>
1714
+ if (distance(vSW.xz, uStudC.xz) < uStudNear) discard; // the real studs stand here
1715
+ // parallax: march the view ray on from the studs' tops (the quad) down to the plate (they repeat every 20/SG LDU); the first point
1716
+ // inside a stud is its top (the first sample) or its wall (any later one), else the ray reaches the plate between studs
1717
+ const float SG = ${grid.toFixed(1)}, SC = 20.0 / SG, SR = 6.0 / SG, SH = 4.0 / SG; // cell, radius, height (LDU)
1718
+ vec3 sdUp = normalize(vNormal) * (gl_FrontFacing ? 1.0 : -1.0), sdV = normalize(vViewPosition);
1719
+ vec3 sdVt = vec3(dot(sdV, vTx), max(dot(sdV, sdUp), 0.08), dot(sdV, vTz)); // toward the eye, stud space (y: up)
1720
+ vec2 sdStep = sdVt.xz / sdVt.y * (SH / 8.0); if (length(sdStep) > SC * 0.2) sdStep *= SC * 0.2 / length(sdStep);
1721
+ float sdPxA = length(dFdx(vSt)), sdPxB = length(dFdy(vSt)), sdPx = min(sdPxA, sdPxB), sdPxM = max(sdPxA, sdPxB);
1722
+ float sdK = clamp((SC / sdPx - 2.5) / 3.0, 0.0, 1.0); // a stud cell under ~3 px: shading fades to the plate's average (no shimmer)
1723
+ float sdAa = max(sdPxM * 0.7, 0.05);
1724
+ float sdHit = -1.0; vec2 sdC = vec2(0.0);
1725
+ for (int i = 0; i <= 8; i++) { vec2 q = vSt - sdStep * float(i); vec2 c = (fract(q / SC + 0.5) - 0.5) * SC;
1726
+ if (length(c) < SR) { sdHit = float(i); sdC = c; break; } }
1727
+ vec2 sdG = (fract((vSt - sdStep * 8.0) / SC + 0.5) - 0.5) * SC; float sdRg = length(sdG); // the plate point, from its nearest stud
1728
+ float sdTop = sdHit == 0.0 ? 1.0 : 0.0, sdWall = sdHit > 0.0 ? 1.0 : 0.0;
1729
+ float sdRim = sdTop * smoothstep(SR - 0.9 * SH - sdAa, SR, length(sdC)); // the rounded edge of a top
1730
+ vec2 sdD = (sdHit >= 0.0 ? sdC : sdG) / max(length(sdHit >= 0.0 ? sdC : sdG), 1e-4);
1731
+ float sdAo = sdHit >= 0.0 ? 1.0 - 0.22 * sdWall * (sdHit / 8.0) // a wall darkens toward its foot
1732
+ : 1.0 - 0.45 * exp(-(sdRg - SR) / (0.5 * SH)); // the plate darkens next to a stud (contact shadow)
1733
+ float sdEdgeAvg = 0.9; // a cell's average darkening, what the shading fades to
1734
+ diffuseColor.rgb *= mix(sdEdgeAvg, sdAo, sdK);
1735
+ roughnessFactor = clamp(roughnessFactor * mix(1.0, sdTop > 0.5 ? 0.85 : 1.1, sdK), 0.04, 1.0);
1736
+ `).replace("#include <normal_fragment_maps>", `#include <normal_fragment_maps>
1737
+ { vec3 sdN = sdUp; vec3 sdR = vTx * sdD.x + vTz * sdD.y;
1738
+ if (sdWall > 0.5) sdN = normalize(sdR + sdUp * 0.12); else if (sdRim > 0.0) sdN = normalize(sdUp + sdR * 1.2 * sdRim);
1739
+ normal = normalize(mix(normal, sdN, sdK)); }`);
1740
+ };
1741
+ d.customProgramCacheKey = () => key + `|stud-decal-${grid}`;
1742
+ m.set(grid, d);
1743
+ return d;
1744
+ }
1745
+
1746
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/cull.ts
1648
1747
  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;
1649
1748
  var prepCache = new WeakMap;
1650
1749
  var lastH = null;
@@ -1930,17 +2029,14 @@ function cullPass(insts, H, steps, eCap) {
1930
2029
  return v;
1931
2030
  };
1932
2031
  const nI = insts.length;
1933
- let cap = 0, nR = 0;
1934
- for (let idx = 0, lp = "";idx < nI; idx++) {
1935
- const part = insts[idx].part;
1936
- if (part === lp) {
1937
- cap++;
1938
- continue;
1939
- }
1940
- const p = H.parts[part];
1941
- if (p && p.mask) {
1942
- cap++;
1943
- lp = part;
2032
+ let cap = 0, nR = 0, nStuds = 0;
2033
+ const pps = new Array(nI);
2034
+ for (let idx = 0;idx < nI; idx++) {
2035
+ const pp = pps[idx] = prepPart(H, insts[idx].part);
2036
+ if (pp) {
2037
+ nStuds += pp.nStuds;
2038
+ if (pp.mask)
2039
+ cap++;
1944
2040
  }
1945
2041
  }
1946
2042
  const rx0 = new Float64Array(cap), rx1 = new Float64Array(cap), rz0 = new Float64Array(cap), rz1 = new Float64Array(cap);
@@ -1975,7 +2071,7 @@ function cullPass(insts, H, steps, eCap) {
1975
2071
  z1 = wz;
1976
2072
  }
1977
2073
  const lv2 = Math.round((m[1] + b[4]) * 2);
1978
- const pp = prepPart(H, it.part);
2074
+ const pp = pps[idx];
1979
2075
  const cx0 = Math.floor(x0 / CELL), cx1 = Math.floor(x1 / CELL), cz0 = Math.floor(z0 / CELL), cz1 = Math.floor(z1 / CELL);
1980
2076
  if (!((cx1 - cx0 + 1) * (cz1 - cz0 + 1) <= 65536) || !inRange(lv2, cx0, cz0) || !inRange(lv2, cx1, cz1))
1981
2077
  continue;
@@ -2096,12 +2192,6 @@ function cullPass(insts, H, steps, eCap) {
2096
2192
  }
2097
2193
  return best;
2098
2194
  };
2099
- let nStuds = 0;
2100
- for (const it of insts) {
2101
- const pp = prepPart(H, it.part);
2102
- if (pp)
2103
- nStuds += pp.nStuds;
2104
- }
2105
2195
  const studHidden = new Uint8Array(nStuds), studUp = new Uint8Array(nStuds);
2106
2196
  let studsHidden = 0;
2107
2197
  const tops = steps ? new Int3Table(nStuds, 4) : null;
@@ -2110,7 +2200,7 @@ function cullPass(insts, H, steps, eCap) {
2110
2200
  const studHideStep = steps ? new Int32Array(nStuds).fill(STEP_NEVER) : undefined;
2111
2201
  for (let idx = 0, j = 0;idx < insts.length; idx++) {
2112
2202
  const it = insts[idx];
2113
- const pp = prepPart(H, it.part);
2203
+ const pp = pps[idx];
2114
2204
  if (!pp)
2115
2205
  continue;
2116
2206
  const m = it.m, S = pp.studM;
@@ -2235,7 +2325,7 @@ function precomputeCull(instances, H, useTex = true) {
2235
2325
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
2236
2326
  }
2237
2327
 
2238
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/render.ts
2328
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/render.ts
2239
2329
  async function loadPack(url) {
2240
2330
  const res = await fetch(url);
2241
2331
  if (!res.ok)
@@ -2259,14 +2349,14 @@ var toF16 = (a) => {
2259
2349
  const o = new Uint16Array(a.length);
2260
2350
  for (let i = 0;i < a.length; i++) {
2261
2351
  const v = a[i];
2262
- o[i] = THREE.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
2352
+ o[i] = THREE2.DataUtils.toHalfFloat(v > F16_MAX ? F16_MAX : v < -F16_MAX ? -F16_MAX : v);
2263
2353
  }
2264
2354
  return o;
2265
2355
  };
2266
2356
  function keepHalf(bm) {
2267
2357
  const p = bm.geometry.getAttribute("position");
2268
2358
  if (p && !p.isFloat16BufferAttribute && p.array instanceof Uint16Array)
2269
- bm.geometry.setAttribute("position", new THREE.Float16BufferAttribute(p.array, p.itemSize));
2359
+ bm.geometry.setAttribute("position", new THREE2.Float16BufferAttribute(p.array, p.itemSize));
2270
2360
  }
2271
2361
  function flatNormals(pos, idx) {
2272
2362
  const n = new Float32Array(pos.length);
@@ -2300,17 +2390,17 @@ function geom(b, arr) {
2300
2390
  let g = c.get(b);
2301
2391
  if (g)
2302
2392
  return g;
2303
- g = new THREE.BufferGeometry;
2393
+ g = new THREE2.BufferGeometry;
2304
2394
  const pos = arr(b.pos);
2305
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(pos), 3));
2395
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(pos), 3));
2306
2396
  const nrm = b.nrm ? arr(b.nrm) : flatNormals(pos, arr(b.idx));
2307
2397
  const col = arr(b.col);
2308
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(nrm), 3, true));
2309
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col instanceof Uint8Array ? col : toU8(col), 4, true));
2398
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(nrm), 3, true));
2399
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col instanceof Uint8Array ? col : toU8(col), 4, true));
2310
2400
  if (b.idx)
2311
- g.setIndex(new THREE.BufferAttribute(arr(b.idx), 1));
2401
+ g.setIndex(new THREE2.BufferAttribute(arr(b.idx), 1));
2312
2402
  if (b.uv)
2313
- g.setAttribute("ldrUV", new THREE.BufferAttribute(arr(b.uv), 2));
2403
+ g.setAttribute("ldrUV", new THREE2.BufferAttribute(arr(b.uv), 2));
2314
2404
  g.computeBoundingSphere();
2315
2405
  g.computeBoundingBox();
2316
2406
  c.set(b, g);
@@ -2335,7 +2425,7 @@ function patchParticleFragment(shader, surface) {
2335
2425
  const frac = Math.max(0.01, Math.min(0.95, surface.particleFraction ?? 0.3));
2336
2426
  const size = Math.max(0.02, surface.particleSize ?? 1);
2337
2427
  const sparkle = surface.finish === "glitter" ? 1 : 0;
2338
- shader.uniforms.ldrParticle = { value: new THREE.Vector4(pr, pg, pb, frac) };
2428
+ shader.uniforms.ldrParticle = { value: new THREE2.Vector4(pr, pg, pb, frac) };
2339
2429
  shader.uniforms.ldrParticleSize = { value: size };
2340
2430
  shader.uniforms.ldrSparkle = { value: sparkle };
2341
2431
  shader.vertexShader = `varying vec3 ldrGrainP;
@@ -2368,16 +2458,16 @@ function makeFinishMaterial(side, surface) {
2368
2458
  transparent: surface.transparent,
2369
2459
  opacity: surface.opacity,
2370
2460
  depthWrite: surface.depthWrite,
2371
- ...surface.emissive > 0 ? { emissive: new THREE.Color(1, 1, 1), emissiveIntensity: surface.emissive } : {}
2461
+ ...surface.emissive > 0 ? { emissive: new THREE2.Color(1, 1, 1), emissiveIntensity: surface.emissive } : {}
2372
2462
  };
2373
- const m = needPhysical ? new THREE.MeshPhysicalMaterial({
2463
+ const m = needPhysical ? new THREE2.MeshPhysicalMaterial({
2374
2464
  ...common,
2375
2465
  clearcoat: surface.clearcoat,
2376
2466
  clearcoatRoughness: surface.clearcoatRoughness,
2377
2467
  sheen: surface.sheen,
2378
2468
  sheenRoughness: surface.sheenRoughness,
2379
- sheenColor: new THREE.Color(1, 1, 1)
2380
- }) : new THREE.MeshStandardMaterial(common);
2469
+ sheenColor: new THREE2.Color(1, 1, 1)
2470
+ }) : new THREE2.MeshStandardMaterial(common);
2381
2471
  const particle = !!surface.particleHex;
2382
2472
  m.onBeforeCompile = (s) => {
2383
2473
  patchLdrColorVertex(s);
@@ -2444,21 +2534,29 @@ function pngHasAlpha(b) {
2444
2534
  return false;
2445
2535
  }
2446
2536
  function packTexture(pack, i, data = false) {
2447
- const t = new THREE.Texture;
2537
+ const t = new THREE2.Texture;
2448
2538
  t.flipY = false;
2449
- t.colorSpace = data ? THREE.NoColorSpace : THREE.SRGBColorSpace;
2450
- t.wrapS = t.wrapT = THREE.ClampToEdgeWrapping;
2539
+ t.colorSpace = data ? THREE2.NoColorSpace : THREE2.SRGBColorSpace;
2540
+ t.wrapS = t.wrapT = THREE2.ClampToEdgeWrapping;
2451
2541
  const e = pack.header.textures?.[i];
2452
2542
  const bytes = e?.data ? pack.arr(e.data) : null;
2453
2543
  if (!bytes || typeof createImageBitmap === "undefined")
2454
2544
  return { texture: t, ready: Promise.resolve() };
2545
+ const done = decoded.get(e);
2546
+ if (done) {
2547
+ t.image = done;
2548
+ t.needsUpdate = true;
2549
+ return { texture: t, ready: Promise.resolve() };
2550
+ }
2455
2551
  const ready = createImageBitmap(new Blob([bytes], { type: e.mime || "image/png" }), { premultiplyAlpha: "none", colorSpaceConversion: "none" }).then((img) => {
2552
+ decoded.set(e, img);
2456
2553
  t.image = img;
2457
2554
  t.needsUpdate = true;
2458
2555
  }).catch(() => {});
2459
2556
  return { texture: t, ready };
2460
2557
  }
2461
- var sharedLineMat = () => new THREE.ShaderMaterial({
2558
+ var decoded = new WeakMap;
2559
+ var sharedLineMat = () => new THREE2.ShaderMaterial({
2462
2560
  vertexShader: `attribute mat4 instanceMatrix; void main(){ gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position,1.0); }`,
2463
2561
  fragmentShader: `void main(){ gl_FragColor = vec4(0.13,0.13,0.13,1.0); }`
2464
2562
  });
@@ -2532,8 +2630,8 @@ function conditionalLines(pack, entry, which = "all") {
2532
2630
  }
2533
2631
  return out;
2534
2632
  }
2535
- var condLineMat = () => new THREE.ShaderMaterial({
2536
- uniforms: { ldrViewProj: { value: new THREE.Matrix4 } },
2633
+ var condLineMat = () => new THREE2.ShaderMaterial({
2634
+ uniforms: { ldrViewProj: { value: new THREE2.Matrix4 } },
2537
2635
  vertexShader: `uniform mat4 ldrViewProj; attribute mat4 instanceMatrix; attribute vec3 ldrP1; attribute vec3 ldrC0; attribute vec3 ldrC1; attribute float ldrSide;
2538
2636
  void main(){
2539
2637
  mat4 mvp = ldrViewProj * instanceMatrix;
@@ -2571,18 +2669,18 @@ function condBuffers(cond) {
2571
2669
  }
2572
2670
  side[l * 2 + 1] = 1;
2573
2671
  }
2574
- return { ib: new THREE.InterleavedBuffer(buf, 12), side: new THREE.BufferAttribute(side, 1) };
2672
+ return { ib: new THREE2.InterleavedBuffer(buf, 12), side: new THREE2.BufferAttribute(side, 1) };
2575
2673
  }
2576
2674
  function condEdges({ ib, side }, im, material) {
2577
- const g = new THREE.InstancedBufferGeometry;
2578
- g.setAttribute("position", new THREE.InterleavedBufferAttribute(ib, 3, 0));
2579
- g.setAttribute("ldrP1", new THREE.InterleavedBufferAttribute(ib, 3, 3));
2580
- g.setAttribute("ldrC0", new THREE.InterleavedBufferAttribute(ib, 3, 6));
2581
- g.setAttribute("ldrC1", new THREE.InterleavedBufferAttribute(ib, 3, 9));
2675
+ const g = new THREE2.InstancedBufferGeometry;
2676
+ g.setAttribute("position", new THREE2.InterleavedBufferAttribute(ib, 3, 0));
2677
+ g.setAttribute("ldrP1", new THREE2.InterleavedBufferAttribute(ib, 3, 3));
2678
+ g.setAttribute("ldrC0", new THREE2.InterleavedBufferAttribute(ib, 3, 6));
2679
+ g.setAttribute("ldrC1", new THREE2.InterleavedBufferAttribute(ib, 3, 9));
2582
2680
  g.setAttribute("ldrSide", side);
2583
2681
  g.setAttribute("instanceMatrix", im.instanceMatrix);
2584
2682
  g.instanceCount = im.count;
2585
- const l = new THREE.LineSegments(g, material);
2683
+ const l = new THREE2.LineSegments(g, material);
2586
2684
  l.frustumCulled = false;
2587
2685
  l.name = "ldrCondLines";
2588
2686
  l.onBeforeRender = (_r, _s, cam, _g, mat) => {
@@ -2597,12 +2695,12 @@ function condEdges({ ib, side }, im, material) {
2597
2695
  }
2598
2696
  function sharedLines(pos, im, material = sharedLineMat()) {
2599
2697
  const { P, I } = weldLines(pos);
2600
- const g = new THREE.InstancedBufferGeometry;
2601
- g.setAttribute("position", new THREE.BufferAttribute(P, 3));
2602
- g.setIndex(new THREE.BufferAttribute(I, 1));
2698
+ const g = new THREE2.InstancedBufferGeometry;
2699
+ g.setAttribute("position", new THREE2.BufferAttribute(P, 3));
2700
+ g.setIndex(new THREE2.BufferAttribute(I, 1));
2603
2701
  g.setAttribute("instanceMatrix", im.instanceMatrix);
2604
2702
  g.instanceCount = im.count;
2605
- const l = new THREE.LineSegments(g, material);
2703
+ const l = new THREE2.LineSegments(g, material);
2606
2704
  l.frustumCulled = false;
2607
2705
  return l;
2608
2706
  }
@@ -2625,8 +2723,8 @@ function writeM4(t, o, m, mo = 0) {
2625
2723
  t[o + 15] = 1;
2626
2724
  }
2627
2725
  function newIM(g, mat, n) {
2628
- const im = new THREE.InstancedMesh(g, mat, 0);
2629
- im.instanceMatrix = new THREE.InstancedBufferAttribute(new Float32Array(n * 16), 16);
2726
+ const im = new THREE2.InstancedMesh(g, mat, 0);
2727
+ im.instanceMatrix = new THREE2.InstancedBufferAttribute(new Float32Array(n * 16), 16);
2630
2728
  im.count = n;
2631
2729
  return im;
2632
2730
  }
@@ -2689,7 +2787,7 @@ function sphereUnion(S, A, n) {
2689
2787
  S[3] = r;
2690
2788
  }
2691
2789
  function setSphere(im, S) {
2692
- const sph = im.boundingSphere ?? new THREE.Sphere;
2790
+ const sph = im.boundingSphere ?? new THREE2.Sphere;
2693
2791
  sph.center.set(S[0], S[1], S[2]);
2694
2792
  sph.radius = S[3];
2695
2793
  if (S[3] < 0)
@@ -2759,7 +2857,7 @@ function fillInstances(im, ids, insts, color) {
2759
2857
  writeM4(M, k * 16, it.m);
2760
2858
  color(it.color).toArray(C, k * 3);
2761
2859
  }
2762
- im.instanceColor = new THREE.InstancedBufferAttribute(C, 3);
2860
+ im.instanceColor = new THREE2.InstancedBufferAttribute(C, 3);
2763
2861
  }
2764
2862
  function computeCulling(insts, H) {
2765
2863
  const c = cullCore(insts, H);
@@ -2891,10 +2989,10 @@ function studDiscGeom() {
2891
2989
  col[i * 4 + 2] = 255;
2892
2990
  col[i * 4 + 3] = 0;
2893
2991
  }
2894
- const g = new THREE.BufferGeometry;
2895
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(pos), 3));
2896
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(nrm), 3, true));
2897
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
2992
+ const g = new THREE2.BufferGeometry;
2993
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(pos), 3));
2994
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(nrm), 3, true));
2995
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
2898
2996
  g.computeBoundingSphere();
2899
2997
  g.computeBoundingBox();
2900
2998
  return _studDisc = g;
@@ -2941,11 +3039,11 @@ function studBoxGeom(w) {
2941
3039
  col[i * 4 + 2] = 255;
2942
3040
  col[i * 4 + 3] = 0;
2943
3041
  }
2944
- g = new THREE.BufferGeometry;
2945
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
2946
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
2947
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
2948
- g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
3042
+ g = new THREE2.BufferGeometry;
3043
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3044
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3045
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
3046
+ g.setIndex(new THREE2.BufferAttribute(new Uint16Array(idx), 1));
2949
3047
  g.computeBoundingSphere();
2950
3048
  g.computeBoundingBox();
2951
3049
  _studBox.set(w, g);
@@ -3012,11 +3110,11 @@ function studTubeGeom(w, wi) {
3012
3110
  col[i * 4 + 2] = 255;
3013
3111
  col[i * 4 + 3] = 0;
3014
3112
  }
3015
- g = new THREE.BufferGeometry;
3016
- g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3017
- g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3018
- g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
3019
- g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
3113
+ g = new THREE2.BufferGeometry;
3114
+ g.setAttribute("position", new THREE2.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
3115
+ g.setAttribute("normal", new THREE2.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
3116
+ g.setAttribute("ldrColor", new THREE2.BufferAttribute(col, 4, true));
3117
+ g.setIndex(new THREE2.BufferAttribute(new Uint16Array(idx), 1));
3020
3118
  g.computeBoundingSphere();
3021
3119
  g.computeBoundingBox();
3022
3120
  _studTube.set(key, g);
@@ -3162,7 +3260,7 @@ function studTopClosed(b, arr) {
3162
3260
  }
3163
3261
  var EDGE_CAP_MIN = 4;
3164
3262
 
3165
- class LdrLodRoot extends THREE.LOD {
3263
+ class LdrLodRoot extends THREE2.LOD {
3166
3264
  clusters = [];
3167
3265
  vpH = 1080;
3168
3266
  px = 0.5;
@@ -3171,8 +3269,8 @@ class LdrLodRoot extends THREE.LOD {
3171
3269
  edgeCap = 0;
3172
3270
  enabled = true;
3173
3271
  apply = () => {};
3174
- inv = new THREE.Matrix4;
3175
- cp = new THREE.Vector3;
3272
+ inv = new THREE2.Matrix4;
3273
+ cp = new THREE2.Vector3;
3176
3274
  lastW = new Float32Array(16).fill(NaN);
3177
3275
  constructor() {
3178
3276
  super();
@@ -3304,7 +3402,51 @@ function fillBucketIds(bIds, fill, studBucket, j0, j1) {
3304
3402
  bIds[b][fill[b]++] = j;
3305
3403
  }
3306
3404
  }
3307
- function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colorIndex, trim = false) {
3405
+ var _studGrid = new WeakMap;
3406
+ function studGridGeom(g, n) {
3407
+ if (n <= 1)
3408
+ return g;
3409
+ let m = _studGrid.get(g);
3410
+ if (!m)
3411
+ _studGrid.set(g, m = new Map);
3412
+ const hit = m.get(n);
3413
+ if (hit)
3414
+ return hit;
3415
+ const src = g;
3416
+ const P = src.getAttribute("position"), nv = P.count, k = n * n, pos = new Float32Array(nv * 3 * k), out = new THREE2.BufferGeometry;
3417
+ for (let a = 0, c = 0;a < n; a++)
3418
+ for (let b = 0;b < n; b++, c++) {
3419
+ const ox = ((a + 0.5) / n - 0.5) * 20, oz = ((b + 0.5) / n - 0.5) * 20, o = c * nv * 3;
3420
+ for (let v = 0;v < nv; v++) {
3421
+ pos[o + v * 3] = P.getX(v) / n + ox;
3422
+ pos[o + v * 3 + 1] = P.getY(v) / n;
3423
+ pos[o + v * 3 + 2] = P.getZ(v) / n + oz;
3424
+ }
3425
+ }
3426
+ out.setAttribute("position", g.getAttribute("position") instanceof THREE2.Float16BufferAttribute ? new THREE2.Float16BufferAttribute(toF16(pos), 3) : new THREE2.BufferAttribute(pos, 3));
3427
+ for (const name of Object.keys(src.attributes)) {
3428
+ if (name === "position")
3429
+ continue;
3430
+ const A = src.getAttribute(name);
3431
+ const sa = A.array, dst = new sa.constructor(sa.length * k);
3432
+ for (let c = 0;c < k; c++)
3433
+ dst.set(sa, c * sa.length);
3434
+ out.setAttribute(name, new A.constructor(dst, A.itemSize, A.normalized));
3435
+ }
3436
+ const I = src.getIndex();
3437
+ if (I) {
3438
+ const ia = I.array, ni = ia.length, big = nv * k > 65535, dst = big ? new Uint32Array(ni * k) : new Uint16Array(ni * k);
3439
+ for (let c = 0;c < k; c++)
3440
+ for (let i = 0;i < ni; i++)
3441
+ dst[c * ni + i] = ia[i] + c * nv;
3442
+ out.setIndex(new THREE2.BufferAttribute(dst, 1));
3443
+ }
3444
+ out.computeBoundingSphere();
3445
+ out.computeBoundingBox();
3446
+ m.set(n, out);
3447
+ return out;
3448
+ }
3449
+ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colorIndex, trim = false, grid = 1) {
3308
3450
  const bKind = [], bMat = [];
3309
3451
  const bAll = [];
3310
3452
  const studBucket = new Uint16Array(cull.nStuds);
@@ -3422,7 +3564,7 @@ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colo
3422
3564
  }
3423
3565
  const n = trim ? v : c.length;
3424
3566
  const im = newIM(g, bMat[b], n);
3425
- im.instanceColor = new THREE.InstancedBufferAttribute(new Float32Array(n * 3), 3);
3567
+ im.instanceColor = new THREE2.InstancedBufferAttribute(new Float32Array(n * 3), 3);
3426
3568
  sMesh.push({ im, kind, vis: v, all: c.length, ...steps ? { slots: { own: new Int32Array(n), hide: new Int32Array(n), inst: new Int32Array(n), stud: new Int16Array(n), col: new Uint16Array(n) } } : {} });
3427
3569
  }
3428
3570
  };
@@ -3430,10 +3572,10 @@ function* buildStudMeshesGen(insts, H, cull, arr, LOD, color, matOf, steps, colo
3430
3572
  if (b)
3431
3573
  yield;
3432
3574
  const kind = bKind[b];
3433
- const g = geom(H.studKinds[kind].body, arr);
3575
+ const g0 = geom(H.studKinds[kind].body, arr), g = g0 && studGridGeom(g0, grid);
3434
3576
  const ids = bIds[b];
3435
3577
  const studTris = g ? (g.getIndex() ? g.getIndex().count : g.getAttribute("position").count) / 3 : 24;
3436
- const kStud = LOD ? Math.max(256, Math.min(4096, Math.round(65536 / Math.max(1, studTris)))) : Infinity;
3578
+ const kStud = LOD ? Math.max(256, Math.min(4096, Math.round(65536 * grid / Math.max(1, studTris)))) : Infinity;
3437
3579
  const clusters = yield* gridClustersGen(ids.length, (i) => sx[ids[i]], (i) => sz[ids[i]], kStud);
3438
3580
  for (let c0 = 0;c0 < clusters.length; c0 += 4) {
3439
3581
  if (c0)
@@ -3581,6 +3723,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3581
3723
  const { header: H, arr } = pack;
3582
3724
  const LOD = P.lod !== false;
3583
3725
  const EDGES = !!P.edges;
3726
+ const G = Math.max(1, Math.round(P.studGrid ?? 1));
3584
3727
  const root = new LdrLodRoot;
3585
3728
  root.enabled = LOD;
3586
3729
  root.px = P.lodPx ?? 0.5;
@@ -3601,8 +3744,8 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3601
3744
  base.apply(this, a);
3602
3745
  };
3603
3746
  };
3604
- const matF = makeMaterial(P.side === "front" ? THREE.FrontSide : THREE.DoubleSide), matB = makeMaterial(P.side === "front" ? THREE.BackSide : THREE.DoubleSide);
3605
- const matD = makeMaterial(THREE.DoubleSide);
3747
+ const matF = makeMaterial(P.side === "front" ? THREE2.FrontSide : THREE2.DoubleSide), matB = makeMaterial(P.side === "front" ? THREE2.BackSide : THREE2.DoubleSide);
3748
+ const matD = makeMaterial(THREE2.DoubleSide);
3606
3749
  let nUncert = 0;
3607
3750
  matF.userData.ldrSideRole = "F";
3608
3751
  matB.userData.ldrSideRole = "B";
@@ -3635,7 +3778,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3635
3778
  const key = fk + "|" + role;
3636
3779
  let m = matCache.get(key);
3637
3780
  if (!m) {
3638
- const side = uncert ? THREE.DoubleSide : P.side === "front" ? mirror ? THREE.BackSide : THREE.FrontSide : THREE.DoubleSide;
3781
+ const side = uncert ? THREE2.DoubleSide : P.side === "front" ? mirror ? THREE2.BackSide : THREE2.FrontSide : THREE2.DoubleSide;
3639
3782
  if (fk === "default:op" && lc.luminance === 0) {
3640
3783
  m = role === "D" ? matD : role === "B" ? matB : matF;
3641
3784
  } else {
@@ -3749,7 +3892,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3749
3892
  let w = lineCache.get(ref);
3750
3893
  if (!w) {
3751
3894
  const r = weldLines(src ? src.pos : arr(ref), LOD && !src?.lens);
3752
- lineCache.set(ref, w = { P: new THREE.BufferAttribute(r.P, 3), I: new THREE.BufferAttribute(r.I, 1), lens: src?.lens ?? r.lens, order: r.order });
3895
+ lineCache.set(ref, w = { P: new THREE2.BufferAttribute(r.P, 3), I: new THREE2.BufferAttribute(r.I, 1), lens: src?.lens ?? r.lens, order: r.order });
3753
3896
  }
3754
3897
  return lineObj(w, im, cl);
3755
3898
  };
@@ -3769,17 +3912,17 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3769
3912
  I[n * 2 + 1] = FI[k * 2 + 1];
3770
3913
  lens[n++] = full.lens[k];
3771
3914
  }
3772
- lineCache.set(ref, w = { P: full.P, I: new THREE.BufferAttribute(I.subarray(0, n * 2), 1), lens: lens.subarray(0, n) });
3915
+ lineCache.set(ref, w = { P: full.P, I: new THREE2.BufferAttribute(I.subarray(0, n * 2), 1), lens: lens.subarray(0, n) });
3773
3916
  }
3774
3917
  return lineObj(w, im, cl);
3775
3918
  };
3776
3919
  const lineObj = (w, im, cl) => {
3777
- const g = new THREE.InstancedBufferGeometry;
3920
+ const g = new THREE2.InstancedBufferGeometry;
3778
3921
  g.setAttribute("position", w.P);
3779
3922
  g.setIndex(w.I);
3780
3923
  g.setAttribute("instanceMatrix", im.instanceMatrix);
3781
3924
  g.instanceCount = im.count;
3782
- const l = new THREE.LineSegments(g, lmat());
3925
+ const l = new THREE2.LineSegments(g, lmat());
3783
3926
  l.frustumCulled = false;
3784
3927
  if (LOD)
3785
3928
  l.userData.ldrLens = w.lens;
@@ -3830,7 +3973,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3830
3973
  return gm ?? undefined;
3831
3974
  };
3832
3975
  const texMat = (t, base, wrapU, g) => {
3833
- const role = base.userData?.ldrSideRole ?? (base.side === THREE.BackSide ? "B" : base.side === THREE.DoubleSide ? "D" : "F");
3976
+ const role = base.userData?.ldrSideRole ?? (base.side === THREE2.BackSide ? "B" : base.side === THREE2.DoubleSide ? "D" : "F");
3834
3977
  const fin = base.userData?.ldrFinish ?? "default";
3835
3978
  const gloss = glossOf(g);
3836
3979
  const k = t + ":" + role + ":" + fin + ":" + (wrapU ? 1 : 0) + (gloss ? ":g" + g : "");
@@ -3856,7 +3999,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
3856
3999
  return c;
3857
4000
  };
3858
4001
  const lodLevels = (b, base, mat) => !LOD || !b?.lod ? [] : b.lod.map((l) => {
3859
- const im = new THREE.InstancedMesh(geom(l, arr), mat, 0);
4002
+ const im = new THREE2.InstancedMesh(geom(l, arr), mat, 0);
3860
4003
  im.userData = { ...base.userData };
3861
4004
  im.instanceMatrix = base.instanceMatrix;
3862
4005
  im.count = base.count;
@@ -4048,8 +4191,8 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4048
4191
  }
4049
4192
  }
4050
4193
  yield root;
4051
- const tmpM = new THREE.Matrix4;
4052
- const tmpC = new THREE.Color;
4194
+ const tmpM = new THREE2.Matrix4;
4195
+ const tmpC = new THREE2.Color;
4053
4196
  for (const [mat, items] of coldByMat) {
4054
4197
  yield root;
4055
4198
  const entries = [];
@@ -4089,7 +4232,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4089
4232
  yield root;
4090
4233
  }
4091
4234
  }
4092
- const bm = new THREE.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
4235
+ const bm = new THREE2.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
4093
4236
  bm.perObjectFrustumCulled = true;
4094
4237
  bm.sortObjects = false;
4095
4238
  bm.frustumCulled = true;
@@ -4133,7 +4276,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4133
4276
  members.length = 0;
4134
4277
  members.push(...live);
4135
4278
  bm.computeBoundingSphere();
4136
- const cl = newCluster(bm.boundingSphere ?? new THREE.Sphere, bm);
4279
+ const cl = newCluster(bm.boundingSphere ?? new THREE2.Sphere, bm);
4137
4280
  const bodyErrs = live.map(({ p }) => [0, ...(p.body?.lod ?? []).map((l) => l.err)]);
4138
4281
  bm.userData.ldrMergeGids = instGids;
4139
4282
  cl.mergedLod = { bm, gids: instGids, errs: bodyErrs };
@@ -4154,7 +4297,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4154
4297
  continue;
4155
4298
  if (!pp.edges && !(wantCond && (pp.condl || pp.condlu)))
4156
4299
  continue;
4157
- const ghost = newIM(geom(pp.body, arr) || new THREE.BufferGeometry, mat, ids.length);
4300
+ const ghost = newIM(geom(pp.body, arr) || new THREE2.BufferGeometry, mat, ids.length);
4158
4301
  fillInstances(ghost, ids, insts, color);
4159
4302
  const nL = cl.lines.length, nC = cl.cond.length;
4160
4303
  if (pp.edges)
@@ -4204,7 +4347,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4204
4347
  yield root;
4205
4348
  }
4206
4349
  }
4207
- const ubm = new THREE.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
4350
+ const ubm = new THREE2.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
4208
4351
  ubm.perObjectFrustumCulled = true;
4209
4352
  ubm.sortObjects = false;
4210
4353
  ubm.frustumCulled = true;
@@ -4254,7 +4397,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4254
4397
  umembers.length = 0;
4255
4398
  umembers.push(...uLive);
4256
4399
  ubm.computeBoundingSphere();
4257
- const ucl = newCluster(ubm.boundingSphere ?? new THREE.Sphere, ubm);
4400
+ const ucl = newCluster(ubm.boundingSphere ?? new THREE2.Sphere, ubm);
4258
4401
  const uErrs = uLive.map(({ p }) => [0, ...(p.under?.lod ?? []).map((l) => l.err)]);
4259
4402
  ubm.userData._stepMode = !!steps;
4260
4403
  ubm.userData.ldrMergeGids = uInstGids;
@@ -4276,7 +4419,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4276
4419
  continue;
4277
4420
  const ord = [...ids.filter((id) => !cull.underHidden[id]), ...ids.filter((id) => cull.underHidden[id])];
4278
4421
  const vis = ids.length - ids.reduce((a, id) => a + cull.underHidden[id], 0);
4279
- const ghost = newIM(geom(pp.under, arr) || new THREE.BufferGeometry, mat, ord.length);
4422
+ const ghost = newIM(geom(pp.under, arr) || new THREE2.BufferGeometry, mat, ord.length);
4280
4423
  fillInstances(ghost, ord, insts, color);
4281
4424
  const nC = ucl.cond.length;
4282
4425
  addCond(pp, ghost, ucl, "under");
@@ -4328,7 +4471,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4328
4471
  }
4329
4472
  }
4330
4473
  yield root;
4331
- const _studGen = buildStudMeshesGen(insts, H, cull, arr, LOD, color, (c, mirror) => materialFor(c, mirror, false), steps, steps && colorIndex, !steps && !!P.cullStuds);
4474
+ const _studGen = buildStudMeshesGen(insts, H, cull, arr, LOD, color, (c, mirror) => materialFor(c, mirror, false), steps, steps && colorIndex, !steps && !!P.cullStuds, G);
4332
4475
  let _studR = _studGen.next();
4333
4476
  while (!_studR.done) {
4334
4477
  yield root;
@@ -4337,10 +4480,10 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4337
4480
  const sMesh = _studR.value;
4338
4481
  const sKind = sMesh.map((x) => x?.kind ?? "");
4339
4482
  const sVis = sMesh.map((x) => x?.vis ?? 0);
4340
- const STUD_ERR = 12;
4341
- const STUD_BOX_ERR = 2.49;
4483
+ const STUD_ERR = 12 / G;
4484
+ const STUD_BOX_ERR = 2.49 / G;
4342
4485
  const STUD_BOX_W_LOW = 5.317;
4343
- const STUD_DISC_ERR = 8;
4486
+ const STUD_DISC_ERR = 8 / G;
4344
4487
  let _coopS = 0;
4345
4488
  const sqLineKey = new Map;
4346
4489
  for (let ci = 0;ci < sMesh.length; ci++) {
@@ -4371,7 +4514,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4371
4514
  const h = studTopClosed(k.body, arr) ? null : studHole(k.body, arr);
4372
4515
  const hole = h ? { r: h.r, w: h.r * Math.sqrt(Math.PI) / 2 } : undefined;
4373
4516
  if (LOD && (hole || studTopClosed(k.body, arr)) && (im.geometry.getIndex()?.count ?? im.geometry.getAttribute("position").count) > 30) {
4374
- const box = new THREE.InstancedMesh(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), im.material, 0);
4517
+ const box = new THREE2.InstancedMesh(studGridGeom(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), G), im.material, 0);
4375
4518
  box.userData = { ldrStud: true, ldrLod: true };
4376
4519
  box.instanceMatrix = im.instanceMatrix;
4377
4520
  box.count = im.count;
@@ -4381,11 +4524,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4381
4524
  box.onBeforeRender = trackVp;
4382
4525
  root.add(box);
4383
4526
  discObjs.push(box);
4384
- cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, 6 * Math.SQRT2 - h.out) : STUD_BOX_ERR });
4527
+ cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, (6 * Math.SQRT2 - h.out) / G) : STUD_BOX_ERR });
4385
4528
  cl.studLineLv = 1;
4386
4529
  }
4387
4530
  if (LOD) {
4388
- const disc = new THREE.InstancedMesh(studDiscGeom(), im.material, 0);
4531
+ const disc = new THREE2.InstancedMesh(studGridGeom(studDiscGeom(), G), im.material, 0);
4389
4532
  disc.userData = { ldrStud: true, ldrLod: true };
4390
4533
  disc.instanceMatrix = im.instanceMatrix;
4391
4534
  disc.count = im.count;
@@ -4398,7 +4541,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4398
4541
  cl.lv.push({ objs: [disc], err: STUD_DISC_ERR });
4399
4542
  cl.lv.push({ objs: [], err: STUD_ERR });
4400
4543
  }
4401
- if (EDGES && k.edges) {
4544
+ if (EDGES && k.edges && G === 1) {
4402
4545
  const round = addLines(k.edges, im, cl);
4403
4546
  let sq = cl.studLineLv === 1 && round ? sqLineKey.get(kind) : null;
4404
4547
  if (sq === undefined) {
@@ -4424,6 +4567,18 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4424
4567
  toggles.push({ mesh: countTo(() => objs), all: trim ? vis : all, visible: vis, flag: "studs" });
4425
4568
  if (sm.slots)
4426
4569
  stepBatches.push({ im, objs, flag: "studs", ...sm.slots });
4570
+ if (sm.slots && P.studDecal && im.material.opacity === 1 && !im.material.transparent) {
4571
+ const n = im.instanceMatrix.count, decal = new THREE2.InstancedMesh(studDecalGeom(G), studDecalMaterial(im.material, P.studDecal, G), n);
4572
+ decal.instanceMatrix = new THREE2.InstancedBufferAttribute(im.instanceMatrix.array.slice(), 16);
4573
+ decal.instanceColor = new THREE2.InstancedBufferAttribute(im.instanceColor.array.slice(), 3);
4574
+ decal.count = im.count;
4575
+ decal.boundingSphere = im.boundingSphere;
4576
+ decal.visible = false;
4577
+ decal.userData = { ldrStudDecal: true };
4578
+ root.add(decal);
4579
+ stepBatches[stepBatches.length - 1].decal = decal;
4580
+ stats.studDecals = (stats.studDecals ?? 0) + 1;
4581
+ }
4427
4582
  }
4428
4583
  yield root;
4429
4584
  stats.uncertParts = Object.values(H.parts).filter((x) => x.uncert).length;
@@ -4465,12 +4620,17 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4465
4620
  const texturesReady = Promise.all(pending).then(() => {});
4466
4621
  let stepS = STEP_NEVER - 1, cullS = !!P.cullStuds, cullU = !!P.cullUnder;
4467
4622
  let only = null;
4468
- const applySteps = () => {
4623
+ let studMask = null;
4624
+ const applySteps = (studsOnly = false) => {
4469
4625
  const st = { studsTotal: 0, studsHidden: 0, undersTotal: 0, undersHidden: 0 };
4470
- const S = stepS, O = only;
4626
+ const S = stepS, O = only, SM = studMask, SA = SM && !("r" in SM) ? SM : null, SCi = SM && "r" in SM ? SM : null, SR2 = SCi ? Math.sign(SCi.r) * SCi.r * SCi.r : 0;
4471
4627
  const wm = new Float64Array(12);
4472
4628
  for (const b of stepBatches) {
4629
+ if (studsOnly && b.flag !== "studs")
4630
+ continue;
4473
4631
  const MA = b.im.instanceMatrix.array, CA = b.im.instanceColor.array;
4632
+ const D = b.decal, DM = D?.instanceMatrix.array, DC = D?.instanceColor.array, sm = b.flag === "studs" ? SM : null;
4633
+ let w2 = 0;
4474
4634
  const useHide = b.flag === "studs" ? cullS : b.flag === "under" ? cullU : false;
4475
4635
  const { own, hide, inst, stud, col } = b;
4476
4636
  let w = 0;
@@ -4492,14 +4652,31 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4492
4652
  const n = inst[i];
4493
4653
  if (O && !O[n])
4494
4654
  continue;
4495
- if (stud) {
4655
+ if (stud)
4496
4656
  mul12To(instM, instPP[n].studM, stud[i] * 12, wm, n * 12);
4657
+ const real = !sm || (SA ? !!SA[n] : (wm[0] - SCi.x) ** 2 + (wm[2] - SCi.z) ** 2 < SR2);
4658
+ if (!real && !D)
4659
+ continue;
4660
+ if (D) {
4661
+ writeM4(DM, w2 * 16, wm);
4662
+ palette[col[i]].toArray(DC, w2 * 3);
4663
+ w2++;
4664
+ }
4665
+ if (!real)
4666
+ continue;
4667
+ if (stud)
4497
4668
  writeM4(MA, w * 16, wm);
4498
- } else
4669
+ else
4499
4670
  writeM4(MA, w * 16, instM, n * 12);
4500
4671
  palette[col[i]].toArray(CA, w * 3);
4501
4672
  w++;
4502
4673
  }
4674
+ if (D) {
4675
+ D.instanceMatrix.needsUpdate = true;
4676
+ D.instanceColor.needsUpdate = true;
4677
+ D.count = w2;
4678
+ D.visible = !!SM;
4679
+ }
4503
4680
  b.im.instanceMatrix.needsUpdate = true;
4504
4681
  b.im.instanceColor.needsUpdate = true;
4505
4682
  for (const o of b.objs) {
@@ -4509,20 +4686,21 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4509
4686
  o.geometry.instanceCount = w;
4510
4687
  }
4511
4688
  }
4512
- for (const b of stepBatched) {
4513
- const useHide = b.flag === "under" ? cullU : false;
4514
- const { own, hide, inst, bm } = b;
4515
- for (let i = 0;i < own.length; i++) {
4516
- const hid = !!hide && hide[i] <= S;
4517
- if (b.flag === "under") {
4518
- st.undersTotal++;
4519
- if (hid)
4520
- st.undersHidden++;
4689
+ if (!studsOnly)
4690
+ for (const b of stepBatched) {
4691
+ const useHide = b.flag === "under" ? cullU : false;
4692
+ const { own, hide, inst, bm } = b;
4693
+ for (let i = 0;i < own.length; i++) {
4694
+ const hid = !!hide && hide[i] <= S;
4695
+ if (b.flag === "under") {
4696
+ st.undersTotal++;
4697
+ if (hid)
4698
+ st.undersHidden++;
4699
+ }
4700
+ const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
4701
+ bm.setVisibleAt(i, on);
4521
4702
  }
4522
- const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
4523
- bm.setVisibleAt(i, on);
4524
4703
  }
4525
- }
4526
4704
  return st;
4527
4705
  };
4528
4706
  const setCull = (studs, under) => {
@@ -4542,7 +4720,14 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4542
4720
  only = mask;
4543
4721
  return applySteps();
4544
4722
  };
4545
- const box = new THREE.Box3;
4723
+ const setStudMask = (mask) => {
4724
+ if (!steps)
4725
+ return false;
4726
+ studMask = mask;
4727
+ applySteps(true);
4728
+ return true;
4729
+ };
4730
+ const box = new THREE2.Box3;
4546
4731
  for (const it of insts) {
4547
4732
  if (!H.parts[it.part])
4548
4733
  continue;
@@ -4564,11 +4749,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4564
4749
  for (const m of new Set([matF, matB, matD, ...matCache.values(), ...texMats.values()])) {
4565
4750
  const role = m.userData?.ldrSideRole;
4566
4751
  if (role === "D") {
4567
- m.side = THREE.DoubleSide;
4752
+ m.side = THREE2.DoubleSide;
4568
4753
  } else if (role === "B") {
4569
- m.side = front ? THREE.BackSide : THREE.DoubleSide;
4754
+ m.side = front ? THREE2.BackSide : THREE2.DoubleSide;
4570
4755
  } else {
4571
- m.side = front ? THREE.FrontSide : THREE.DoubleSide;
4756
+ m.side = front ? THREE2.FrontSide : THREE2.DoubleSide;
4572
4757
  }
4573
4758
  m.needsUpdate = true;
4574
4759
  }
@@ -4600,7 +4785,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
4600
4785
  o.matrixAutoUpdate = false;
4601
4786
  o.matrixWorldNeedsUpdate = true;
4602
4787
  }
4603
- return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, box, texturesReady, trimmed };
4788
+ return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, setStudMask, box, texturesReady, trimmed };
4604
4789
  }
4605
4790
  function buildLdrScene(insts, pack, P, color, mark) {
4606
4791
  const g = buildLdrSceneGen(insts, pack, P, color, mark);
@@ -4678,18 +4863,18 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
4678
4863
  await new Promise((r) => setTimeout(r, 0));
4679
4864
  }
4680
4865
  }
4681
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/scene.ts
4682
- import * as THREE2 from "three";
4683
- var _box = new THREE2.Box3;
4684
- var _m4 = new THREE2.Matrix4;
4866
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/scene.ts
4867
+ import * as THREE3 from "three";
4868
+ var _box = new THREE3.Box3;
4869
+ var _m4 = new THREE3.Matrix4;
4685
4870
  function ghostMaterial(side, g) {
4686
- const m = new THREE2.MeshStandardMaterial({ color: 16777215, roughness: 0.85, metalness: 0, side, transparent: false, depthWrite: true, opacity: g.opacity });
4687
- m.blending = THREE2.CustomBlending;
4688
- m.blendSrc = THREE2.SrcAlphaFactor;
4689
- m.blendDst = THREE2.OneMinusSrcAlphaFactor;
4690
- m.blendSrcAlpha = THREE2.OneFactor;
4691
- m.blendDstAlpha = THREE2.OneMinusSrcAlphaFactor;
4692
- const tint = new THREE2.Color(g.color);
4871
+ const m = new THREE3.MeshStandardMaterial({ color: 16777215, roughness: 0.85, metalness: 0, side, transparent: false, depthWrite: true, opacity: g.opacity, polygonOffset: true, polygonOffsetFactor: 1, polygonOffsetUnits: 1 });
4872
+ m.blending = THREE3.CustomBlending;
4873
+ m.blendSrc = THREE3.SrcAlphaFactor;
4874
+ m.blendDst = THREE3.OneMinusSrcAlphaFactor;
4875
+ m.blendSrcAlpha = THREE3.OneFactor;
4876
+ m.blendDstAlpha = THREE3.OneMinusSrcAlphaFactor;
4877
+ const tint = new THREE3.Color(g.color);
4693
4878
  const u = { ldrGhostTint: { value: tint }, ldrGhostMix: { value: g.whiten } };
4694
4879
  m.onBeforeCompile = (sh) => {
4695
4880
  Object.assign(sh.uniforms, u);
@@ -4703,13 +4888,13 @@ function ghostMaterial(side, g) {
4703
4888
  }
4704
4889
  function colorFn(src, pack, fallback) {
4705
4890
  const table = new Map;
4706
- const put = (k, v) => table.set(String(k), new THREE2.Color(typeof v === "string" ? v : v.hex));
4891
+ const put = (k, v) => table.set(String(k), new THREE3.Color(typeof v === "string" ? v : v.hex));
4707
4892
  if (typeof src === "function") {
4708
4893
  return (c) => {
4709
4894
  let col = table.get(c);
4710
4895
  if (!col) {
4711
4896
  const v = src(+c);
4712
- col = v === undefined ? direct(c) ?? fallback : new THREE2.Color(v);
4897
+ col = v === undefined ? direct(c) ?? fallback : new THREE3.Color(v);
4713
4898
  table.set(c, col);
4714
4899
  }
4715
4900
  return col;
@@ -4727,14 +4912,14 @@ function colorFn(src, pack, fallback) {
4727
4912
  var direct = (c) => {
4728
4913
  const n = +c;
4729
4914
  if (n > 16777215 && n >>> 24 === 2)
4730
- return new THREE2.Color(n & 16777215);
4915
+ return new THREE3.Color(n & 16777215);
4731
4916
  const b = blendedColourHex(n);
4732
- return b ? new THREE2.Color(b) : null;
4917
+ return b ? new THREE3.Color(b) : null;
4733
4918
  };
4734
4919
  function withLocalColours(base, local) {
4735
4920
  if (!local.size)
4736
4921
  return base;
4737
- const own = new Map([...local].map(([k, v]) => [k, new THREE2.Color(v.hex)]));
4922
+ const own = new Map([...local].map(([k, v]) => [k, new THREE3.Color(v.hex)]));
4738
4923
  return (c) => own.get(c) ?? base(c);
4739
4924
  }
4740
4925
  var plasticCache = new WeakMap;
@@ -4746,7 +4931,7 @@ function toPlastic(old) {
4746
4931
  return old;
4747
4932
  let m = plasticCache.get(old);
4748
4933
  if (!m) {
4749
- const p = new THREE2.MeshPhysicalMaterial({
4934
+ const p = new THREE3.MeshPhysicalMaterial({
4750
4935
  vertexColors: true,
4751
4936
  roughness: 0.3,
4752
4937
  clearcoat: 0.3,
@@ -4757,8 +4942,11 @@ function toPlastic(old) {
4757
4942
  opacity: old.opacity,
4758
4943
  depthWrite: old.depthWrite,
4759
4944
  metalness: old.metalness,
4760
- emissive: old.emissive?.clone?.() ?? new THREE2.Color(0),
4761
- emissiveIntensity: old.emissiveIntensity ?? 0
4945
+ emissive: old.emissive?.clone?.() ?? new THREE3.Color(0),
4946
+ emissiveIntensity: old.emissiveIntensity ?? 0,
4947
+ polygonOffset: old.polygonOffset,
4948
+ polygonOffsetFactor: old.polygonOffsetFactor,
4949
+ polygonOffsetUnits: old.polygonOffsetUnits
4762
4950
  });
4763
4951
  p.onBeforeCompile = old.onBeforeCompile;
4764
4952
  p.customProgramCacheKey = () => "Phys" + old.customProgramCacheKey() + old.side;
@@ -4778,14 +4966,24 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4778
4966
  const useTex = o.textures !== false;
4779
4967
  const { all, stepOf, nSteps, localColours } = sceneInstances(instances, pack.header, useTex);
4780
4968
  const uniq = { length: nSteps };
4781
- const color = withLocalColours(colorFn(o.colors, pack, new THREE2.Color(o.fallbackColor ?? 10528169)), localColours);
4969
+ const color = withLocalColours(colorFn(o.colors, pack, new THREE3.Color(o.fallbackColor ?? 10528169)), localColours);
4782
4970
  const stepViews = new Array(uniq.length).fill(null);
4783
4971
  instances.forEach((i, k) => {
4784
4972
  if (i.view)
4785
4973
  stepViews[stepOf[k]] = i.view;
4786
4974
  });
4787
- const missing = [...new Set(all.filter((i) => !pack.header.parts[i.part]).map((i) => i.part))];
4788
- const object = new THREE2.Group;
4975
+ const parts = pack.header.parts;
4976
+ const miss = new Set;
4977
+ let drawnAll = 0;
4978
+ for (let k = 0;k < all.length; k++) {
4979
+ const p = all[k].part;
4980
+ if (parts[p])
4981
+ drawnAll++;
4982
+ else
4983
+ miss.add(p);
4984
+ }
4985
+ const missing = [...miss];
4986
+ const object = new THREE3.Group;
4789
4987
  object.name = "ldr";
4790
4988
  if (!o.ldrawSpace)
4791
4989
  object.rotation.x = Math.PI;
@@ -4804,7 +5002,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4804
5002
  x.geometry?.dispose?.();
4805
5003
  if (x.material)
4806
5004
  mats.add(x.material);
4807
- if (x.dispose && x.isInstancedMesh)
5005
+ if (x.dispose && (x.isInstancedMesh || x.isBatchedMesh))
4808
5006
  x.dispose();
4809
5007
  });
4810
5008
  for (const m of [...mats, ...pairs.values()]) {
@@ -4815,16 +5013,17 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4815
5013
  cur = null;
4816
5014
  };
4817
5015
  let ghostOn = false, ghost = null, ghostBuild = null, ghostGen = 0;
4818
- let shownStep = null, shownMask = null;
5016
+ let studMaskShown = null;
5017
+ let shownStep = null, shownMask = null, shownGhost = null;
4819
5018
  const ghostOpts = { opacity: 0.2, color: 16777215, whiten: 0.75 };
4820
5019
  const ghostMats = new Map;
4821
5020
  const syncGhost = () => {
4822
5021
  if (!ghost)
4823
5022
  return;
4824
- const show = ghostOn && shownStep != null && shownStep < uniq.length - 1;
5023
+ const show = ghostOn && shownStep != null && shownGhost != null && shownGhost < uniq.length - 1;
4825
5024
  ghost.root.visible = show;
4826
5025
  if (show)
4827
- ghost.setStep(uniq.length - 2 - shownStep, shownMask);
5026
+ ghost.setStep(uniq.length - 2 - shownGhost, shownMask);
4828
5027
  };
4829
5028
  const disposeGhost = () => {
4830
5029
  ghostGen++;
@@ -4849,7 +5048,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4849
5048
  const rev = new Int32Array(stepOf.length);
4850
5049
  for (let k = 0;k < rev.length; k++)
4851
5050
  rev[k] = n - 1 - stepOf[k];
4852
- const so = { ...sceneOpts(), edges: false, cond: false, tex: false, steps: rev, cull: undefined };
5051
+ const so = { ...sceneOpts(), studDecal: undefined, edges: false, cond: false, tex: false, steps: rev, cull: undefined };
4853
5052
  so.cull = cullCore(all, pack.header, rev);
4854
5053
  const g = await buildLdrSceneAsync(all, pack, so, color, () => {}, { postPaintSliceMs: 12 });
4855
5054
  if (my !== ghostGen) {
@@ -4865,9 +5064,9 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4865
5064
  return;
4866
5065
  if (x.material)
4867
5066
  old.add(x.material);
4868
- let m = ghostMats.get(x.material?.side ?? THREE2.FrontSide);
5067
+ let m = ghostMats.get(x.material?.side ?? THREE3.FrontSide);
4869
5068
  if (!m)
4870
- ghostMats.set(x.material?.side ?? THREE2.FrontSide, m = ghostMaterial(x.material?.side ?? THREE2.FrontSide, ghostOpts));
5069
+ ghostMats.set(x.material?.side ?? THREE3.FrontSide, m = ghostMaterial(x.material?.side ?? THREE3.FrontSide, ghostOpts));
4871
5070
  x.material = m;
4872
5071
  x.castShadow = x.receiveShadow = false;
4873
5072
  x.renderOrder = 1;
@@ -4884,8 +5083,28 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4884
5083
  syncGhost();
4885
5084
  })();
4886
5085
  const multiStep = uniq.length > 1;
4887
- const drawnAt = (step, mask) => all.filter((i, k) => (step == null || stepOf[k] <= step) && (!mask || mask[k]) && pack.header.parts[i.part]).length;
4888
- const sceneOpts = () => ({ localColours: localColours.size ? localColours : undefined, cullStuds: cs, cullUnder: cu, edges: o.edges, side, cond: o.conditionalLines, condStuds: o.conditionalStudLines !== false, tex: o.textures !== false, lod: o.lod !== false, lodPx: o.lodPx, lodEdgePx: o.lodEdgePx, lodEdgeMinPx: o.lodEdgeMinPx, lodEdgeCap: o.lodEdgeCap, lodUnder: o.lodUnder, steps: multiStep ? stepOf : undefined, cull: o.precomputedCull });
5086
+ const drawnAt = (step, mask) => {
5087
+ if (step == null && !mask)
5088
+ return drawnAll;
5089
+ let n = 0;
5090
+ for (let k = 0;k < all.length; k++)
5091
+ if ((step == null || stepOf[k] <= step) && (!mask || mask[k]) && parts[all[k].part])
5092
+ n++;
5093
+ return n;
5094
+ };
5095
+ let stepMode = multiStep && (o.step != null || !!o.eagerSteps);
5096
+ let flatCull = o.precomputedCull, stepCull = o.precomputedCull?.studHideStep ? o.precomputedCull : undefined;
5097
+ const withCull = (so) => {
5098
+ if (!so.cull) {
5099
+ so.cull = cullCore(all, pack.header, so.steps);
5100
+ if (so.steps)
5101
+ stepCull = so.cull;
5102
+ else
5103
+ flatCull = so.cull;
5104
+ }
5105
+ return so;
5106
+ };
5107
+ const sceneOpts = () => ({ localColours: localColours.size ? localColours : undefined, cullStuds: cs, cullUnder: cu, studGrid: o.studGrid, studDecal: o.studDecal, edges: o.edges, side, cond: o.conditionalLines, condStuds: o.conditionalStudLines !== false, tex: o.textures !== false, lod: o.lod !== false, lodPx: o.lodPx, lodEdgePx: o.lodEdgePx, lodEdgeMinPx: o.lodEdgeMinPx, lodEdgeCap: o.lodEdgeCap, lodUnder: o.lodUnder, steps: stepMode ? stepOf : undefined, cull: stepMode ? stepCull : flatCull });
4889
5108
  const applyBuilt = (built, t0) => {
4890
5109
  cur = built;
4891
5110
  pairs.clear();
@@ -4908,15 +5127,28 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4908
5127
  cur.setLod(false);
4909
5128
  if (cur.root.parent !== object)
4910
5129
  object.add(cur.root);
5130
+ if (studMaskShown && stepMode)
5131
+ cur.setStudMask(studMaskShown);
4911
5132
  Object.assign(stats, { drawn: drawnAt(null), studsTotal: cur.stats.studsTotal, studsHidden: cur.stats.studsHidden, undersTotal: cur.stats.undersTotal, undersHidden: cur.stats.undersHidden, condBatches: cur.stats.condBatches ?? 0, texBatches: cur.stats.texBatches ?? 0, textures: cur.stats.textures ?? 0, glossmaps: cur.stats.glossmaps ?? 0, clusters: cur.stats.clusters ?? 0, longestSliceMs: cur.stats.longestSliceMs, buildYields: cur.stats.buildYields, buildMs: performance.now() - t0 });
4912
5133
  api.texturesReady = cur.texturesReady;
4913
5134
  };
4914
- const setStep = (step, mask = null) => {
5135
+ const setStep = (step, mask = null, ghostAfter) => {
4915
5136
  if (!multiStep)
4916
5137
  return;
4917
5138
  const t0 = performance.now();
4918
5139
  shownStep = step;
4919
5140
  shownMask = mask;
5141
+ shownGhost = step == null ? null : Math.max(step, ghostAfter ?? step);
5142
+ if (!stepMode) {
5143
+ if (!mask && (step == null || step >= uniq.length - 1)) {
5144
+ Object.assign(stats, { drawn: drawnAt(null), buildMs: performance.now() - t0 });
5145
+ syncGhost();
5146
+ return;
5147
+ }
5148
+ stepMode = true;
5149
+ disposeCur();
5150
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
5151
+ }
4920
5152
  Object.assign(stats, cur.setStep(step, mask), { drawn: drawnAt(step, mask), buildMs: performance.now() - t0 });
4921
5153
  if (ghostOn && step != null && !ghost)
4922
5154
  buildGhost();
@@ -4932,6 +5164,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4932
5164
  stepCount: uniq.length,
4933
5165
  stepViews,
4934
5166
  setStep,
5167
+ setStudMask: (m) => {
5168
+ studMaskShown = m;
5169
+ return stepMode ? cur.setStudMask(m) : false;
5170
+ },
4935
5171
  setEdges: (v) => {
4936
5172
  edges = v;
4937
5173
  cur.setEdges(v);
@@ -4946,7 +5182,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4946
5182
  if (!a && cur.trimmed.studs || !b && cur.trimmed.under) {
4947
5183
  disposeCur();
4948
5184
  const t0 = performance.now();
4949
- applyBuilt(buildLdrScene(all, pack, sceneOpts(), color, () => {}), t0);
5185
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
4950
5186
  } else
4951
5187
  cur.setCull(a, b);
4952
5188
  ghost?.setCull(a, b);
@@ -4983,7 +5219,7 @@ function createLdrObjectInner(instances, pack, options, progressive) {
4983
5219
  p.needsUpdate = true;
4984
5220
  }
4985
5221
  },
4986
- getBox: (target = new THREE2.Box3) => {
5222
+ getBox: (target = new THREE3.Box3) => {
4987
5223
  object.updateMatrixWorld(true);
4988
5224
  target.makeEmpty();
4989
5225
  object.traverse((x) => {
@@ -5012,14 +5248,12 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5012
5248
  };
5013
5249
  if (!progressive) {
5014
5250
  const t0 = performance.now();
5015
- applyBuilt(buildLdrScene(all, pack, sceneOpts(), color, () => {}), t0);
5251
+ applyBuilt(buildLdrScene(all, pack, withCull(sceneOpts()), color, () => {}), t0);
5016
5252
  return finish();
5017
5253
  }
5018
5254
  return (async () => {
5019
5255
  const t0 = performance.now();
5020
- const so = sceneOpts();
5021
- if (!so.cull)
5022
- so.cull = cullCore(all, pack.header, so.steps);
5256
+ const so = withCull(sceneOpts());
5023
5257
  const built = await buildLdrSceneAsync(all, pack, so, color, () => {}, {
5024
5258
  sliceMs: o.sliceMs,
5025
5259
  postPaintSliceMs: o.postPaintSliceMs,
@@ -5033,10 +5267,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
5033
5267
  return finish();
5034
5268
  })();
5035
5269
  }
5036
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/parts-cdn.ts
5270
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/parts-cdn.ts
5037
5271
  import { decompress as decompress2 } from "fzstd";
5038
5272
 
5039
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/embedded.ts
5273
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/embedded.ts
5040
5274
  function splitFiles(text, fallback) {
5041
5275
  const files = new Map;
5042
5276
  let cur = null, saw = false, skip = false;
@@ -5114,8 +5348,8 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
5114
5348
  return out;
5115
5349
  }
5116
5350
 
5117
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/parts-cdn.ts
5118
- var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
5351
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/parts-cdn.ts
5352
+ var DEFAULT_PARTS_CDN = "https://ldr-parts-cdn.baconbrix.workers.dev/v1/";
5119
5353
  var indexCache = new Map;
5120
5354
  var shardCache = new Map;
5121
5355
  function loadPartsIndex(cdn = DEFAULT_PARTS_CDN, f = fetch) {
@@ -5375,10 +5609,10 @@ async function prepareModel(source, o = {}) {
5375
5609
  return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
5376
5610
  }
5377
5611
 
5378
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/load-worker.gen.ts
5379
- var load_worker_gen_default = 'var nn=ArrayBuffer,W=Uint8Array,ze=Uint16Array,rn=Int16Array;var $e=Int32Array,Ye=function(e,t,n){if(W.prototype.slice)return W.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new W(n-t);return r.set(e.subarray(t,n)),r},Re=function(e,t,n,r){if(W.prototype.fill)return W.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},sn=function(e,t,n,r){if(W.prototype.copyWithin)return W.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var on=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],Z=function(e,t,n){var r=Error(t||on[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,Z);if(!n)throw r;return r},bt=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},an=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},ln=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)Z(0);var a=6-s,u=i==3?4:i,l=bt(e,a,u);a+=u;var f=c?1<<c:s,h=bt(e,a,f)+(c==1&&256),g=h;if(!s){var p=1<<10+(e[5]>>3);g=p+(p>>3)*(e[5]&7)}if(g>2145386496)Z(1);var m=new W((t==1?h||g:t?0:g)+12);return m[0]=1,m[4]=4,m[8]=8,{b:a+f,y:0,l:0,d:l,w:t&&t!=1?t:m.subarray(12),e:g,o:new $e(m.buffer,0,3),u:h,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return an(e,4)+8;Z(0)},Se=function(e){var t=0;for(;1<<t<=e;++t);return t-1},Be=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)Z(3);var o=1<<s,i=o,c=-1,a=-1,u=-1,l=o,f=new nn(512+(o<<2)),h=new rn(f,0,256),g=new ze(f,0,256),p=new ze(f,512,o),m=512+(o<<1),A=new W(f,m,o),x=new W(f,m+o);while(c<255&&i>0){var d=Se(i+1),w=r>>3,b=(1<<d+1)-1,M=(e[w]|e[w+1]<<8|e[w+2]<<16)>>(r&7)&b,k=(1<<d)-1,N=b-i-1,P=M&k;if(P<N)r+=d,M=P;else if(r+=d+1,M>k)M-=N;if(h[++c]=--M,M==-1)i+=M,A[--l]=c;else i-=M;if(!M)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,c+=a}while(a==3)}if(c>255||i)Z(0);var y=0,B=(o>>1)+(o>>3)+3,C=o-1;for(var I=0;I<=c;++I){var R=h[I];if(R<1){g[I]=-R;continue}for(u=0;u<R;++u){A[y]=I;do y=y+B&C;while(y>=l)}}if(y)Z(0);for(u=0;u<o;++u){var S=g[A[u]]++,V=x[u]=s-Se(S);p[u]=(S<<V)-o}return[r+7>>3,{b:s,s:A,n:x,t:p}]},cn=function(e,t){var n=0,r=-1,s=new W(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),a=new ze(s.buffer,268);if(o<128){var u=Be(e,t+1,6),l=u[0],f=u[1];t+=o;var h=l<<3,g=e[t];if(!g)Z(0);var p=0,m=0,A=f.b,x=A,d=(++t<<3)-8+Se(g);for(;;){if(d-=A,d<h)break;var w=d>>3;if(p+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<A)-1,i[++r]=f.s[p],d-=x,d<h)break;w=d>>3,m+=(e[w]|e[w+1]<<8)>>(d&7)&(1<<x)-1,i[++r]=f.s[m],A=f.n[p],p=f.t[p],x=f.n[m],m=f.t[m]}if(++r>255)Z(0)}else{r=o-127;for(;n<r;n+=2){var b=e[++t];i[n]=b>>4,i[n+1]=b&15}++t}var M=0;for(n=0;n<r;++n){var k=i[n];if(k>11)Z(0);M+=k&&1<<k-1}var N=Se(M)+1,P=1<<N,D=P-M;if(D&D-1)Z(0);i[r++]=Se(D)+1;for(n=0;n<r;++n){var k=i[n];++c[i[n]=k&&N+1-k]}var y=new W(P<<1),B=y.subarray(0,P),C=y.subarray(P);a[N]=0;for(n=N;n>0;--n){var I=a[n];Re(C,n,I,a[n-1]=I+c[n]*(1<<N-n))}if(a[0]!=P)Z(0);for(n=0;n<r;++n){var R=i[n];if(R){var S=a[R];Re(B,n,S,a[R]=S+(1<<N-R))}}return[t,{n:C,b:N,s:B}]},un=Be(new W([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],fn=Be(new W([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],pn=Be(new W([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],yt=function(e,t){var n=e.length,r=new $e(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Je=new W(new $e([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),mn=yt(Je,0),Qe=new W(new $e([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),hn=yt(Qe,3),Fe=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)Z(0);var a=0,u=n.b,l=(r<<3)-8+Se(o)-u,f=-1;for(;l>c&&f<s;){var h=l>>3,g=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(l&7);a=(a<<u|g)&i,t[++f]=n.s[a],l-=u=n.n[a]}if(l!=c||f+1!=s)Z(0)},gn=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;Fe(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),Fe(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),Fe(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),Fe(e.subarray(r),t.subarray(c),n)},dn=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,a=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return Re(n,e[s],t.y,t.y+=c),n;return Re(new W(c),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=c,n;return Ye(e,s,a)}if(i==2){var u=e[s],l=u&3,f=u>>2&3,h=u>>4,g=0,p=0;if(l<2)if(f&1)h|=e[++s]<<4|(f&2&&e[++s]<<12);else h=u>>3;else if(p=f,f<2)h|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(f==2)h|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var m=n?n.subarray(t.y,t.y+t.m):new W(t.m),A=m.length-h;if(l==0)m.set(e.subarray(s,s+=h),A);else if(l==1)Re(m,e[s++],A);else{var x=t.h;if(l==2){var d=cn(e,s);g+=s-(s=d[0]),t.h=x=d[1]}else if(!x)Z(0);(p?gn:Fe)(e.subarray(s,s+=g),m.subarray(A),x)}var w=e[s++];if(w){if(w==255)w=(e[s++]|e[s++]<<8)+32512;else if(w>127)w=w-128<<8|e[s++];var b=e[s++];if(b&3)Z(0);var M=[fn,pn,un];for(var k=2;k>-1;--k){var N=b>>(k<<1)+2&3;if(N==1){var P=new W([0,0,e[s++]]);M[k]={s:P.subarray(2,3),n:P.subarray(0,1),t:new ze(P.buffer,0,1),b:0}}else if(N==2)r=Be(e,s,9-(k&1)),s=r[0],M[k]=r[1];else if(N==3){if(!t.t)Z(0);M[k]=t.t[k]}}var D=t.t=M,y=D[0],B=D[1],C=D[2],I=e[a-1];if(!I)Z(0);var R=(a<<3)-8+Se(I)-C.b,S=R>>3,V=0,he=(e[S]|e[S+1]<<8)>>(R&7)&(1<<C.b)-1;S=(R-=B.b)>>3;var ce=(e[S]|e[S+1]<<8)>>(R&7)&(1<<B.b)-1;S=(R-=y.b)>>3;var Me=(e[S]|e[S+1]<<8)>>(R&7)&(1<<y.b)-1;for(++w;--w;){var re=C.s[he],Te=C.n[he],be=y.s[Me],ve=y.n[Me],fe=B.s[ce],ke=B.n[ce];S=(R-=fe)>>3;var O=1<<fe,T=O+((e[S]|e[S+1]<<8|e[S+2]<<16|e[S+3]<<24)>>>(R&7)&O-1);S=(R-=Qe[be])>>3;var _=hn[be]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Qe[be])-1);S=(R-=Je[re])>>3;var X=mn[re]+((e[S]|e[S+1]<<8|e[S+2]<<16)>>(R&7)&(1<<Je[re])-1);if(S=(R-=Te)>>3,he=C.t[he]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<Te)-1),S=(R-=ve)>>3,Me=y.t[Me]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ve)-1),S=(R-=ke)>>3,ce=B.t[ce]+((e[S]|e[S+1]<<8)>>(R&7)&(1<<ke)-1),T>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=T-=3;else{var q=T-(X!=0);if(q){if(T=q==3?t.o[0]-1:t.o[q],q>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=T}else T=t.o[0]}for(var k=0;k<X;++k)m[V+k]=m[A+k];V+=X,A+=X;var ee=V-T;if(ee<0){var J=-ee,L=t.e+ee;if(J>_)J=_;for(var k=0;k<J;++k)m[V+k]=t.w[L+k];V+=J,_-=J,ee=0}for(var k=0;k<_;++k)m[V+k]=m[ee+k];V+=_}if(V!=A)while(A<m.length)m[V++]=m[A++];else V=m.length;if(n)t.y+=V;else m=Ye(m,0,V)}else if(n){if(t.y+=h,A)for(var k=0;k<h;++k)m[k]=m[A+k]}else if(A)m=Ye(m,A);return t.b=a,m}Z(2)},bn=function(e,t){if(e.length==1)return e[0];var n=new W(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function je(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=ln(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var c=dn(e,i,t);if(!c)Z(5);if(t)i.e=i.y;else n.push(c),o+=c.length,sn(i.w,0,c.length),i.w.set(c,i.w.length-c.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return bn(n,o)}async function yn(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(je(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function xt(e){return new TextDecoder().decode(await yn(e))}var wt=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function Ve(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var Y=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),et=/^[A-Za-z][A-Za-z0-9_]*$/,qe=new Map;function tt(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!qe.has(r))qe.set(r,t);return r}function nt(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&et.test(e))return tt(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var At=/^~?\\s*moved\\s+to\\s+(.+)$/i,xn=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),wn=new Set(["FILE","NOFILE","!DATA"]),Et=1000000000000000,Pt=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),An=new Set(["model","submodel","configuration"]),Mn=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function Mt(e){let t=Mn.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Pt.has(n)||An.has(n)?n:void 0}function vn(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function Cn(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((f)=>Number.isFinite(f)&&Math.abs(f)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let f=0;f<s;f++)c=c.replace(/^\\S+\\s*/,"");let a=vn(c);if(!a.length)return null;let u={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)u.a=i[9];if(s===11)u.b=i[10];let l=a.findIndex((f,h)=>h>0&&f.toUpperCase()==="GLOSSMAP");if(l>0&&a[l+1])u.glossmap=a[l+1];if(t)u.next=!0;return u}var kn=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,"");if(t.length%4===1)t=t.slice(0,-1);let n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function Tn(e,t){let n=e.length,r=1,s=(p)=>p===32||p===9,o=()=>{while(r<n&&s(e.charCodeAt(r)))r++;let p=r,m=e.charCodeAt(r),A=m===45;if(A)m=e.charCodeAt(++r);let x=0,d=0;while(m>=48&&m<=57)x=x*10+(m-48),d++,m=e.charCodeAt(++r);if(d>0&&d<=15&&(r>=n||s(m)))return A?-x:x;while(r<n&&!s(e.charCodeAt(r)))r++;return p<r?+e.slice(p,r):NaN};while(r<n&&s(e.charCodeAt(r)))r++;let i=r;if(r>=n)return null;let c=e.charCodeAt(r),a=c===45,u=0,l=0;if(a)c=e.charCodeAt(++r);while(c>=48&&c<=57)u=u*10+(c-48),l++,c=e.charCodeAt(++r);if(l>0&&l<=15&&(r>=n||s(c))){if(a)u=-u}else{while(r<n&&!s(e.charCodeAt(r)))r++;u=nt(e.slice(i,r))}let f=Array(12);for(let p=0;p<12;p++){let m=o();if(!Number.isFinite(m))return null;f[p]=m}while(r<n&&s(e.charCodeAt(r)))r++;if(r>=n)return null;let h=e.slice(r),g=t.get(h);if(g===void 0)g=Y(/[ \\t]{2,}|\\t/.test(h)?h.split(/\\s+/).join(" "):h),t.set(h,g);if(!Number.isFinite(u))return null;return{t:1,color:u,m:f,file:g}}var Ln=[0,12,6,9,12,12];function vt(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=nt(e[1]),r=Ln[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=Y(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function It(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,a=null,u=[],l=null,f=()=>{if(!a)return;let w=kn(a.chunks.join("")),b=w[0]===137&&w[1]===80&&w[2]===78&&w[3]===71;(c??=new Map).set(Y(a.name),{name:a.name,bytes:w,...b?{mime:"image/png"}:{}}),a=null},h=new Map,g=!0,p=(w)=>{if(f(),o={name:Y(w),cmds:[]},s.set(o.name,o),!i)i=o.name;u=[],l=null,g=!0},m=!1,A=!1,x=()=>{if(A)return;A=!0,s.clear(),o=null,i=""},d=(w,b)=>{if(l){w.tex=l,l=null;return}let M=u[u.length-1];if(!M)return;if(M.fallback){if(!b)w.fallback=!0}else w.tex=M.map};for(let w of e.split(`\n`)){let b=w.trim();if(!b)continue;if(r&&b.charCodeAt(0)>=50&&b.charCodeAt(0)<=53&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){if(a||m)continue;if(!o)p(t);let P=b.slice(2).trimStart(),D=P.search(/\\s/),y={t:b.charCodeAt(0)-48,color:nt(D<0?P:P.slice(0,D)),p:[],src:b};d(y,!1),o.cmds.push(y),g=!1;continue}if(b.charCodeAt(0)===48&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)){let P=2;while(b.charCodeAt(P)===32||b.charCodeAt(P)===9)P++;let D=P;while(D<b.length&&b.charCodeAt(D)!==32&&b.charCodeAt(D)!==9)D++;let y=b.slice(P,D),B=/[^\\x21-\\x7e]/.test(y)?b.slice(P).trim().split(/\\s+/)[0]:y;if(!xn.has(B)&&!(B.length>=4&&B.length<=6&&wn.has(B.toUpperCase()))){if(m||a)continue;if(!o)p(t);let C=b.slice(P),I={t:0,text:C};if(y.charCodeAt(0)===33)I.meta=y;if(l=null,g&&!o.org){let S=Mt(C);if(S)o.org=S}let R=C.match(At);if(R&&!o.movedTo){let S=R[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(S))S+=".dat";o.movedTo=Y(S)}o.cmds.push(I);continue}}if(b.charCodeAt(0)===49&&(b.charCodeAt(1)===32||b.charCodeAt(1)===9)&&!a&&!m){let P=Tn(b,h);if(P){if(!o)p(t);d(P,!1),o.cmds.push(P),g=!1;continue}}let M=b.split(/\\s+/);if(+M[0]===0){let P=b.slice(1).trim(),D=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(D==="FILE"){let C=P.slice(5).trimStart().split("\\r")[0].trim();if(C){x(),m=!1,p(C);continue}}if(D==="NOFILE"){f(),o=null,m=!0;continue}if(D==="!DATA"){x(),f(),o=null,m=!1,a={name:P.slice(5).trim(),chunks:[]};continue}if(m)continue;if(a){if(M[1]==="!:")a.chunks.push(M.slice(2).join(""));continue}if(!o)p(t);let y={t:0,text:P};if(M[1]==="STEP")y.step=!0,u=[],l=null;else if(M[1]==="BFC")y.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(y.meta="ROTSTEP",y.step=!0,u=[],l=null,(M[2]??"").toUpperCase()==="END")y.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(M[5]??"REL").toUpperCase(),I=(R)=>{let S=Number(R);return Number.isFinite(S)?S:0};y.rotstep={x:I(M[2]),y:I(M[3]),z:I(M[4]),mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(M[1]==="BUFEXCHG"){y.meta="BUFEXCHG";let C=(M[2]??"").toUpperCase();y.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))y.meta=M[1];if(g&&!o.org){let C=Mt(P);if(C)o.org=C}if(M[1]==="!TEXMAP"){let C=(M[2]??"").toUpperCase();if(l=null,C==="START"||C==="NEXT"){let I=Cn(P.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(y.texmap={op:C,...I?{map:I}:{}},I)if((o.texmaps??=[]).push(I),C==="START")u.push({map:I,fallback:!1});else l=I}else if(C==="FALLBACK"){y.texmap={op:C};let I=u[u.length-1];if(I)I.fallback=!0}else if(C==="END")y.texmap={op:C},u.pop()}else if(M[1]==="!:"){l=null;let C=vt(M.slice(2));if(C)d(C,!0),y.geom=C}else l=null;let B=P.match(At);if(B&&!o.movedTo){let C=B[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=Y(C)}o.cmds.push(y);continue}if(a||m)continue;if(!o)p(t);let N=vt(M);if(!N){if(/^[2-5][ \\t]/.test(b))g=!1;continue}d(N,!1),o.cmds.push(N),g=!1}return f(),c?{main:i,files:s,data:c}:{main:i,files:s}}var rr=Math.PI/180;function Ft(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function Rt(e,t){let[n,r,s,o,i,c,a,u,l,f,h,g]=e,[p,m,A,x,d,w,b,M,k,N,P,D]=t;return[o*p+i*m+c*A+n,a*p+u*m+l*A+r,f*p+h*m+g*A+s,o*x+i*b+c*N,o*d+i*M+c*P,o*w+i*k+c*D,a*x+u*b+l*N,a*d+u*M+l*P,a*w+u*k+l*D,f*x+h*b+g*N,f*d+h*M+g*P,f*w+h*k+g*D]}var rt=[0,0,0,1,0,0,0,1,0,0,0,1];var Ct=new WeakMap,Sn=/^(s|8|48)\\//;function st(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=Ct.get(n);if(r)return r;if(n.org)r=Pt.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&Sn.test(s.file))?"part":"model";return Ct.set(n,r),r}var kt=new WeakMap;function Bt(e){let t=kt.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return kt.set(e,t),t}var Tt=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?qe.get(e)??String(e):String(e),En=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Tt(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Tt(e.color)} ${e.p.join(" ")}`,ot=(e,t)=>`${Y(e)}#${t}`;function Pn(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:ot(e.name,t),cmds:n}}function Dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Pn(e,t).cmds.map(En)].join(`\n`)+`\n`}function it(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function Ut(e){let[t,n,r,s,o,i,c,a,u,l,f,h]=e,g=a*h-u*f,p=-(c*h-u*l),m=c*f-a*l,A=s*g+o*p+i*m;if(!Number.isFinite(A)||Math.abs(A)<0.000000000001)return null;let x=1/A,d=[g*x,-(o*h-i*f)*x,(o*u-i*a)*x,p*x,(s*h-i*l)*x,-(s*u-i*c)*x,m*x,-(s*f-o*l)*x,(s*a-o*c)*x];return[-(d[0]*t+d[1]*n+d[2]*r),-(d[3]*t+d[4]*n+d[5]*r),-(d[6]*t+d[7]*n+d[8]*r),...d]}var In=(e)=>String(+e.toFixed(6)||0),Lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function Nt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(In).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${Lt(t.texture)}${t.glossmap?" GLOSSMAP "+Lt(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${Y(e)}\n0 !TEXMAP END\n`;return{name:`${Y(e)}#tex-${it(r)}`,source:r}}var Fn=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function Rn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),a=Math.sin(n*r),u=Math.cos(n*r);return[c*u,-c*a,i,o*a+s*i*u,o*u-s*i*a,-s*c,s*a-o*i*u,s*u+o*i*a,o*c]}var St=new WeakMap;function Ot(e){let t=St.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=Rn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:Fn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),St.set(e,n),n}class at extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var Bn=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=Et))return!1;return!0},zt=999999,Vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",_t=new WeakMap,$t=new WeakMap;function Dn(e,t){let n=$t.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=_t.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},$t.set(t,n);let r=n.parts.get(e);if(!r){let s=Y(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${it(o)}`,source:o},n.parts.set(e,r)}return r}function Un(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,a=0,u=new Set,l=t.maxInstances??2000000,f=0,h=(p,m)=>{let A=p.name+"#"+m,x=c.get(A);if(!x){let d;x=Object.assign(()=>d??=Dt(p,m),{file:p,step:m}),c.set(A,x)}return x},g=(p,m,A,x,d,w,b,M,k=null,N=[],P=[],D=void 0,y=null)=>{let B=p.files.get(m);if(!B||b>r||u.has(B))return;if(++f>l)throw new at("model",l);u.add(B);let C=y,I=0,R=b>0?++a:0,S=i&&R?[...N,R]:N,V=i&&R?[...P,A]:P,he=i&&!k?new Map:null,ce=-1,Me=0,re=(O,T,_,X,q,ee,J)=>{if(ce!==I)ce=I,Me=0;let L=he?.get(I+"|"+T);if(L)return L.n++,g(O,O===p?T:O.main,_,X,d+"/"+T,[...q,zt],b+1,ee,[...q,zt],S,V,J,C);let F=[...q,Me++],v=n.length;g(O,O===p?T:O.main,_,X,d+"/"+T,F,b+1,ee,k,S,V,J,C),he?.set(I+"|"+T,{n:1,from:v,to:n.length})},Te=Ot(B),be=s?Bt(B):[],ve=0,fe=(O,T,_,X,q,ee,J,L,F)=>{if(k)X=k;if(++f>l)throw new at("model",l);let v={part:O,color:T,m:_,step:X[0],steps:X,localStep:q,path:d};if(L)v.colour=L;if(R){if(v.sub=R,i)v.subPath=S,v.subMats=V}if(ee)v.embedded=!0;if(J){let E=Nt(O,J);v.texPart=E.name,v.texSource=E.source}else if(F){let E=Dn(O,F);v.colPart=E.name,v.colSource=E.source}let U=Te[q];if(U)v.view=U;return n.push(v),v},ke=(O)=>{while(ve<be.length&&be[ve]<=O){let T=be[ve++];fe(ot(B.name,T),x,A,[...w,T],T,!1,null,D,y).source=h(B,T)}};for(let O of B.cmds){if(O.t===0&&O.step){I++;continue}let T=O;if(T.t>=2||T.t===0&&T.geom&&T.geom.t>=2){ke(I);continue}if(T.t===0){if(T.meta==="!COLOUR"){let U=On(T.text);if(U&&U.code!==16&&U.code!==24)_t.set(U,T.text),(C=new Map(C??[])).set(U.code,U);continue}if(o&&T.geom?.t===1)T=T.geom;else continue}if(T.t!==1)continue;if(o&&T.fallback)continue;let _=Rt(A,T.m);if(!Bn(_))continue;let X=T.color===16?x:T.color,q=T.color===16?D:C?.get(T.color),ee=[...w,I],J=o?T.tex??M:null,L=J?Ut(T.m):null,F=J&&L?Ft(J,L):null;if(p.files.has(T.file)){if(st(p,T.file)==="model"){re(p,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!0,F,q,C);continue}let v=t.resolveModel?.(T.file);if(v){re(v,T.file,_,X,ee,F,q);continue}fe(T.file,X,_,ee,I,!1,F,q,C)}if(ke(1/0),u.delete(B),he){for(let O of he.values())if(O.n>1)for(let T=O.from;T<O.to;T++)n[T].mult??=O.n}};if(st(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...rt],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,rt,16,e.main,[],0,null),n}function Gt(e,t="main.ldr",n){return Un(It(e,t,{geometryText:!0}),n)}var Nn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function lt(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function jt(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=lt(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function On(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,a=0,u={type:"default"},l=1;while(l<n.length){let f=n[l].toUpperCase(),h=n[l+1];if(f==="CODE")s=h!==void 0&&et.test(h)?tt(h):h!==void 0&&/^\\d+$/.test(h)?+h:NaN,l+=2;else if(f==="VALUE"){let g=lt(h);if(g)o=g;l+=2}else if(f==="EDGE")i=lt(h)??h,l+=2;else if(f==="ALPHA")c=+h,l+=2;else if(f==="LUMINANCE")a=+h,l+=2;else if(f==="CHROME")u={type:"chrome"},l+=1;else if(f==="PEARLESCENT")u={type:"pearlescent"},l+=1;else if(f==="RUBBER")u={type:"rubber"},l+=1;else if(f==="MATTE_METALLIC")u={type:"matte_metallic"},l+=1;else if(f==="METAL")u={type:"metal"},l+=1;else if(f==="MATERIAL"){let g=(n[l+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:p,next:m}=jt(n,l+2);u={type:"glitter",material:p},l=m}else if(g==="SPECKLE"){let{grain:p,next:m}=jt(n,l+2);u={type:"speckle",material:p},l=m}else if(g==="FABRIC"){let p=(n[l+2]||"").toUpperCase(),m=["VELVET","CANVAS","STRING","FUR"].includes(p)?p.toLowerCase():void 0;u={type:"fabric",kind:m},l+=m?3:2}else l=n.length}else if(Nn.has(f))l+=1;else l+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(a)?a:0,finish:u}}function zn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function ct(e){let t=zn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function $n(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(Y(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(Y(t),r)}let a=i.trim().replace(/\\s+/g," ");if(a)r.push(a)}return n}var jn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Vn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Wt(e,t,n="main.ldr"){let r=[...t],s=new Map;if(!r.length)return s;let o=$n(e,n);for(let i of r){let c=Y(i);if(!o.has(c)||s.has(c))continue;let a=new Set([c]),u=[c];while(u.length)for(let f of o.get(u.pop())){let h=jn(f);if(h&&o.has(h)&&!a.has(h))a.add(h),u.push(h)}let l=[c,...[...a].filter((f)=>f!==c).sort()].map((f)=>"0 FILE "+(f===c?"":f)+`\n`+o.get(f).join(`\n`)).join(`\n`);s.set(c,`emb/${Vn(l)}.dat`)}return s}var Xt=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Ht=new WeakMap,ut=null,ft="",pt=null;function mt(e,t){if(e===ut&&t===ft)return pt;let n=Ht.get(e);if(!n)Ht.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return ut=e,ft=t,pt=r,r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],a=[];s.studs.forEach((g,p)=>{c.push(g[0]),a.push(g[1]);for(let m=0;m<12;m++)i[p*12+m]=g[2+m]});let u=null,l=0,f=0;if(s.mask){l=s.mask[0],f=s.mask[1];let g=s.mask[2];u=new Uint8Array(g.length);for(let p=0;p<g.length;p++)u[p]=g.charCodeAt(p)===49?1:0}let h=!!u;if(u){for(let g=0;g<u.length;g++)if(u[g]!==1){h=!1;break}}return n.set(t,r={nStuds:o,studM:i,kind:c,color:a,mask:u,nx:l,nz:f,full:h}),ut=e,ft=t,pt=r,r}var Pe=1073741824;class Ee{t;tag;mask;size=0;shift;constructor(e=1024,t=-1){let n=1024;while(n<e*2)n*=2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.shift=t}slot(e,t,n){let r=this.shift;if(r<0){let o=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return o^=o>>>15,o=Math.imul(o,739982445),o^=o>>>12,o&this.mask}let s=Math.imul(e>>r+2,2654435761)^Math.imul(t,2246822507)^Math.imul(n>>r+2,3266489909);return s^=s>>>15,s=Math.imul(s,739982445),s^=s>>>12,(s<<4|(e>>r&3)<<2|n>>r&3)&this.mask}static tagOf(e,t,n){return Math.imul(e^Math.imul(t,374761393)^Math.imul(n,668265261),2654435761)>>>24|1}get(e,t,n){let r=Ee.tagOf(e,t,n),s=this.tag,o=this.t,i=this.mask,c=this.slot(e,t,n);for(;;){let a=s[c];if(a===0)return-1;if(a===r){let u=c<<2;if(o[u]===e&&o[u+1]===t&&o[u+2]===n)return o[u+3]}c=c+1&i}}put(e,t,n,r){if((this.size+1)*2>this.tag.length)this.grow();let s=Ee.tagOf(e,t,n),o=this.tag,i=this.t,c=this.mask,a=this.slot(e,t,n);for(;;){let u=o[a],l=a<<2;if(u===0)return o[a]=s,i[l]=e,i[l+1]=t,i[l+2]=n,i[l+3]=r,this.size++,-1;if(u===s&&i[l]===e&&i[l+1]===t&&i[l+2]===n){let f=i[l+3];return i[l+3]=r,f}a=a+1&c}}grow(){let e=this.t,t=this.tag,n=t.length*2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.size=0;for(let r=0;r<t.length;r++)if(t[r]){let s=r<<2;this.put(e[s],e[s+1],e[s+2],e[s+3])}}}class Zt{grp=new Ee(64);gBits=[];gX0=[];gZ0=[];gNz=[];gNx=[];bits;rest;lk=NaN;lpx=NaN;lpz=NaN;lg=-1;group(e,t,n){if(e!==this.lk||t!==this.lpx||n!==this.lpz)this.lk=e,this.lpx=t,this.lpz=n,this.lg=this.grp.get(e,t,n);return this.lg}constructor(e,t,n,r){let s=[],o=[],i=[],c=[],a=[];for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=(h%20+20)%20,A=(p%20+20)%20,x=this.group(g,m,A);if(x<0)x=s.length,this.grp.put(g,m,A,x),this.lg=x,s.push(0),o.push(h),i.push(h),c.push(p),a.push(p);if(s[x]++,h<o[x])o[x]=h;else if(h>i[x])i[x]=h;if(p<c[x])c[x]=p;else if(p>a[x])a[x]=p}let u=0,l=0;for(let f=0;f<s.length;f++){let h=(i[f]-o[f])/20+1,g=(a[f]-c[f])/20+1,p=h*g;if(this.gX0.push(o[f]),this.gZ0.push(c[f]),this.gNx.push(h),this.gNz.push(g),p<=64*s[f]+1024&&u+p<2147483648)this.gBits.push(u),u+=p;else this.gBits.push(-1),l+=s[f]}this.bits=new Uint8Array(Math.ceil(u/8)),this.rest=new Ee(l);for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=this.group(g,(h%20+20)%20,(p%20+20)%20),A=this.gBits[m];if(A<0){this.rest.put(h,g,p,1);continue}let x=A+(h-this.gX0[m])/20*this.gNz[m]+(p-this.gZ0[m])/20;this.bits[x>>>3]|=1<<(x&7)}}has(e,t,n){let r=this.group(t,(e%20+20)%20,(n%20+20)%20);if(r<0)return!1;let s=this.gBits[r];if(s<0)return this.rest.get(e,t,n)>=0;let o=(e-this.gX0[r])/20,i=(n-this.gZ0[r])/20;if(o<0||i<0||o>=this.gNx[r]||i>=this.gNz[r])return!1;let c=s+o*this.gNz[r]+i;return(this.bits[c>>>3]&1<<(c&7))!==0}}var _n=(e,t,n,r)=>e===0&&r===0&&(t===1||t===-1)&&(n===1||n===-1)||t===0&&n===0&&(e===1||e===-1)&&(r===1||r===-1),Ie=(e,t,n)=>e>-Pe&&e<Pe&&t>-Pe&&t<Pe&&n>-Pe&&n<Pe,De=2147483647;function Gn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function Wn(e,t,n){return Kt(e,t,n,-1)??Kt(e,t,n,Yt)}var Yt=0;function Kt(e,t,n,r){let o=new Map,i=(L)=>{let F=o.get(L);if(F===void 0)o.set(L,F=Gn(t,L));return F},c=e.length,a=0,u=0;for(let L=0,F="";L<c;L++){let v=e[L].part;if(v===F){a++;continue}let U=t.parts[v];if(U&&U.mask)a++,F=v}let l=new Float64Array(a),f=new Float64Array(a),h=new Float64Array(a),g=new Float64Array(a),p=new Int32Array(a),m=new Int32Array(a),A=new Float64Array(a),x=new Float64Array(a),d=[],w=new Int32Array(a),b=new Float64Array(a*9),M=new Uint8Array(a);if(r<0)r=a*4+64;let k=new Ee(e.length*2),N=new Int32Array(r),P=new Int32Array(r),D=0,y=0;for(let L=0;L<e.length;L++){let F=e[L],v=F.m,U=t.parts[F.part];if(!U||!U.mask||!Xt(v)||i(F.color))continue;let E=U.bbox,z=1/0,j=-1/0,te=1/0,H=-1/0;for(let K=0;K<2;K++)for(let le=0;le<2;le++){let ne=K?E[3]:E[0],Le=le?E[5]:E[2],Ae=v[0]+v[3]*ne+v[5]*Le,de=v[2]+v[9]*ne+v[11]*Le;if(Ae<z)z=Ae;if(Ae>j)j=Ae;if(de<te)te=de;if(de>H)H=de}let G=Math.round((v[1]+E[4])*2),Q=mt(t,F.part),ue=Math.floor(z/40),ye=Math.floor(j/40),xe=Math.floor(te/40),we=Math.floor(H/40);if(!((ye-ue+1)*(we-xe+1)<=65536)||!Ie(G,ue,xe)||!Ie(G,ye,we))continue;let ge=Math.floor((z+5)/40),se=Math.floor((j-5)/40),oe=Math.floor((te+5)/40),ie=Math.floor((H-5)/40),Ce=ge<=se&&oe<=ie?(se-ge+1)*(ie-oe+1):0;y+=Ce;let pe=-1;for(let K=ge<=se&&oe<=ie?k.get(G,ge,oe):-1,le=0;K>=0&&le<8;K=N[K],le++){let ne=P[K];if(l[ne]!==z||f[ne]!==j||h[ne]!==te||g[ne]!==H||d[ne]!==Q)continue;let Le=e[p[ne]].m,Ae=!0;for(let de=0;de<12;de++)if(Le[de]!==v[de]){Ae=!1;break}if(Ae){pe=ne;break}}if(pe>=0){let K=n?n[L]:0;if(n&&K<n[p[pe]])m[pe]=p[pe],p[pe]=L;else if(m[pe]<0||n&&K<n[m[pe]])m[pe]=L;continue}let ae=u++;l[ae]=z,f[ae]=j,h[ae]=te,g[ae]=H,p[ae]=L,m[ae]=-1,d.push(Q),A[ae]=E[0],x[ae]=E[2],w[ae]=G;let me=ae*9;if(b[me]=v[0],b[me+1]=v[1],b[me+2]=v[2],b[me+3]=v[3],b[me+4]=v[6],b[me+5]=v[9],b[me+6]=v[5],b[me+7]=v[8],b[me+8]=v[11],M[ae]=Q.full&&E[3]-E[0]<=20*Q.nx&&E[5]-E[2]<=20*Q.nz&&v[4]===0&&v[6]===0&&v[8]===0&&v[10]===0&&_n(v[3],v[5],v[9],v[11])?1:0,D+Ce>r){D=r+1;continue}for(let K=ge;K<=se;K++)for(let le=oe;le<=ie;le++){if(!Ie(G,K,le))continue;let ne=D++;P[ne]=ae,N[ne]=k.put(G,K,le,ne)}}if(D>r)return Yt=y,null;let B=[0,5,-5,5,-5],C=[0,5,5,-5,-5],I=(L,F,v,U)=>{if(!(F-6>=l[L]-0.5&&F+6<=f[L]+0.5&&U-6>=h[L]-0.5&&U+6<=g[L]+0.5))return!1;if(M[L]===1)return!0;let E=L*9,z=d[L],j=A[L],te=x[L],H=F-b[E],G=v-b[E+1],Q=U-b[E+2],ue=b[E+3]*H+b[E+4]*G+b[E+5]*Q,ye=b[E+6]*H+b[E+7]*G+b[E+8]*Q,{nx:xe,nz:we,mask:ge}=z;for(let se=0;se<5;se++){let oe=Math.floor((ue+B[se]-j)/20),ie=Math.floor((ye+C[se]-te)/20);if(oe<0||ie<0||oe>=xe||ie>=we||ge[oe*we+ie]!==1)return!1}return!0},R=NaN,S=NaN,V=NaN,he=-1,ce=-1,Me=(L,F,v,U)=>{let E=Math.round(F*2),z=Math.floor(L/40),j=Math.floor(v/40);if(!Ie(E,z,j))return De;let te=De;if(!n&&ce>=0&&w[ce]===E&&(p[ce]!==U||m[ce]>=0)&&I(ce,L,F,v))return 0;if(E!==R||z!==S||j!==V)R=E,S=z,V=j,he=k.get(E,z,j);for(let H=he;H>=0;H=N[H]){let G=P[H],Q=p[G];if(Q===U&&(Q=m[G])<0)continue;if(!I(G,L,F,v))continue;if(!n)return ce=G,0;let ue=n[Q];if(ue<te)te=ue}return te},re=0;for(let L of e){let F=mt(t,L.part);if(F)re+=F.nStuds}let Te=new Uint8Array(re),be=new Uint8Array(re),ve=0,fe=n?new Ee(re,4):null,ke=n?null:new Int32Array(re),O=n?null:new Int32Array(re),T=n?null:new Int32Array(re),_=0,X=n?new Int32Array(re).fill(De):void 0;for(let L=0,F=0;L<e.length;L++){let v=e[L],U=mt(t,v.part);if(!U)continue;let E=v.m,z=U.studM,j=E[0],te=E[1],H=E[2],G=E[3],Q=E[4],ue=E[5],ye=E[6],xe=E[7],we=E[8],ge=E[9],se=E[10],oe=E[11];for(let ie=0;ie<U.nStuds;ie++,F++){let Ce=ie*12,pe=z[Ce+4],ae=z[Ce+7],me=z[Ce+10];if(!(Math.abs(ye*pe+xe*ae+we*me-1)<0.001&&Math.abs(G*pe+Q*ae+ue*me)<0.001&&Math.abs(ge*pe+se*ae+oe*me)<0.001))continue;be[F]=1;let K=z[Ce],le=z[Ce+1],ne=z[Ce+2],Le=j+G*K+Q*le+ue*ne,Ae=te+ye*K+xe*le+we*ne,de=H+ge*K+se*le+oe*ne,ht=Me(Le,Ae,de,L);if(ht!==De){if(Te[F]=1,ve++,X)X[F]=ht}let Ue=Math.round(Le),Ne=Math.round(Ae),Oe=Math.round(de);if(!Ie(Ue,Ne,Oe))continue;if(!fe){ke[_]=Ue,O[_]=Ne,T[_++]=Oe;continue}let gt=n[L],dt=fe.get(Ue,Ne,Oe);if(dt<0||gt<dt)fe.put(Ue,Ne,Oe,gt)}}let q=fe?null:new Zt(ke,O,T,_),ee=new Uint8Array(e.length),J=n?new Int32Array(e.length).fill(De):void 0;for(let L=0;L<e.length;L++){let F=e[L],v=t.parts[F.part];if(!v||!v.under||!Xt(F.m)||i(F.color))continue;let U=v.bbox,E=Math.round((U[3]-U[0])/20),z=Math.round((U[5]-U[2])/20);if(!E||!z||E*z>4096)continue;let j=F.m,te=Math.round(j[1]+U[4]),H=!0,G=0;for(let Q=0;Q<E&&H;Q++)for(let ue=0;ue<z;ue++){let ye=U[0]+10+20*Q,xe=U[2]+10+20*ue,we=j[0]+j[3]*ye+j[5]*xe,ge=j[2]+j[9]*ye+j[11]*xe,se=Math.round(we),oe=Math.round(ge),ie=!Ie(se,te,oe)?-1:fe?fe.get(se,te,oe):q.has(se,te,oe)?1:-1;if(ie<0){H=!1;break}if(ie>G)G=ie}if(H){if(ee[L]=1,J)J[L]=G}}return{nStuds:re,studHidden:Te,studUp:be,underHidden:ee,studsHidden:ve,studHideStep:X,underHideStep:J}}function Xn(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let f=l.colour;if(!f)return String(l.color);let h=o.get(f);if(h!==void 0)return h;let g=t.colorTable?.[l.color],p=g?.hex??t.colors?.[l.color],m=g?ct({alpha:g.alpha??255,luminance:g.luminance??0,finish:g.finish??{type:"default"}}):"default:op",A=ct(f);if(h=p&&p.toUpperCase()===f.hex.toUpperCase()&&m===A?String(l.color):f.hex.toUpperCase()+"/"+A,h!==String(l.color))s.set(h,f);return o.set(f,h),h},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),{stepOf:a,nSteps:u}=Hn(c);return{all:c,stepOf:a,nSteps:u,localColours:s}}function Hn(e){let t=!0;for(let o=0;o<e.length;o++){let i=e[o].steps;if(i.length!==1){t=!1;break}let c=i[0];if(!(Number.isInteger(c)&&c>=0&&c<1e6)){t=!1;break}}if(t){let o=new Set;for(let a=0;a<e.length;a++)o.add(e[a].steps[0]);let i=[...o].sort((a,u)=>a-u),c=new Map(i.map((a,u)=>[a,u]));return{stepOf:e.map((a)=>c.get(a.steps[0])),nSteps:i.length}}let n=e.map((o)=>Vt(o.steps)),r=[...new Set(n)].sort(),s=new Map(r.map((o,i)=>[o,i]));return{stepOf:n.map((o)=>s.get(o)),nSteps:r.length}}function _e(e,t,n=!0){let r=Xn(e,t,n);return Wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Ke="https://ldr-demo.vercel.app/cdn/v1/",We=new Map,Ge=new Map;function Xe(e=Ke,t=fetch){let n=We.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>We.delete(e)),We.set(e,n);return n}var Kn=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),He=(e,t)=>Kn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>He(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,He(r,t)])):e;function Zn(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let g=h.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let p=new DataView(g).getUint32(0,!0),m=new Uint8Array(g,4+p),A=r;n.push(m),r+=m.byteLength;let x=(4-r%4)%4;if(x)n.push(new Uint8Array(x)),r+=x;for(let[d,w]of Object.entries(h.header.parts??{}))if(!(d in s))s[d]=He(w,A);for(let[d,w]of Object.entries(h.header.studKinds??{}))if(!(d in o))o[d]=He(w,A)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+c.length)%4)%4,u=4+c.length+a,l=new Uint8Array(u+r);new DataView(l.buffer).setUint32(0,c.length+a,!0),l.set(c,4),l.fill(32,4+c.length,u);let f=u;for(let h of n)l.set(h,f),f+=h.byteLength;return Ve(l.buffer)}async function Yn(e,t={}){e=[...e];try{return await Jt(e,t)}catch(n){let r=t.cdn??Ke,s=t.fetch??fetch;We.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await Jt(e,{...t,fetch:o})}catch{throw n}}}async function Jt(e,t){let n=t.cdn??Ke,r=t.fetch??fetch,s=t.gap??16384,o=await Xe(n,r),i=[...new Set([...new Set(e)].map(Y))],c=[],a=[];for(let d of i){if(Ge.has(n+d))continue;let w=o.parts[d];if(w)a.push({name:d,off:w[0],len:w[1],file:w[2]??0});else c.push(d)}a.sort((d,w)=>d.file-w.file||d.off-w.off);let u=[];for(let d of a){let w=u[u.length-1];if(w&&w.file===d.file&&d.off-w.end<=s)w.end=Math.max(w.end,d.off+d.len),w.items.push(d);else u.push({file:d.file,start:d.off,end:d.off+d.len,items:[d]})}let l=0,f=0,h=0,g=new Map,p=async()=>{while(h<u.length){let d=u[h++],w=g.get(d.file);if(w)w=w.subarray(d.start,d.end);else{let b=await r(new URL(o.archives[d.file],n).href,{headers:{Range:`bytes=${d.start}-${d.end-1}`,"Accept-Encoding":"identity"}});if(!b.ok)throw Error(`ldr: parts CDN ${b.status}`);if(f++,w=new Uint8Array(await b.arrayBuffer()),l+=w.byteLength,b.status===200)g.set(d.file,w),w=w.subarray(d.start,d.end)}for(let b of d.items){let M=je(w.subarray(b.off-d.start,b.off-d.start+b.len)),k=M.buffer.slice(M.byteOffset,M.byteOffset+M.byteLength);Ge.set(n+b.name,Ve(k))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,u.length)},p));let m=i.filter((d)=>Ge.has(n+d)).map((d)=>Ge.get(n+d)),A={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:m.length?Zn(m,A):Ve(Jn(A)),missing:c,requests:f,bytes:l}}function Jn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function Qn(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function Qt(e,t,n){let r=0,s=0,o=!1,i=new Set,c=new Map;for(let a of e){let u;if(a.embedded)u=t.get(a.part);else if(u=c.get(a.part),u===void 0)c.set(a.part,u=Y(a.part));let l=u?n.parts[u]:void 0;if(!l)continue;if(l[3]!=null)o=!0,r+=l[3];if(!i.has(u))i.add(u),s+=l[1]}return{bodyTris:r,packBytes:s,known:o}}class Ze extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function qt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Xe(t.cdn??Ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(y)=>{if(!y.ok)throw Error(`ldr: ${y.status} fetching ${e}`);return xt(await y.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":wt(e)),a=Gt(o,c,{looseGeometry:!1,callouts:t.callouts}),u=performance.now();t.onParsed?.(a),await s;let l=Wt(o,new Set(a.filter((y)=>y.embedded).map((y)=>y.part)),c),f=(y,B)=>t.maxBodyTris!=null&&y>t.maxBodyTris||t.maxPackBytes!=null&&B>t.maxPackBytes,h=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(y)=>new Ze({...y,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),p="full";if(h){let y=Qt(a,l,await s);if(f(y.known?y.bodyTris:0,y.packBytes)){if(!t.lowCdn)throw g(y);let B=await Xe(t.lowCdn,r).catch(()=>null);if(!B)throw g(y);let C=Qt(a,l,B);if(f(C.known?C.bodyTris:0,C.packBytes))throw g(C);p="low"}}let m=[...a.filter((y)=>!y.embedded).map((y)=>y.part),...l.values()],A=async()=>{let y=await Yn(m,p==="low"?{...t,cdn:t.lowCdn}:t);for(let[B,C]of l){let I=y.pack.header.parts[C];if(I)y.pack.header.parts[B]=I}return{...y,packBytes:y.pack.buffer?.byteLength??y.pack.bytes??0,bodyTris:Qn(a,y.pack)}},x=await A();if(h&&f(x.bodyTris,x.packBytes)&&p==="full"&&t.lowCdn&&await Xe(t.lowCdn,r).then(()=>!0,()=>!1)){p="low";let y=x;x=await A(),x.requests+=y.requests,x.bytes+=y.bytes}if(h&&f(x.bodyTris,x.packBytes))throw g(x);let{pack:d,missing:w,requests:b,bytes:M}=x,k=new Map([...l].map(([y,B])=>[B,y])),N=w.map((y)=>k.get(y)??y),P=performance.now(),D=t.cull?_e(a,d.header,t.textures!==!1):void 0;return{insts:a,pack:d,tier:p,missing:N,requests:b,bytes:M,cull:D,timings:{fetchModel:i-n,parse:u-i,parts:P-u,...D?{cull:performance.now()-P}:{}}}}var qn=new Set(["part","color","m","step","steps","localStep","path"]);function en(e){let t=e.length,n=0;for(let p of e){if(typeof p.part!=="string"||typeof p.path!=="string"||typeof p.color!=="number"||typeof p.step!=="number"||typeof p.localStep!=="number"||!Array.isArray(p.m)||p.m.length!==12||!Array.isArray(p.steps))return null;n+=p.steps.length}let r=[],s=new Map,o=(p)=>{let m=s.get(p);if(m===void 0)s.set(p,m=r.length),r.push(p);return m},i=new Uint32Array(t),c=new Uint32Array(t),a=new Float64Array(t*3),u=new Float64Array(t*12),l=new Uint32Array(t+1),f=new Float64Array(n),h=[],g=0;for(let p=0;p<t;p++){let m=e[p];i[p]=o(m.part),c[p]=o(m.path),a[p*3]=m.color,a[p*3+1]=m.step,a[p*3+2]=m.localStep;let A=m.m,x=p*12;for(let b=0;b<12;b++)u[x+b]=A[b];let d=m.steps;for(let b=0;b<d.length;b++)f[g++]=d[b];l[p+1]=g;let w=null;for(let b in m)if(!qn.has(b))(w??={})[b]=m[b];if(w)h.push([p,w])}return{n:t,strs:r,part:i,path:c,num:a,m:u,so:l,steps:f,extra:h}}var tn=(e)=>[e.part.buffer,e.path.buffer,e.num.buffer,e.m.buffer,e.so.buffer,e.steps.buffer];self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await qt(n,{...r,cull:!1,onParsed:(l)=>{let f=en(l);if(f)self.postMessage({id:t,packed:f},tn(f));else self.postMessage({id:t,insts:l})}}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),c=_e(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,u=[];for(let l of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(l)u.push(l.buffer);self.postMessage({id:t,cull:c,ms:a},u)}catch(s){if(s instanceof Ze||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
5612
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/load-worker.gen.ts
5613
+ var load_worker_gen_default = 'var sn=ArrayBuffer,H=Uint8Array,$e=Uint16Array,on=Int16Array;var je=Int32Array,Ye=function(e,t,n){if(H.prototype.slice)return H.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 H(n-t);return r.set(e.subarray(t,n)),r},Be=function(e,t,n,r){if(H.prototype.fill)return H.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},an=function(e,t,n,r){if(H.prototype.copyWithin)return H.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 ln=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],Z=function(e,t,n){var r=Error(t||ln[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,Z);if(!n)throw r;return r},yt=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},cn=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},un=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)Z(0);var a=6-s,u=i==3?4:i,l=yt(e,a,u);a+=u;var f=c?1<<c:s,h=yt(e,a,f)+(c==1&&256),g=h;if(!s){var p=1<<10+(e[5]>>3);g=p+(p>>3)*(e[5]&7)}if(g>2145386496)Z(1);var m=new H((t==1?h||g:t?0:g)+12);return m[0]=1,m[4]=4,m[8]=8,{b:a+f,y:0,l:0,d:l,w:t&&t!=1?t:m.subarray(12),e:g,o:new je(m.buffer,0,3),u:h,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return cn(e,4)+8;Z(0)},Se=function(e){var t=0;for(;1<<t<=e;++t);return t-1},De=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)Z(3);var o=1<<s,i=o,c=-1,a=-1,u=-1,l=o,f=new sn(512+(o<<2)),h=new on(f,0,256),g=new $e(f,0,256),p=new $e(f,512,o),m=512+(o<<1),A=new H(f,m,o),b=new H(f,m+o);while(c<255&&i>0){var d=Se(i+1),x=r>>3,w=(1<<d+1)-1,v=(e[x]|e[x+1]<<8|e[x+2]<<16)>>(r&7)&w,M=(1<<d)-1,U=w-i-1,S=v&M;if(S<U)r+=d,v=S;else if(r+=d+1,v>M)v-=U;if(h[++c]=--v,v==-1)i+=v,A[--l]=c;else i-=v;if(!v)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,c+=a}while(a==3)}if(c>255||i)Z(0);var y=0,R=(o>>1)+(o>>3)+3,C=o-1;for(var F=0;F<=c;++F){var B=h[F];if(B<1){g[F]=-B;continue}for(u=0;u<B;++u){A[y]=F;do y=y+R&C;while(y>=l)}}if(y)Z(0);for(u=0;u<o;++u){var L=g[A[u]]++,V=b[u]=s-Se(L);p[u]=(L<<V)-o}return[r+7>>3,{b:s,s:A,n:b,t:p}]},fn=function(e,t){var n=0,r=-1,s=new H(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),a=new $e(s.buffer,268);if(o<128){var u=De(e,t+1,6),l=u[0],f=u[1];t+=o;var h=l<<3,g=e[t];if(!g)Z(0);var p=0,m=0,A=f.b,b=A,d=(++t<<3)-8+Se(g);for(;;){if(d-=A,d<h)break;var x=d>>3;if(p+=(e[x]|e[x+1]<<8)>>(d&7)&(1<<A)-1,i[++r]=f.s[p],d-=b,d<h)break;x=d>>3,m+=(e[x]|e[x+1]<<8)>>(d&7)&(1<<b)-1,i[++r]=f.s[m],A=f.n[p],p=f.t[p],b=f.n[m],m=f.t[m]}if(++r>255)Z(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 v=0;for(n=0;n<r;++n){var M=i[n];if(M>11)Z(0);v+=M&&1<<M-1}var U=Se(v)+1,S=1<<U,D=S-v;if(D&D-1)Z(0);i[r++]=Se(D)+1;for(n=0;n<r;++n){var M=i[n];++c[i[n]=M&&U+1-M]}var y=new H(S<<1),R=y.subarray(0,S),C=y.subarray(S);a[U]=0;for(n=U;n>0;--n){var F=a[n];Be(C,n,F,a[n-1]=F+c[n]*(1<<U-n))}if(a[0]!=S)Z(0);for(n=0;n<r;++n){var B=i[n];if(B){var L=a[B];Be(R,n,L,a[B]=L+(1<<U-B))}}return[t,{n:C,b:U,s:R}]},pn=De(new H([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],mn=De(new H([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],hn=De(new H([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],xt=function(e,t){var n=e.length,r=new je(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Je=new H(new je([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),gn=xt(Je,0),Qe=new H(new je([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),dn=xt(Qe,3),Re=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)Z(0);var a=0,u=n.b,l=(r<<3)-8+Se(o)-u,f=-1;for(;l>c&&f<s;){var h=l>>3,g=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(l&7);a=(a<<u|g)&i,t[++f]=n.s[a],l-=u=n.n[a]}if(l!=c||f+1!=s)Z(0)},bn=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;Re(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),Re(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),Re(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),Re(e.subarray(r),t.subarray(c),n)},yn=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,a=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return Be(n,e[s],t.y,t.y+=c),n;return Be(new H(c),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=c,n;return Ye(e,s,a)}if(i==2){var u=e[s],l=u&3,f=u>>2&3,h=u>>4,g=0,p=0;if(l<2)if(f&1)h|=e[++s]<<4|(f&2&&e[++s]<<12);else h=u>>3;else if(p=f,f<2)h|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(f==2)h|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var m=n?n.subarray(t.y,t.y+t.m):new H(t.m),A=m.length-h;if(l==0)m.set(e.subarray(s,s+=h),A);else if(l==1)Be(m,e[s++],A);else{var b=t.h;if(l==2){var d=fn(e,s);g+=s-(s=d[0]),t.h=b=d[1]}else if(!b)Z(0);(p?bn:Re)(e.subarray(s,s+=g),m.subarray(A),b)}var x=e[s++];if(x){if(x==255)x=(e[s++]|e[s++]<<8)+32512;else if(x>127)x=x-128<<8|e[s++];var w=e[s++];if(w&3)Z(0);var v=[mn,hn,pn];for(var M=2;M>-1;--M){var U=w>>(M<<1)+2&3;if(U==1){var S=new H([0,0,e[s++]]);v[M]={s:S.subarray(2,3),n:S.subarray(0,1),t:new $e(S.buffer,0,1),b:0}}else if(U==2)r=De(e,s,9-(M&1)),s=r[0],v[M]=r[1];else if(U==3){if(!t.t)Z(0);v[M]=t.t[M]}}var D=t.t=v,y=D[0],R=D[1],C=D[2],F=e[a-1];if(!F)Z(0);var B=(a<<3)-8+Se(F)-C.b,L=B>>3,V=0,me=(e[L]|e[L+1]<<8)>>(B&7)&(1<<C.b)-1;L=(B-=R.b)>>3;var be=(e[L]|e[L+1]<<8)>>(B&7)&(1<<R.b)-1;L=(B-=y.b)>>3;var ye=(e[L]|e[L+1]<<8)>>(B&7)&(1<<y.b)-1;for(++x;--x;){var ue=C.s[me],Pe=C.n[me],xe=y.s[ye],Ce=y.n[ye],ke=R.s[be],he=R.n[be];L=(B-=ke)>>3;var O=1<<ke,k=O+((e[L]|e[L+1]<<8|e[L+2]<<16|e[L+3]<<24)>>>(B&7)&O-1);L=(B-=Qe[xe])>>3;var J=dn[xe]+((e[L]|e[L+1]<<8|e[L+2]<<16)>>(B&7)&(1<<Qe[xe])-1);L=(B-=Je[ue])>>3;var _=gn[ue]+((e[L]|e[L+1]<<8|e[L+2]<<16)>>(B&7)&(1<<Je[ue])-1);if(L=(B-=Pe)>>3,me=C.t[me]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<Pe)-1),L=(B-=Ce)>>3,ye=y.t[ye]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<Ce)-1),L=(B-=he)>>3,be=R.t[be]+((e[L]|e[L+1]<<8)>>(B&7)&(1<<he)-1),k>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=k-=3;else{var W=k-(_!=0);if(W){if(k=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]=k}else k=t.o[0]}for(var M=0;M<_;++M)m[V+M]=m[A+M];V+=_,A+=_;var ne=V-k;if(ne<0){var q=-ne,le=t.e+ne;if(q>J)q=J;for(var M=0;M<q;++M)m[V+M]=t.w[le+M];V+=q,J-=q,ne=0}for(var M=0;M<J;++M)m[V+M]=m[ne+M];V+=J}if(V!=A)while(A<m.length)m[V++]=m[A++];else V=m.length;if(n)t.y+=V;else m=Ye(m,0,V)}else if(n){if(t.y+=h,A)for(var M=0;M<h;++M)m[M]=m[A+M]}else if(A)m=Ye(m,A);return t.b=a,m}Z(2)},xn=function(e,t){if(e.length==1)return e[0];var n=new H(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 Ve(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=un(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=yn(e,i,t);if(!c)Z(5);if(t)i.e=i.y;else n.push(c),o+=c.length,an(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 xn(n,o)}async function wn(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(Ve(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 wt(e){return new TextDecoder().decode(await wn(e))}var At=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function _e(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var Y=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),et=/^[A-Za-z][A-Za-z0-9_]*$/,qe=new Map;function tt(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!qe.has(r))qe.set(r,t);return r}function nt(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&et.test(e))return tt(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var Mt=/^~?\\s*moved\\s+to\\s+(.+)$/i,An=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Mn=new Set(["FILE","NOFILE","!DATA"]),Pt=1000000000000000,It=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),vn=new Set(["model","submodel","configuration"]),Cn=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function vt(e){let t=Cn.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return It.has(n)||vn.has(n)?n:void 0}function kn(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 Tn(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((f)=>Number.isFinite(f)&&Math.abs(f)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let f=0;f<s;f++)c=c.replace(/^\\S+\\s*/,"");let a=kn(c);if(!a.length)return null;let u={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)u.a=i[9];if(s===11)u.b=i[10];let l=a.findIndex((f,h)=>h>0&&f.toUpperCase()==="GLOSSMAP");if(l>0&&a[l+1])u.glossmap=a[l+1];if(t)u.next=!0;return u}var Ln=(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 Sn(e,t){let n=e.length,r=1,s=(p)=>p===32||p===9,o=()=>{while(r<n&&s(e.charCodeAt(r)))r++;let p=r,m=e.charCodeAt(r),A=m===45;if(A)m=e.charCodeAt(++r);let b=0,d=0;while(m>=48&&m<=57)b=b*10+(m-48),d++,m=e.charCodeAt(++r);if(d>0&&d<=15&&(r>=n||s(m)))return A?-b:b;while(r<n&&!s(e.charCodeAt(r)))r++;return p<r?+e.slice(p,r):NaN};while(r<n&&s(e.charCodeAt(r)))r++;let i=r;if(r>=n)return null;let c=e.charCodeAt(r),a=c===45,u=0,l=0;if(a)c=e.charCodeAt(++r);while(c>=48&&c<=57)u=u*10+(c-48),l++,c=e.charCodeAt(++r);if(l>0&&l<=15&&(r>=n||s(c))){if(a)u=-u}else{while(r<n&&!s(e.charCodeAt(r)))r++;u=nt(e.slice(i,r))}let f=Array(12);for(let p=0;p<12;p++){let m=o();if(!Number.isFinite(m))return null;f[p]=m}while(r<n&&s(e.charCodeAt(r)))r++;if(r>=n)return null;let h=e.slice(r),g=t.get(h);if(g===void 0)g=Y(/[ \\t]{2,}|\\t/.test(h)?h.split(/\\s+/).join(" "):h),t.set(h,g);if(!Number.isFinite(u))return null;return{t:1,color:u,m:f,file:g}}var En=[0,12,6,9,12,12];function Ct(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=nt(e[1]),r=En[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=Y(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function Ft(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,a=null,u=[],l=null,f=()=>{if(!a)return;let x=Ln(a.chunks.join("")),w=x[0]===137&&x[1]===80&&x[2]===78&&x[3]===71;(c??=new Map).set(Y(a.name),{name:a.name,bytes:x,...w?{mime:"image/png"}:{}}),a=null},h=new Map,g=!0,p=(x)=>{if(f(),o={name:Y(x),cmds:[]},s.set(o.name,o),!i)i=o.name;u=[],l=null,g=!0},m=!1,A=!1,b=()=>{if(A)return;A=!0,s.clear(),o=null,i=""},d=(x,w)=>{if(l){x.tex=l,l=null;return}let v=u[u.length-1];if(!v)return;if(v.fallback){if(!w)x.fallback=!0}else x.tex=v.map};for(let x of e.split(`\n`)){let w=x.trim();if(!w)continue;if(r&&w.charCodeAt(0)>=50&&w.charCodeAt(0)<=53&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)){if(a||m)continue;if(!o)p(t);let S=w.slice(2).trimStart(),D=S.search(/\\s/),y={t:w.charCodeAt(0)-48,color:nt(D<0?S:S.slice(0,D)),p:[],src:w};d(y,!1),o.cmds.push(y),g=!1;continue}if(w.charCodeAt(0)===48&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)){let S=2;while(w.charCodeAt(S)===32||w.charCodeAt(S)===9)S++;let D=S;while(D<w.length&&w.charCodeAt(D)!==32&&w.charCodeAt(D)!==9)D++;let y=w.slice(S,D),R=/[^\\x21-\\x7e]/.test(y)?w.slice(S).trim().split(/\\s+/)[0]:y;if(!An.has(R)&&!(R.length>=4&&R.length<=6&&Mn.has(R.toUpperCase()))){if(m||a)continue;if(!o)p(t);let C=w.slice(S),F={t:0,text:C};if(y.charCodeAt(0)===33)F.meta=y;if(l=null,g&&!o.org){let L=vt(C);if(L)o.org=L}let B=C.match(Mt);if(B&&!o.movedTo){let L=B[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(L))L+=".dat";o.movedTo=Y(L)}o.cmds.push(F);continue}}if(w.charCodeAt(0)===49&&(w.charCodeAt(1)===32||w.charCodeAt(1)===9)&&!a&&!m){let S=Sn(w,h);if(S){if(!o)p(t);d(S,!1),o.cmds.push(S),g=!1;continue}}let v=w.split(/\\s+/);if(+v[0]===0){let S=w.slice(1).trim(),D=v.length>1&&v[1].length>=4&&v[1].length<=6?v[1].toUpperCase():v[1];if(D==="FILE"){let C=S.slice(5).trimStart().split("\\r")[0].trim();if(C){b(),m=!1,p(C);continue}}if(D==="NOFILE"){f(),o=null,m=!0;continue}if(D==="!DATA"){b(),f(),o=null,m=!1,a={name:S.slice(5).trim(),chunks:[]};continue}if(m)continue;if(a){if(v[1]==="!:")a.chunks.push(v.slice(2).join(""));continue}if(!o)p(t);let y={t:0,text:S};if(v[1]==="STEP")y.step=!0,u=[],l=null;else if(v[1]==="BFC")y.bfc=v.slice(2).join(" ");else if(v[1]==="ROTSTEP")if(y.meta="ROTSTEP",y.step=!0,u=[],l=null,(v[2]??"").toUpperCase()==="END")y.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(v[5]??"REL").toUpperCase(),F=(B)=>{let L=Number(B);return Number.isFinite(L)?L:0};y.rotstep={x:F(v[2]),y:F(v[3]),z:F(v[4]),mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(v[1]==="BUFEXCHG"){y.meta="BUFEXCHG";let C=(v[2]??"").toUpperCase();y.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:v[3]??"A"}}else if(v[1]?.startsWith("!"))y.meta=v[1];if(g&&!o.org){let C=vt(S);if(C)o.org=C}if(v[1]==="!TEXMAP"){let C=(v[2]??"").toUpperCase();if(l=null,C==="START"||C==="NEXT"){let F=Tn(S.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(y.texmap={op:C,...F?{map:F}:{}},F)if((o.texmaps??=[]).push(F),C==="START")u.push({map:F,fallback:!1});else l=F}else if(C==="FALLBACK"){y.texmap={op:C};let F=u[u.length-1];if(F)F.fallback=!0}else if(C==="END")y.texmap={op:C},u.pop()}else if(v[1]==="!:"){l=null;let C=Ct(v.slice(2));if(C)d(C,!0),y.geom=C}else l=null;let R=S.match(Mt);if(R&&!o.movedTo){let C=R[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=Y(C)}o.cmds.push(y);continue}if(a||m)continue;if(!o)p(t);let U=Ct(v);if(!U){if(/^[2-5][ \\t]/.test(w))g=!1;continue}d(U,!1),o.cmds.push(U),g=!1}return f(),c?{main:i,files:s,data:c}:{main:i,files:s}}var sr=Math.PI/180;function Rt(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 Bt(e,t){let[n,r,s,o,i,c,a,u,l,f,h,g]=e,[p,m,A,b,d,x,w,v,M,U,S,D]=t;return[o*p+i*m+c*A+n,a*p+u*m+l*A+r,f*p+h*m+g*A+s,o*b+i*w+c*U,o*d+i*v+c*S,o*x+i*M+c*D,a*b+u*w+l*U,a*d+u*v+l*S,a*x+u*M+l*D,f*b+h*w+g*U,f*d+h*v+g*S,f*x+h*M+g*D]}var rt=[0,0,0,1,0,0,0,1,0,0,0,1];var kt=new WeakMap,Pn=/^(s|8|48)\\//;function st(e,t){let n=e.files.get(Y(t));if(!n)return"part";let r=kt.get(n);if(r)return r;if(n.org)r=It.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&&Pn.test(s.file))?"part":"model";return kt.set(n,r),r}var Tt=new WeakMap;function Dt(e){let t=Tt.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 Tt.set(e,t),t}var Lt=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?qe.get(e)??String(e):String(e),In=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${Lt(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${Lt(e.color)} ${e.p.join(" ")}`,ot=(e,t)=>`${Y(e)}#${t}`;function Fn(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:ot(e.name,t),cmds:n}}function Ut(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Fn(e,t).cmds.map(In)].join(`\n`)+`\n`}function it(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function Nt(e){let[t,n,r,s,o,i,c,a,u,l,f,h]=e,g=a*h-u*f,p=-(c*h-u*l),m=c*f-a*l,A=s*g+o*p+i*m;if(!Number.isFinite(A)||Math.abs(A)<0.000000000001)return null;let b=1/A,d=[g*b,-(o*h-i*f)*b,(o*u-i*a)*b,p*b,(s*h-i*l)*b,-(s*u-i*c)*b,m*b,-(s*f-o*l)*b,(s*a-o*c)*b];return[-(d[0]*t+d[1]*n+d[2]*r),-(d[3]*t+d[4]*n+d[5]*r),-(d[6]*t+d[7]*n+d[8]*r),...d]}var Rn=(e)=>String(+e.toFixed(6)||0),St=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function Ot(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(Rn).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${St(t.texture)}${t.glossmap?" GLOSSMAP "+St(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${Y(e)}\n0 !TEXMAP END\n`;return{name:`${Y(e)}#tex-${it(r)}`,source:r}}var Bn=(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 Dn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),a=Math.sin(n*r),u=Math.cos(n*r);return[c*u,-c*a,i,o*a+s*i*u,o*u-s*i*a,-s*c,s*a-o*i*u,s*u+o*i*a,o*c]}var Et=new WeakMap;function zt(e){let t=Et.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=Dn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:Bn(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),Et.set(e,n),n}class at extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var Un=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=Pt))return!1;return!0},$t=999999,_t=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Gt=new WeakMap,jt=new WeakMap;function Nn(e,t){let n=jt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Gt.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},jt.set(t,n);let r=n.parts.get(e);if(!r){let s=Y(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${it(o)}`,source:o},n.parts.set(e,r)}return r}function On(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,a=0,u=new Set,l=t.maxInstances??2000000,f=0,h=(p,m)=>{let A=p.name+"#"+m,b=c.get(A);if(!b){let d;b=Object.assign(()=>d??=Ut(p,m),{file:p,step:m}),c.set(A,b)}return b},g=(p,m,A,b,d,x,w,v,M=null,U=[],S=[],D=void 0,y=null)=>{let R=p.files.get(m);if(!R||w>r||u.has(R))return;if(++f>l)throw new at("model",l);u.add(R);let C=y,F=0,B=w>0?++a:0,L=i&&B?[...U,B]:U,V=i&&B?[...S,A]:S,me=i&&!M?new Map:null,be=-1,ye=0,ue=(O,k,J,_,W,ne,q)=>{if(be!==F)be=F,ye=0;let le=me?.get(F+"|"+k);if(le)return le.n++,g(O,O===p?k:O.main,J,_,d+"/"+k,[...W,$t],w+1,ne,[...W,$t],L,V,q,C);let T=[...W,ye++],P=n.length;g(O,O===p?k:O.main,J,_,d+"/"+k,T,w+1,ne,M,L,V,q,C),me?.set(F+"|"+k,{n:1,from:P,to:n.length})},Pe=zt(R),xe=s?Dt(R):[],Ce=0,ke=(O,k,J,_,W,ne,q,le,T)=>{if(M)_=M;if(++f>l)throw new at("model",l);let P={part:O,color:k,m:J,step:_[0],steps:_,localStep:W,path:d};if(le)P.colour=le;if(B){if(P.sub=B,i)P.subPath=L,P.subMats=V}if(ne)P.embedded=!0;if(q){let N=Ot(O,q);P.texPart=N.name,P.texSource=N.source}else if(T){let N=Nn(O,T);P.colPart=N.name,P.colSource=N.source}let E=Pe[W];if(E)P.view=E;return n.push(P),P},he=(O)=>{while(Ce<xe.length&&xe[Ce]<=O){let k=xe[Ce++];ke(ot(R.name,k),b,A,[...x,k],k,!1,null,D,y).source=h(R,k)}};for(let O of R.cmds){if(O.t===0&&O.step){F++;continue}let k=O;if(k.t>=2||k.t===0&&k.geom&&k.geom.t>=2){he(F);continue}if(k.t===0){if(k.meta==="!COLOUR"){let E=$n(k.text);if(E&&E.code!==16&&E.code!==24)Gt.set(E,k.text),(C=new Map(C??[])).set(E.code,E);continue}if(o&&k.geom?.t===1)k=k.geom;else continue}if(k.t!==1)continue;if(o&&k.fallback)continue;let J=Bt(A,k.m);if(!Un(J))continue;let _=k.color===16?b:k.color,W=k.color===16?D:C?.get(k.color),ne=[...x,F],q=o?k.tex??v:null,le=q?Nt(k.m):null,T=q&&le?Rt(q,le):null;if(p.files.has(k.file)){if(st(p,k.file)==="model"){ue(p,k.file,J,_,ne,T,W);continue}ke(k.file,_,J,ne,F,!0,T,W,C);continue}let P=t.resolveModel?.(k.file);if(P){ue(P,k.file,J,_,ne,T,W);continue}ke(k.file,_,J,ne,F,!1,T,W,C)}if(he(1/0),u.delete(R),me){for(let O of me.values())if(O.n>1)for(let k=O.from;k<O.to;k++)n[k].mult??=O.n}};if(st(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...rt],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,rt,16,e.main,[],0,null),n}function Ht(e,t="main.ldr",n){return On(Ft(e,t,{geometryText:!0}),n)}var zn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function lt(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function Vt(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=lt(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function $n(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,a=0,u={type:"default"},l=1;while(l<n.length){let f=n[l].toUpperCase(),h=n[l+1];if(f==="CODE")s=h!==void 0&&et.test(h)?tt(h):h!==void 0&&/^\\d+$/.test(h)?+h:NaN,l+=2;else if(f==="VALUE"){let g=lt(h);if(g)o=g;l+=2}else if(f==="EDGE")i=lt(h)??h,l+=2;else if(f==="ALPHA")c=+h,l+=2;else if(f==="LUMINANCE")a=+h,l+=2;else if(f==="CHROME")u={type:"chrome"},l+=1;else if(f==="PEARLESCENT")u={type:"pearlescent"},l+=1;else if(f==="RUBBER")u={type:"rubber"},l+=1;else if(f==="MATTE_METALLIC")u={type:"matte_metallic"},l+=1;else if(f==="METAL")u={type:"metal"},l+=1;else if(f==="MATERIAL"){let g=(n[l+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:p,next:m}=Vt(n,l+2);u={type:"glitter",material:p},l=m}else if(g==="SPECKLE"){let{grain:p,next:m}=Vt(n,l+2);u={type:"speckle",material:p},l=m}else if(g==="FABRIC"){let p=(n[l+2]||"").toUpperCase(),m=["VELVET","CANVAS","STRING","FUR"].includes(p)?p.toLowerCase():void 0;u={type:"fabric",kind:m},l+=m?3:2}else l=n.length}else if(zn.has(f))l+=1;else l+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(a)?a:0,finish:u}}function jn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function ct(e){let t=jn(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 Vn(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(Y(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(Y(t),r)}let a=i.trim().replace(/\\s+/g," ");if(a)r.push(a)}return n}var _n=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?Y(t.slice(14).join(" ")):null};function Gn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Wt(e,t,n="main.ldr"){let r=[...t],s=new Map;if(!r.length)return s;let o=Vn(e,n);for(let i of r){let c=Y(i);if(!o.has(c)||s.has(c))continue;let a=new Set([c]),u=[c];while(u.length)for(let f of o.get(u.pop())){let h=_n(f);if(h&&o.has(h)&&!a.has(h))a.add(h),u.push(h)}let l=[c,...[...a].filter((f)=>f!==c).sort()].map((f)=>"0 FILE "+(f===c?"":f)+`\n`+o.get(f).join(`\n`)).join(`\n`);s.set(c,`emb/${Gn(l)}.dat`)}return s}var Xt=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Kt=new WeakMap,ut=null,ft="",pt=null;function Hn(e,t){if(e===ut&&t===ft)return pt;let n=Kt.get(e);if(!n)Kt.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return ut=e,ft=t,pt=r,r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],a=[];s.studs.forEach((g,p)=>{c.push(g[0]),a.push(g[1]);for(let m=0;m<12;m++)i[p*12+m]=g[2+m]});let u=null,l=0,f=0;if(s.mask){l=s.mask[0],f=s.mask[1];let g=s.mask[2];u=new Uint8Array(g.length);for(let p=0;p<g.length;p++)u[p]=g.charCodeAt(p)===49?1:0}let h=!!u;if(u){for(let g=0;g<u.length;g++)if(u[g]!==1){h=!1;break}}return n.set(t,r={nStuds:o,studM:i,kind:c,color:a,mask:u,nx:l,nz:f,full:h}),ut=e,ft=t,pt=r,r}var Ie=1073741824;class Ee{t;tag;mask;size=0;shift;constructor(e=1024,t=-1){let n=1024;while(n<e*2)n*=2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.shift=t}slot(e,t,n){let r=this.shift;if(r<0){let o=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return o^=o>>>15,o=Math.imul(o,739982445),o^=o>>>12,o&this.mask}let s=Math.imul(e>>r+2,2654435761)^Math.imul(t,2246822507)^Math.imul(n>>r+2,3266489909);return s^=s>>>15,s=Math.imul(s,739982445),s^=s>>>12,(s<<4|(e>>r&3)<<2|n>>r&3)&this.mask}static tagOf(e,t,n){return Math.imul(e^Math.imul(t,374761393)^Math.imul(n,668265261),2654435761)>>>24|1}get(e,t,n){let r=Ee.tagOf(e,t,n),s=this.tag,o=this.t,i=this.mask,c=this.slot(e,t,n);for(;;){let a=s[c];if(a===0)return-1;if(a===r){let u=c<<2;if(o[u]===e&&o[u+1]===t&&o[u+2]===n)return o[u+3]}c=c+1&i}}put(e,t,n,r){if((this.size+1)*2>this.tag.length)this.grow();let s=Ee.tagOf(e,t,n),o=this.tag,i=this.t,c=this.mask,a=this.slot(e,t,n);for(;;){let u=o[a],l=a<<2;if(u===0)return o[a]=s,i[l]=e,i[l+1]=t,i[l+2]=n,i[l+3]=r,this.size++,-1;if(u===s&&i[l]===e&&i[l+1]===t&&i[l+2]===n){let f=i[l+3];return i[l+3]=r,f}a=a+1&c}}grow(){let e=this.t,t=this.tag,n=t.length*2;this.t=new Int32Array(n*4),this.tag=new Uint8Array(n),this.mask=n-1,this.size=0;for(let r=0;r<t.length;r++)if(t[r]){let s=r<<2;this.put(e[s],e[s+1],e[s+2],e[s+3])}}}class Yt{grp=new Ee(64);gBits=[];gX0=[];gZ0=[];gNz=[];gNx=[];bits;rest;lk=NaN;lpx=NaN;lpz=NaN;lg=-1;group(e,t,n){if(e!==this.lk||t!==this.lpx||n!==this.lpz)this.lk=e,this.lpx=t,this.lpz=n,this.lg=this.grp.get(e,t,n);return this.lg}constructor(e,t,n,r){let s=[],o=[],i=[],c=[],a=[];for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=(h%20+20)%20,A=(p%20+20)%20,b=this.group(g,m,A);if(b<0)b=s.length,this.grp.put(g,m,A,b),this.lg=b,s.push(0),o.push(h),i.push(h),c.push(p),a.push(p);if(s[b]++,h<o[b])o[b]=h;else if(h>i[b])i[b]=h;if(p<c[b])c[b]=p;else if(p>a[b])a[b]=p}let u=0,l=0;for(let f=0;f<s.length;f++){let h=(i[f]-o[f])/20+1,g=(a[f]-c[f])/20+1,p=h*g;if(this.gX0.push(o[f]),this.gZ0.push(c[f]),this.gNx.push(h),this.gNz.push(g),p<=64*s[f]+1024&&u+p<2147483648)this.gBits.push(u),u+=p;else this.gBits.push(-1),l+=s[f]}this.bits=new Uint8Array(Math.ceil(u/8)),this.rest=new Ee(l);for(let f=0;f<r;f++){let h=e[f],g=t[f],p=n[f],m=this.group(g,(h%20+20)%20,(p%20+20)%20),A=this.gBits[m];if(A<0){this.rest.put(h,g,p,1);continue}let b=A+(h-this.gX0[m])/20*this.gNz[m]+(p-this.gZ0[m])/20;this.bits[b>>>3]|=1<<(b&7)}}has(e,t,n){let r=this.group(t,(e%20+20)%20,(n%20+20)%20);if(r<0)return!1;let s=this.gBits[r];if(s<0)return this.rest.get(e,t,n)>=0;let o=(e-this.gX0[r])/20,i=(n-this.gZ0[r])/20;if(o<0||i<0||o>=this.gNx[r]||i>=this.gNz[r])return!1;let c=s+o*this.gNz[r]+i;return(this.bits[c>>>3]&1<<(c&7))!==0}}var Wn=(e,t,n,r)=>e===0&&r===0&&(t===1||t===-1)&&(n===1||n===-1)||t===0&&n===0&&(e===1||e===-1)&&(r===1||r===-1),Fe=(e,t,n)=>e>-Ie&&e<Ie&&t>-Ie&&t<Ie&&n>-Ie&&n<Ie,Ue=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 mt(e,t,n){return Zt(e,t,n,-1)??Zt(e,t,n,Jt)}var Jt=0;function Zt(e,t,n,r){let o=new Map,i=(T)=>{let P=o.get(T);if(P===void 0)o.set(T,P=Xn(t,T));return P},c=e.length,a=0,u=0,l=0,f=Array(c);for(let T=0;T<c;T++){let P=f[T]=Hn(t,e[T].part);if(P){if(l+=P.nStuds,P.mask)a++}}let h=new Float64Array(a),g=new Float64Array(a),p=new Float64Array(a),m=new Float64Array(a),A=new Int32Array(a),b=new Int32Array(a),d=new Float64Array(a),x=new Float64Array(a),w=[],v=new Int32Array(a),M=new Float64Array(a*9),U=new Uint8Array(a);if(r<0)r=a*4+64;let S=new Ee(e.length*2),D=new Int32Array(r),y=new Int32Array(r),R=0,C=0;for(let T=0;T<e.length;T++){let P=e[T],E=P.m,N=t.parts[P.part];if(!N||!N.mask||!Xt(E)||i(P.color))continue;let I=N.bbox,z=1/0,j=-1/0,ee=1/0,X=-1/0;for(let K=0;K<2;K++)for(let ae=0;ae<2;ae++){let te=K?I[3]:I[0],Le=ae?I[5]:I[2],ve=E[0]+E[3]*te+E[5]*Le,de=E[2]+E[9]*te+E[11]*Le;if(ve<z)z=ve;if(ve>j)j=ve;if(de<ee)ee=de;if(de>X)X=de}let G=Math.round((E[1]+I[4])*2),Q=f[T],ce=Math.floor(z/40),we=Math.floor(j/40),Ae=Math.floor(ee/40),Me=Math.floor(X/40);if(!((we-ce+1)*(Me-Ae+1)<=65536)||!Fe(G,ce,Ae)||!Fe(G,we,Me))continue;let ge=Math.floor((z+5)/40),re=Math.floor((j-5)/40),se=Math.floor((ee+5)/40),oe=Math.floor((X-5)/40),Te=ge<=re&&se<=oe?(re-ge+1)*(oe-se+1):0;C+=Te;let fe=-1;for(let K=ge<=re&&se<=oe?S.get(G,ge,se):-1,ae=0;K>=0&&ae<8;K=D[K],ae++){let te=y[K];if(h[te]!==z||g[te]!==j||p[te]!==ee||m[te]!==X||w[te]!==Q)continue;let Le=e[A[te]].m,ve=!0;for(let de=0;de<12;de++)if(Le[de]!==E[de]){ve=!1;break}if(ve){fe=te;break}}if(fe>=0){let K=n?n[T]:0;if(n&&K<n[A[fe]])b[fe]=A[fe],A[fe]=T;else if(b[fe]<0||n&&K<n[b[fe]])b[fe]=T;continue}let ie=u++;h[ie]=z,g[ie]=j,p[ie]=ee,m[ie]=X,A[ie]=T,b[ie]=-1,w.push(Q),d[ie]=I[0],x[ie]=I[2],v[ie]=G;let pe=ie*9;if(M[pe]=E[0],M[pe+1]=E[1],M[pe+2]=E[2],M[pe+3]=E[3],M[pe+4]=E[6],M[pe+5]=E[9],M[pe+6]=E[5],M[pe+7]=E[8],M[pe+8]=E[11],U[ie]=Q.full&&I[3]-I[0]<=20*Q.nx&&I[5]-I[2]<=20*Q.nz&&E[4]===0&&E[6]===0&&E[8]===0&&E[10]===0&&Wn(E[3],E[5],E[9],E[11])?1:0,R+Te>r){R=r+1;continue}for(let K=ge;K<=re;K++)for(let ae=se;ae<=oe;ae++){if(!Fe(G,K,ae))continue;let te=R++;y[te]=ie,D[te]=S.put(G,K,ae,te)}}if(R>r)return Jt=C,null;let F=[0,5,-5,5,-5],B=[0,5,5,-5,-5],L=(T,P,E,N)=>{if(!(P-6>=h[T]-0.5&&P+6<=g[T]+0.5&&N-6>=p[T]-0.5&&N+6<=m[T]+0.5))return!1;if(U[T]===1)return!0;let I=T*9,z=w[T],j=d[T],ee=x[T],X=P-M[I],G=E-M[I+1],Q=N-M[I+2],ce=M[I+3]*X+M[I+4]*G+M[I+5]*Q,we=M[I+6]*X+M[I+7]*G+M[I+8]*Q,{nx:Ae,nz:Me,mask:ge}=z;for(let re=0;re<5;re++){let se=Math.floor((ce+F[re]-j)/20),oe=Math.floor((we+B[re]-ee)/20);if(se<0||oe<0||se>=Ae||oe>=Me||ge[se*Me+oe]!==1)return!1}return!0},V=NaN,me=NaN,be=NaN,ye=-1,ue=-1,Pe=(T,P,E,N)=>{let I=Math.round(P*2),z=Math.floor(T/40),j=Math.floor(E/40);if(!Fe(I,z,j))return Ue;let ee=Ue;if(!n&&ue>=0&&v[ue]===I&&(A[ue]!==N||b[ue]>=0)&&L(ue,T,P,E))return 0;if(I!==V||z!==me||j!==be)V=I,me=z,be=j,ye=S.get(I,z,j);for(let X=ye;X>=0;X=D[X]){let G=y[X],Q=A[G];if(Q===N&&(Q=b[G])<0)continue;if(!L(G,T,P,E))continue;if(!n)return ue=G,0;let ce=n[Q];if(ce<ee)ee=ce}return ee},xe=new Uint8Array(l),Ce=new Uint8Array(l),ke=0,he=n?new Ee(l,4):null,O=n?null:new Int32Array(l),k=n?null:new Int32Array(l),J=n?null:new Int32Array(l),_=0,W=n?new Int32Array(l).fill(Ue):void 0;for(let T=0,P=0;T<e.length;T++){let E=e[T],N=f[T];if(!N)continue;let I=E.m,z=N.studM,j=I[0],ee=I[1],X=I[2],G=I[3],Q=I[4],ce=I[5],we=I[6],Ae=I[7],Me=I[8],ge=I[9],re=I[10],se=I[11];for(let oe=0;oe<N.nStuds;oe++,P++){let Te=oe*12,fe=z[Te+4],ie=z[Te+7],pe=z[Te+10];if(!(Math.abs(we*fe+Ae*ie+Me*pe-1)<0.001&&Math.abs(G*fe+Q*ie+ce*pe)<0.001&&Math.abs(ge*fe+re*ie+se*pe)<0.001))continue;Ce[P]=1;let K=z[Te],ae=z[Te+1],te=z[Te+2],Le=j+G*K+Q*ae+ce*te,ve=ee+we*K+Ae*ae+Me*te,de=X+ge*K+re*ae+se*te,gt=Pe(Le,ve,de,T);if(gt!==Ue){if(xe[P]=1,ke++,W)W[P]=gt}let Ne=Math.round(Le),Oe=Math.round(ve),ze=Math.round(de);if(!Fe(Ne,Oe,ze))continue;if(!he){O[_]=Ne,k[_]=Oe,J[_++]=ze;continue}let dt=n[T],bt=he.get(Ne,Oe,ze);if(bt<0||dt<bt)he.put(Ne,Oe,ze,dt)}}let ne=he?null:new Yt(O,k,J,_),q=new Uint8Array(e.length),le=n?new Int32Array(e.length).fill(Ue):void 0;for(let T=0;T<e.length;T++){let P=e[T],E=t.parts[P.part];if(!E||!E.under||!Xt(P.m)||i(P.color))continue;let N=E.bbox,I=Math.round((N[3]-N[0])/20),z=Math.round((N[5]-N[2])/20);if(!I||!z||I*z>4096)continue;let j=P.m,ee=Math.round(j[1]+N[4]),X=!0,G=0;for(let Q=0;Q<I&&X;Q++)for(let ce=0;ce<z;ce++){let we=N[0]+10+20*Q,Ae=N[2]+10+20*ce,Me=j[0]+j[3]*we+j[5]*Ae,ge=j[2]+j[9]*we+j[11]*Ae,re=Math.round(Me),se=Math.round(ge),oe=!Fe(re,ee,se)?-1:he?he.get(re,ee,se):ne.has(re,ee,se)?1:-1;if(oe<0){X=!1;break}if(oe>G)G=oe}if(X){if(q[T]=1,le)le[T]=G}}return{nStuds:l,studHidden:xe,studUp:Ce,underHidden:q,studsHidden:ke,studHideStep:W,underHideStep:le}}function ht(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let f=l.colour;if(!f)return String(l.color);let h=o.get(f);if(h!==void 0)return h;let g=t.colorTable?.[l.color],p=g?.hex??t.colors?.[l.color],m=g?ct({alpha:g.alpha??255,luminance:g.luminance??0,finish:g.finish??{type:"default"}}):"default:op",A=ct(f);if(h=p&&p.toUpperCase()===f.hex.toUpperCase()&&m===A?String(l.color):f.hex.toUpperCase()+"/"+A,h!==String(l.color))s.set(h,f);return o.set(f,h),h},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),{stepOf:a,nSteps:u}=Kn(c);return{all:c,stepOf:a,nSteps:u,localColours:s}}function Kn(e){let t=!0;for(let o=0;o<e.length;o++){let i=e[o].steps;if(i.length!==1){t=!1;break}let c=i[0];if(!(Number.isInteger(c)&&c>=0&&c<1e6)){t=!1;break}}if(t){let o=new Set;for(let a=0;a<e.length;a++)o.add(e[a].steps[0]);let i=[...o].sort((a,u)=>a-u),c=new Map(i.map((a,u)=>[a,u]));return{stepOf:e.map((a)=>c.get(a.steps[0])),nSteps:i.length}}let n=e.map((o)=>_t(o.steps)),r=[...new Set(n)].sort(),s=new Map(r.map((o,i)=>[o,i]));return{stepOf:n.map((o)=>s.get(o)),nSteps:r.length}}function Qt(e,t,n=!0){let r=ht(e,t,n);return mt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Ke="https://ldr-parts-cdn.baconbrix.workers.dev/v1/",He=new Map,Ge=new Map;function We(e=Ke,t=fetch){let n=He.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(()=>He.delete(e)),He.set(e,n);return n}var Zn=(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"),Xe=(e,t)=>Zn(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Xe(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Xe(r,t)])):e;function Yn(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let g=h.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let p=new DataView(g).getUint32(0,!0),m=new Uint8Array(g,4+p),A=r;n.push(m),r+=m.byteLength;let b=(4-r%4)%4;if(b)n.push(new Uint8Array(b)),r+=b;for(let[d,x]of Object.entries(h.header.parts??{}))if(!(d in s))s[d]=Xe(x,A);for(let[d,x]of Object.entries(h.header.studKinds??{}))if(!(d in o))o[d]=Xe(x,A)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+c.length)%4)%4,u=4+c.length+a,l=new Uint8Array(u+r);new DataView(l.buffer).setUint32(0,c.length+a,!0),l.set(c,4),l.fill(32,4+c.length,u);let f=u;for(let h of n)l.set(h,f),f+=h.byteLength;return _e(l.buffer)}async function Jn(e,t={}){e=[...e];try{return await qt(e,t)}catch(n){let r=t.cdn??Ke,s=t.fetch??fetch;He.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await qt(e,{...t,fetch:o})}catch{throw n}}}async function qt(e,t){let n=t.cdn??Ke,r=t.fetch??fetch,s=t.gap??16384,o=await We(n,r),i=[...new Set([...new Set(e)].map(Y))],c=[],a=[];for(let d of i){if(Ge.has(n+d))continue;let x=o.parts[d];if(x)a.push({name:d,off:x[0],len:x[1],file:x[2]??0});else c.push(d)}a.sort((d,x)=>d.file-x.file||d.off-x.off);let u=[];for(let d of a){let x=u[u.length-1];if(x&&x.file===d.file&&d.off-x.end<=s)x.end=Math.max(x.end,d.off+d.len),x.items.push(d);else u.push({file:d.file,start:d.off,end:d.off+d.len,items:[d]})}let l=0,f=0,h=0,g=new Map,p=async()=>{while(h<u.length){let d=u[h++],x=g.get(d.file);if(x)x=x.subarray(d.start,d.end);else{let w=await r(new URL(o.archives[d.file],n).href,{headers:{Range:`bytes=${d.start}-${d.end-1}`,"Accept-Encoding":"identity"}});if(!w.ok)throw Error(`ldr: parts CDN ${w.status}`);if(f++,x=new Uint8Array(await w.arrayBuffer()),l+=x.byteLength,w.status===200)g.set(d.file,x),x=x.subarray(d.start,d.end)}for(let w of d.items){let v=Ve(x.subarray(w.off-d.start,w.off-d.start+w.len)),M=v.buffer.slice(v.byteOffset,v.byteOffset+v.byteLength);Ge.set(n+w.name,_e(M))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,u.length)},p));let m=i.filter((d)=>Ge.has(n+d)).map((d)=>Ge.get(n+d)),A={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:m.length?Yn(m,A):_e(Qn(A)),missing:c,requests:f,bytes:l}}function Qn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function qn(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function en(e,t,n){let r=0,s=0,o=!1,i=new Set,c=new Map;for(let a of e){let u;if(a.embedded)u=t.get(a.part);else if(u=c.get(a.part),u===void 0)c.set(a.part,u=Y(a.part));let l=u?n.parts[u]:void 0;if(!l)continue;if(l[3]!=null)o=!0,r+=l[3];if(!i.has(u))i.add(u),s+=l[1]}return{bodyTris:r,packBytes:s,known:o}}class Ze extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function tn(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=We(t.cdn??Ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(y)=>{if(!y.ok)throw Error(`ldr: ${y.status} fetching ${e}`);return wt(await y.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":At(e)),a=Ht(o,c,{looseGeometry:!1,callouts:t.callouts}),u=performance.now();t.onParsed?.(a),await s;let l=Wt(o,new Set(a.filter((y)=>y.embedded).map((y)=>y.part)),c),f=(y,R)=>t.maxBodyTris!=null&&y>t.maxBodyTris||t.maxPackBytes!=null&&R>t.maxPackBytes,h=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(y)=>new Ze({...y,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),p="full";if(h){let y=en(a,l,await s);if(f(y.known?y.bodyTris:0,y.packBytes)){if(!t.lowCdn)throw g(y);let R=await We(t.lowCdn,r).catch(()=>null);if(!R)throw g(y);let C=en(a,l,R);if(f(C.known?C.bodyTris:0,C.packBytes))throw g(C);p="low"}}let m=[...a.filter((y)=>!y.embedded).map((y)=>y.part),...l.values()],A=async()=>{let y=await Jn(m,p==="low"?{...t,cdn:t.lowCdn}:t);for(let[R,C]of l){let F=y.pack.header.parts[C];if(F)y.pack.header.parts[R]=F}return{...y,packBytes:y.pack.buffer?.byteLength??y.pack.bytes??0,bodyTris:qn(a,y.pack)}},b=await A();if(h&&f(b.bodyTris,b.packBytes)&&p==="full"&&t.lowCdn&&await We(t.lowCdn,r).then(()=>!0,()=>!1)){p="low";let y=b;b=await A(),b.requests+=y.requests,b.bytes+=y.bytes}if(h&&f(b.bodyTris,b.packBytes))throw g(b);let{pack:d,missing:x,requests:w,bytes:v}=b,M=new Map([...l].map(([y,R])=>[R,y])),U=x.map((y)=>M.get(y)??y),S=performance.now(),D=t.cull?Qt(a,d.header,t.textures!==!1):void 0;return{insts:a,pack:d,tier:p,missing:U,requests:w,bytes:v,cull:D,timings:{fetchModel:i-n,parse:u-i,parts:S-u,...D?{cull:performance.now()-S}:{}}}}var er=new Set(["part","color","m","step","steps","localStep","path"]);function nn(e){let t=e.length,n=0;for(let p of e){if(typeof p.part!=="string"||typeof p.path!=="string"||typeof p.color!=="number"||typeof p.step!=="number"||typeof p.localStep!=="number"||!Array.isArray(p.m)||p.m.length!==12||!Array.isArray(p.steps))return null;n+=p.steps.length}let r=[],s=new Map,o=(p)=>{let m=s.get(p);if(m===void 0)s.set(p,m=r.length),r.push(p);return m},i=new Uint32Array(t),c=new Uint32Array(t),a=new Float64Array(t*3),u=new Float64Array(t*12),l=new Uint32Array(t+1),f=new Float64Array(n),h=[],g=0;for(let p=0;p<t;p++){let m=e[p];i[p]=o(m.part),c[p]=o(m.path),a[p*3]=m.color,a[p*3+1]=m.step,a[p*3+2]=m.localStep;let A=m.m,b=p*12;for(let w=0;w<12;w++)u[b+w]=A[w];let d=m.steps;for(let w=0;w<d.length;w++)f[g++]=d[w];l[p+1]=g;let x=null;for(let w in m)if(!er.has(w))(x??={})[w]=m[w];if(x)h.push([p,x])}return{n:t,strs:r,part:i,path:c,num:a,m:u,so:l,steps:f,extra:h}}var rn=(e)=>[e.part.buffer,e.path.buffer,e.num.buffer,e.m.buffer,e.so.buffer,e.steps.buffer];self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await tn(n,{...r,cull:!1,onParsed:(f)=>{let h=nn(f);if(h)self.postMessage({id:t,packed:h},rn(h));else self.postMessage({id:t,insts:f})}}),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=ht(s.insts,s.pack.header,r.textures!==!1),a=mt(c.all,s.pack.header,r.stepCull&&c.nSteps>1?c.stepOf:void 0),u=performance.now()-i,l=[];for(let f of[a.studHidden,a.studUp,a.underHidden,a.studHideStep,a.underHideStep])if(f)l.push(f.buffer);self.postMessage({id:t,cull:a,ms:u},l)}catch(s){if(s instanceof Ze||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
5380
5614
 
5381
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/inst-io.ts
5615
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/inst-io.ts
5382
5616
  var CORE = new Set(["part", "color", "m", "step", "steps", "localStep", "path"]);
5383
5617
  function unpackInstances(p) {
5384
5618
  const { n, strs, part, path, num, m, so, steps, extra } = p;
@@ -5403,7 +5637,7 @@ function unpackInstances(p) {
5403
5637
  return out;
5404
5638
  }
5405
5639
 
5406
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/cdn.ts
5640
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/cdn.ts
5407
5641
  var worker;
5408
5642
  var seq = 0;
5409
5643
  var pending = new Map;
@@ -5452,6 +5686,7 @@ function getWorker() {
5452
5686
  return worker = null;
5453
5687
  }
5454
5688
  }
5689
+ var eagerSteps = (o) => o.step != null || (o.eagerSteps ?? !!o.callouts);
5455
5690
  var abs = (u) => {
5456
5691
  try {
5457
5692
  return new URL(u, globalThis.location?.href).href;
@@ -5461,7 +5696,7 @@ var abs = (u) => {
5461
5696
  };
5462
5697
  function prepareInWorker(w, source, o) {
5463
5698
  const id = ++seq;
5464
- const opts = { cdn: abs(o.cdn ?? DEFAULT_PARTS_CDN), gap: o.gap, concurrency: o.concurrency, text: o.text, name: o.name, cull: true, textures: o.textures, callouts: o.callouts, maxBodyTris: o.maxBodyTris, maxPackBytes: o.maxPackBytes, lowCdn: o.lowCdn && abs(o.lowCdn) };
5699
+ const opts = { cdn: abs(o.cdn ?? DEFAULT_PARTS_CDN), gap: o.gap, concurrency: o.concurrency, text: o.text, name: o.name, cull: true, stepCull: eagerSteps(o), textures: o.textures, callouts: o.callouts, maxBodyTris: o.maxBodyTris, maxPackBytes: o.maxPackBytes, lowCdn: o.lowCdn && abs(o.lowCdn) };
5465
5700
  const name = o.name ?? (o.text ? undefined : modelFileName(source));
5466
5701
  let insts;
5467
5702
  pendingInsts.set(id, (v) => {
@@ -5502,7 +5737,8 @@ async function loadModel(source, o = {}) {
5502
5737
  } else
5503
5738
  prep = await prepareModel(source, o);
5504
5739
  const t3 = performance.now();
5505
- const obj = await createLdrObjectAsync(prep.insts, prep.pack, prep.cull ? { ...o, precomputedCull: prep.cull } : o);
5740
+ const oo = { ...o, eagerSteps: eagerSteps(o) };
5741
+ const obj = await createLdrObjectAsync(prep.insts, prep.pack, prep.cull ? { ...oo, precomputedCull: prep.cull } : oo);
5506
5742
  for (const m of prep.missing)
5507
5743
  if (!obj.stats.missing.includes(m))
5508
5744
  obj.stats.missing.push(m);
@@ -5517,7 +5753,7 @@ async function loadModel(source, o = {}) {
5517
5753
  timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
5518
5754
  });
5519
5755
  }
5520
- // ../../../../../../../tmp/ldr-build-VjJ0ZB/src/usdz.ts
5756
+ // ../../../../../../../tmp/ldr-build-vpoU1w/src/usdz.ts
5521
5757
  var IDENT = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1];
5522
5758
  var MAX_ERR = 8;
5523
5759
  var REL_ERR = 0.1;
@@ -6222,6 +6458,7 @@ export {
6222
6458
  smoothNormals,
6223
6459
  stepKey,
6224
6460
  stepViewMatrix,
6461
+ studDecalUniforms,
6225
6462
  texWrapper,
6226
6463
  texmapTriangleUV,
6227
6464
  texmapUV,