ldr 0.33.6 → 0.33.8
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/README.md +1 -1
- package/dist/cli.js +18 -12
- package/dist/index.js +179 -24
- package/dist/node/index.js +194 -33
- package/dist/render.d.ts +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -139,7 +139,7 @@ MPD-embedded parts, such as Studio/OMR unofficial parts or stickers, become part
|
|
|
139
139
|
| `ldrawSpace` | `false` | `true` keeps native LDraw space (-Y up). |
|
|
140
140
|
| `scale` | `1` | Uniform scale (1 = 1 LDU; 1 stud = 20 LDU). |
|
|
141
141
|
| `step` | all | Initial build step (inclusive, 0-based). |
|
|
142
|
-
| `lod` | `true` | Distance LOD, re-selected for each camera you render with. Batches are split into spatial clusters (off-screen ones are frustum-culled). Each cluster draws the coarsest simplified mesh (from `lod` packs) whose error stays under `lodPx`, swaps closed studs to a 10-triangle square stud (with a square outline) then a flat disc, and drops them once their 12-LDU disc is under `lodPx`, and hides edges where a stud spans less than `lodEdgePx`. |
|
|
142
|
+
| `lod` | `true` | Distance LOD, re-selected for each camera you render with. Batches are split into spatial clusters (off-screen ones are frustum-culled). Each cluster draws the coarsest simplified mesh (from `lod` packs) whose error stays under `lodPx`, swaps closed studs to a 10-triangle square stud and open (hollow) studs to a 24-triangle square stud with a square hole (each with a square outline), then a flat disc, and drops them once their 12-LDU disc is under `lodPx`, and hides edges where a stud spans less than `lodEdgePx`. |
|
|
143
143
|
| `lodPx` | `0.5` | LOD: maximum screen-space error in pixels. |
|
|
144
144
|
| `lodEdgePx` | `0.5` | LOD: draw edge and conditional lines only where one stud (20 LDU) spans at least this many pixels. `0` = always. |
|
|
145
145
|
| `lodEdgeMinPx` | `0.4` | LOD: draw only edge segments at least this many pixels long on screen. `0` = every segment. |
|
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ../../../../../../../tmp/ldr-build-
|
|
3
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cli.ts
|
|
4
4
|
import fs4 from "node:fs";
|
|
5
5
|
import zlib from "node:zlib";
|
|
6
6
|
|
|
7
|
-
// ../../../../../../../tmp/ldr-build-
|
|
7
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/build-pack.ts
|
|
8
8
|
import fs3 from "node:fs";
|
|
9
9
|
import path3 from "node:path";
|
|
10
10
|
|
|
11
|
-
// ../../../../../../../tmp/ldr-build-
|
|
11
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/resolver.ts
|
|
12
12
|
import fs from "node:fs";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
|
|
15
|
-
// ../../../../../../../tmp/ldr-build-
|
|
15
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/spec.ts
|
|
16
16
|
var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
17
17
|
var COLOUR_ID_RE = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
18
18
|
var namedCodes = new Map;
|
|
@@ -817,7 +817,7 @@ function fileStepViews(f) {
|
|
|
817
817
|
return out;
|
|
818
818
|
}
|
|
819
819
|
|
|
820
|
-
// ../../../../../../../tmp/ldr-build-
|
|
820
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/model.ts
|
|
821
821
|
class ModelLimitError extends Error {
|
|
822
822
|
limit;
|
|
823
823
|
code = "ldr-model-limit";
|
|
@@ -1259,7 +1259,7 @@ function blendedColourHex(code) {
|
|
|
1259
1259
|
return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1260
1260
|
}
|
|
1261
1261
|
|
|
1262
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1262
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/resolver.ts
|
|
1263
1263
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
1264
1264
|
var UNDER_STUD_RE = /^(stud3|stud3a|stud4.*|stud12|stud16.*|stud18a)\.dat$/i;
|
|
1265
1265
|
var norm2 = (ref) => ref.trim().replace(/\\/g, "/").toLowerCase();
|
|
@@ -1586,11 +1586,11 @@ function collectDeps(lib, refs) {
|
|
|
1586
1586
|
return out;
|
|
1587
1587
|
}
|
|
1588
1588
|
|
|
1589
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1589
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/compile.ts
|
|
1590
1590
|
import fs2 from "node:fs";
|
|
1591
1591
|
import path2 from "node:path";
|
|
1592
1592
|
|
|
1593
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1593
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/lod.ts
|
|
1594
1594
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
1595
1595
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
1596
1596
|
function reorderMesh(P, N, C, I) {
|
|
@@ -1613,7 +1613,7 @@ function reorderMesh(P, N, C, I) {
|
|
|
1613
1613
|
}
|
|
1614
1614
|
return { P: P2, N: N2, C: C2, I: idx };
|
|
1615
1615
|
}
|
|
1616
|
-
var TARGETS = [0.25, 0.
|
|
1616
|
+
var TARGETS = [0.25, 0.16, 0.1, 0.065, 0.04, 0.025];
|
|
1617
1617
|
var HALF = 0.4;
|
|
1618
1618
|
var HALF_ERR_SCALE = 1.5;
|
|
1619
1619
|
var MIN_TRIS = 64;
|
|
@@ -1793,10 +1793,16 @@ function lodChain(P, C, I, half = false) {
|
|
|
1793
1793
|
out.unshift(h);
|
|
1794
1794
|
}
|
|
1795
1795
|
}
|
|
1796
|
+
for (let i = out.length - 2, min = out.length ? out[out.length - 1].err : 0;i >= 0; i--) {
|
|
1797
|
+
if (out[i].err >= min)
|
|
1798
|
+
out.splice(i, 1);
|
|
1799
|
+
else
|
|
1800
|
+
min = out[i].err;
|
|
1801
|
+
}
|
|
1796
1802
|
return out;
|
|
1797
1803
|
}
|
|
1798
1804
|
|
|
1799
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1805
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/compile.ts
|
|
1800
1806
|
class BfcState {
|
|
1801
1807
|
accum;
|
|
1802
1808
|
ccw = true;
|
|
@@ -2728,7 +2734,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
2728
2734
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
2729
2735
|
}
|
|
2730
2736
|
|
|
2731
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2737
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/build-pack.ts
|
|
2732
2738
|
function packCompilerOpts(o) {
|
|
2733
2739
|
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures, ...o.partWorkLimit ? { workLimit: o.partWorkLimit } : {} };
|
|
2734
2740
|
}
|
|
@@ -2801,7 +2807,7 @@ function buildPack(o) {
|
|
|
2801
2807
|
return { data: encodePack(parts, kinds, comp.opts.weld, extra, { texture, lod: o.lod !== false, reorder: !!o.reorder }), parts: parts.size, studKinds: kinds.size, missing: [...missing], ...warnings.length ? { warnings } : {} };
|
|
2802
2808
|
}
|
|
2803
2809
|
|
|
2804
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2810
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cli.ts
|
|
2805
2811
|
var HELP = `ldr pack — build a parts pack for the ldr three.js renderer
|
|
2806
2812
|
|
|
2807
2813
|
Usage:
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/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;
|
|
@@ -778,7 +778,7 @@ function fileStepViews(f) {
|
|
|
778
778
|
viewMemo.set(f, out);
|
|
779
779
|
return out;
|
|
780
780
|
}
|
|
781
|
-
// ../../../../../../../tmp/ldr-build-
|
|
781
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/model.ts
|
|
782
782
|
class ModelLimitError extends Error {
|
|
783
783
|
limit;
|
|
784
784
|
code = "ldr-model-limit";
|
|
@@ -1219,7 +1219,7 @@ function blendedColourHex(code) {
|
|
|
1219
1219
|
const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
|
|
1220
1220
|
return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1221
1221
|
}
|
|
1222
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1222
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/instructions.ts
|
|
1223
1223
|
var MIN_VIS = 0.5;
|
|
1224
1224
|
var REORIENT = 0.35;
|
|
1225
1225
|
var deg = Math.PI / 180;
|
|
@@ -1587,10 +1587,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
|
|
|
1587
1587
|
}
|
|
1588
1588
|
};
|
|
1589
1589
|
}
|
|
1590
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1590
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/render.ts
|
|
1591
1591
|
import * as THREE from "three";
|
|
1592
1592
|
|
|
1593
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1593
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/pack-io.ts
|
|
1594
1594
|
import { decompress } from "fzstd";
|
|
1595
1595
|
async function decompressPack(data) {
|
|
1596
1596
|
const u = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -1613,7 +1613,7 @@ function decodePack(buf) {
|
|
|
1613
1613
|
return { header, arr, bytes: buf.byteLength, buffer: buf };
|
|
1614
1614
|
}
|
|
1615
1615
|
|
|
1616
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1616
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cull.ts
|
|
1617
1617
|
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;
|
|
1618
1618
|
var prepCache = new WeakMap;
|
|
1619
1619
|
function prepPart(H, part) {
|
|
@@ -1996,7 +1996,7 @@ function precomputeCull(instances, H, useTex = true) {
|
|
|
1996
1996
|
return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
|
|
1997
1997
|
}
|
|
1998
1998
|
|
|
1999
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1999
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/render.ts
|
|
2000
2000
|
async function loadPack(url) {
|
|
2001
2001
|
const res = await fetch(url);
|
|
2002
2002
|
if (!res.ok)
|
|
@@ -2708,21 +2708,134 @@ function studBoxGeom(w) {
|
|
|
2708
2708
|
_studBox.set(w, g);
|
|
2709
2709
|
return g;
|
|
2710
2710
|
}
|
|
2711
|
+
var _studTube = new Map;
|
|
2712
|
+
function studTubeGeom(w, wi) {
|
|
2713
|
+
const key = w + "," + wi;
|
|
2714
|
+
let g = _studTube.get(key);
|
|
2715
|
+
if (g)
|
|
2716
|
+
return g;
|
|
2717
|
+
const y = -4, s = Math.SQRT1_2;
|
|
2718
|
+
const sq = (h) => [[-h, -h], [h, -h], [h, h], [-h, h]];
|
|
2719
|
+
const C = sq(w), Ci = sq(wi);
|
|
2720
|
+
const pos = [], nrm = [], idx = [];
|
|
2721
|
+
for (const [x, z] of C) {
|
|
2722
|
+
pos.push(x, y, z);
|
|
2723
|
+
nrm.push(0, -1, 0);
|
|
2724
|
+
}
|
|
2725
|
+
for (const [x, z] of Ci) {
|
|
2726
|
+
pos.push(x, y, z);
|
|
2727
|
+
nrm.push(0, -1, 0);
|
|
2728
|
+
}
|
|
2729
|
+
for (const [x, z] of C) {
|
|
2730
|
+
pos.push(x, y, z, x, 0, z);
|
|
2731
|
+
nrm.push(Math.sign(x) * s, 0, Math.sign(z) * s, Math.sign(x) * s, 0, Math.sign(z) * s);
|
|
2732
|
+
}
|
|
2733
|
+
for (const [x, z] of Ci) {
|
|
2734
|
+
pos.push(x, y, z, x, 0, z);
|
|
2735
|
+
nrm.push(-Math.sign(x) * s, 0, -Math.sign(z) * s, -Math.sign(x) * s, 0, -Math.sign(z) * s);
|
|
2736
|
+
}
|
|
2737
|
+
const tri = (a, b, c, out) => {
|
|
2738
|
+
const P = (i) => pos.slice(i * 3, i * 3 + 3);
|
|
2739
|
+
const [A, B, Cc] = [P(a), P(b), P(c)];
|
|
2740
|
+
const u = [B[0] - A[0], B[1] - A[1], B[2] - A[2]], v = [Cc[0] - A[0], Cc[1] - A[1], Cc[2] - A[2]];
|
|
2741
|
+
const n = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];
|
|
2742
|
+
if (n[0] * out[0] + n[1] * out[1] + n[2] * out[2] < 0)
|
|
2743
|
+
idx.push(a, c, b);
|
|
2744
|
+
else
|
|
2745
|
+
idx.push(a, b, c);
|
|
2746
|
+
};
|
|
2747
|
+
for (let i = 0;i < 4; i++) {
|
|
2748
|
+
const j = (i + 1) % 4;
|
|
2749
|
+
tri(i, j, 4 + j, [0, -1, 0]);
|
|
2750
|
+
tri(i, 4 + j, 4 + i, [0, -1, 0]);
|
|
2751
|
+
const mid = [(C[i][0] + C[j][0]) / 2, 0, (C[i][1] + C[j][1]) / 2];
|
|
2752
|
+
{
|
|
2753
|
+
const ti = 8 + i * 2, bi = ti + 1, tj = 8 + j * 2, bj = tj + 1;
|
|
2754
|
+
tri(ti, tj, bj, mid);
|
|
2755
|
+
tri(ti, bj, bi, mid);
|
|
2756
|
+
}
|
|
2757
|
+
{
|
|
2758
|
+
const ti = 16 + i * 2, bi = ti + 1, tj = 16 + j * 2, bj = tj + 1;
|
|
2759
|
+
const inn = [-mid[0], 0, -mid[2]];
|
|
2760
|
+
tri(ti, tj, bj, inn);
|
|
2761
|
+
tri(ti, bj, bi, inn);
|
|
2762
|
+
}
|
|
2763
|
+
}
|
|
2764
|
+
const nv = pos.length / 3;
|
|
2765
|
+
const col = new Uint8Array(nv * 4);
|
|
2766
|
+
for (let i = 0;i < nv; i++) {
|
|
2767
|
+
col[i * 4] = 255;
|
|
2768
|
+
col[i * 4 + 1] = 255;
|
|
2769
|
+
col[i * 4 + 2] = 255;
|
|
2770
|
+
col[i * 4 + 3] = 0;
|
|
2771
|
+
}
|
|
2772
|
+
g = new THREE.BufferGeometry;
|
|
2773
|
+
g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
|
|
2774
|
+
g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
|
|
2775
|
+
g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
|
|
2776
|
+
g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
|
|
2777
|
+
g.computeBoundingSphere();
|
|
2778
|
+
g.computeBoundingBox();
|
|
2779
|
+
_studTube.set(key, g);
|
|
2780
|
+
return g;
|
|
2781
|
+
}
|
|
2782
|
+
var _hole = new WeakMap;
|
|
2783
|
+
function studHole(b, arr = (r) => r) {
|
|
2784
|
+
if (!b)
|
|
2785
|
+
return null;
|
|
2786
|
+
let v = _hole.get(b);
|
|
2787
|
+
if (v !== undefined)
|
|
2788
|
+
return v;
|
|
2789
|
+
v = null;
|
|
2790
|
+
const p = arr(b.pos);
|
|
2791
|
+
let rin = Infinity, out = Infinity, ok = p.length >= 9;
|
|
2792
|
+
for (let i = 0;i < p.length && ok; i += 3) {
|
|
2793
|
+
const y = p[i + 1], r = Math.hypot(p[i], p[i + 2]);
|
|
2794
|
+
if (y < -4.01 || y > 0.01 || r > 6.02)
|
|
2795
|
+
ok = false;
|
|
2796
|
+
else if (r < 5.8)
|
|
2797
|
+
rin = Math.min(rin, r);
|
|
2798
|
+
else
|
|
2799
|
+
out = Math.min(out, r);
|
|
2800
|
+
}
|
|
2801
|
+
if (ok && rin >= 3.5 && rin <= 4.5) {
|
|
2802
|
+
let top = false, foot = false;
|
|
2803
|
+
for (let i = 0;i < p.length && ok; i += 3) {
|
|
2804
|
+
const r = Math.hypot(p[i], p[i + 2]);
|
|
2805
|
+
if (r >= 5.8)
|
|
2806
|
+
continue;
|
|
2807
|
+
if (r - rin > 0.1)
|
|
2808
|
+
ok = false;
|
|
2809
|
+
else if (Math.abs(p[i + 1] + 4) < 0.01)
|
|
2810
|
+
top = true;
|
|
2811
|
+
else if (Math.abs(p[i + 1]) < 0.01)
|
|
2812
|
+
foot = true;
|
|
2813
|
+
}
|
|
2814
|
+
if (ok && top && foot)
|
|
2815
|
+
v = { r: rin, out };
|
|
2816
|
+
}
|
|
2817
|
+
_hole.set(b, v);
|
|
2818
|
+
return v;
|
|
2819
|
+
}
|
|
2711
2820
|
var _topClosed = new WeakMap;
|
|
2712
|
-
function studSquareLines(E, w) {
|
|
2821
|
+
function studSquareLines(E, w, hole) {
|
|
2713
2822
|
const n = Math.floor(E.length / 6);
|
|
2714
2823
|
if (!n)
|
|
2715
2824
|
return null;
|
|
2716
2825
|
const loops = new Map;
|
|
2826
|
+
const cls = (q) => {
|
|
2827
|
+
const r = Math.hypot(E[q], E[q + 2]);
|
|
2828
|
+
return Math.abs(r - 6) <= 0.02 ? "o" : hole && Math.abs(r - hole.r) <= 0.02 ? "i" : null;
|
|
2829
|
+
};
|
|
2717
2830
|
for (let s = 0;s < n; s++) {
|
|
2718
2831
|
const o = s * 6;
|
|
2719
2832
|
const y0 = E[o + 1], y1 = E[o + 4];
|
|
2720
2833
|
if (Math.abs(y0 - y1) > 0.001)
|
|
2721
2834
|
return null;
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
const k = String(Math.round(y0 * 100) / 100 + 0);
|
|
2835
|
+
const c0 = cls(o);
|
|
2836
|
+
if (!c0 || cls(o + 3) !== c0)
|
|
2837
|
+
return null;
|
|
2838
|
+
const k = String(Math.round(y0 * 100) / 100 + 0) + c0;
|
|
2726
2839
|
const L = loops.get(k) || loops.set(k, { segs: 0, len: 0, deg: new Map }).get(k);
|
|
2727
2840
|
L.segs++;
|
|
2728
2841
|
L.len = Math.max(L.len, Math.hypot(E[o + 3] - E[o], E[o + 5] - E[o + 2]));
|
|
@@ -2738,10 +2851,10 @@ function studSquareLines(E, w) {
|
|
|
2738
2851
|
const C = [[-w, -w], [w, -w], [w, w], [-w, w]];
|
|
2739
2852
|
const pos = new Float32Array(ord.length * 24), lens = new Float32Array(ord.length * 4);
|
|
2740
2853
|
ord.forEach(([yk, L], i) => {
|
|
2741
|
-
const y =
|
|
2854
|
+
const y = parseFloat(yk), h = yk.endsWith("i") ? hole.w / w : 1;
|
|
2742
2855
|
for (let c = 0;c < 4; c++) {
|
|
2743
2856
|
const a = C[c], b = C[(c + 1) % 4];
|
|
2744
|
-
pos.set([a[0], y, a[1], b[0], y, b[1]], (i * 4 + c) * 6);
|
|
2857
|
+
pos.set([a[0] * h, y, a[1] * h, b[0] * h, y, b[1] * h], (i * 4 + c) * 6);
|
|
2745
2858
|
lens[i * 4 + c] = L.len;
|
|
2746
2859
|
}
|
|
2747
2860
|
});
|
|
@@ -2803,11 +2916,44 @@ class LdrLodRoot extends THREE.LOD {
|
|
|
2803
2916
|
apply = () => {};
|
|
2804
2917
|
inv = new THREE.Matrix4;
|
|
2805
2918
|
cp = new THREE.Vector3;
|
|
2919
|
+
lastW = new Float32Array(16).fill(NaN);
|
|
2806
2920
|
constructor() {
|
|
2807
2921
|
super();
|
|
2808
2922
|
this.autoUpdate = true;
|
|
2809
2923
|
}
|
|
2810
2924
|
raycast() {}
|
|
2925
|
+
updateMatrixWorld(force) {
|
|
2926
|
+
if (this.matrixAutoUpdate)
|
|
2927
|
+
this.updateMatrix();
|
|
2928
|
+
let moved = false;
|
|
2929
|
+
if (this.matrixWorldNeedsUpdate || force) {
|
|
2930
|
+
if (this.matrixWorldAutoUpdate) {
|
|
2931
|
+
if (this.parent === null)
|
|
2932
|
+
this.matrixWorld.copy(this.matrix);
|
|
2933
|
+
else
|
|
2934
|
+
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
|
|
2935
|
+
}
|
|
2936
|
+
this.matrixWorldNeedsUpdate = false;
|
|
2937
|
+
const e = this.matrixWorld.elements, l = this.lastW;
|
|
2938
|
+
for (let i = 0;i < 16; i++)
|
|
2939
|
+
if (e[i] !== l[i]) {
|
|
2940
|
+
l[i] = e[i];
|
|
2941
|
+
moved = true;
|
|
2942
|
+
}
|
|
2943
|
+
}
|
|
2944
|
+
const ch = this.children;
|
|
2945
|
+
for (let i = 0, n = ch.length;i < n; i++) {
|
|
2946
|
+
const c = ch[i];
|
|
2947
|
+
if (!c.matrixAutoUpdate && c.children.length === 0) {
|
|
2948
|
+
if (moved || c.matrixWorldNeedsUpdate) {
|
|
2949
|
+
if (c.matrixWorldAutoUpdate)
|
|
2950
|
+
c.matrixWorld.multiplyMatrices(this.matrixWorld, c.matrix);
|
|
2951
|
+
c.matrixWorldNeedsUpdate = false;
|
|
2952
|
+
}
|
|
2953
|
+
} else
|
|
2954
|
+
c.updateMatrixWorld(moved || force);
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2811
2957
|
update(camera) {
|
|
2812
2958
|
if (!this.enabled || !this.clusters.length)
|
|
2813
2959
|
return;
|
|
@@ -3780,8 +3926,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3780
3926
|
cl.studLineLv = 0;
|
|
3781
3927
|
cl.lv.push({ objs: [im], err: 0 });
|
|
3782
3928
|
const discObjs = [];
|
|
3783
|
-
|
|
3784
|
-
|
|
3929
|
+
const sqW = /(^|[\\/])8[\\/]/.test(kind) ? STUD_BOX_W_LOW : 6;
|
|
3930
|
+
const h = studTopClosed(k.body, arr) ? null : studHole(k.body, arr);
|
|
3931
|
+
const hole = h ? { r: h.r, w: h.r * Math.sqrt(Math.PI) / 2 } : undefined;
|
|
3932
|
+
if (LOD && (hole || studTopClosed(k.body, arr)) && (im.geometry.getIndex()?.count ?? im.geometry.getAttribute("position").count) > 30) {
|
|
3933
|
+
const box = new THREE.InstancedMesh(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), im.material, 0);
|
|
3785
3934
|
box.userData = { ldrStud: true, ldrLod: true };
|
|
3786
3935
|
box.instanceMatrix = im.instanceMatrix;
|
|
3787
3936
|
box.count = im.count;
|
|
@@ -3791,7 +3940,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3791
3940
|
box.onBeforeRender = trackVp;
|
|
3792
3941
|
root.add(box);
|
|
3793
3942
|
discObjs.push(box);
|
|
3794
|
-
cl.lv.push({ objs: [box], err: STUD_BOX_ERR });
|
|
3943
|
+
cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, 6 * Math.SQRT2 - h.out) : STUD_BOX_ERR });
|
|
3795
3944
|
cl.studLineLv = 1;
|
|
3796
3945
|
}
|
|
3797
3946
|
if (LOD) {
|
|
@@ -3812,7 +3961,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3812
3961
|
const round = addLines(k.edges, im, cl);
|
|
3813
3962
|
let sq = cl.studLineLv === 1 && round ? sqLineKey.get(kind) : null;
|
|
3814
3963
|
if (sq === undefined) {
|
|
3815
|
-
const r = studSquareLines(arr(k.edges),
|
|
3964
|
+
const r = studSquareLines(arr(k.edges), sqW, hole);
|
|
3816
3965
|
sqLineKey.set(kind, sq = r && { sq: r });
|
|
3817
3966
|
}
|
|
3818
3967
|
if (sq && round) {
|
|
@@ -4004,6 +4153,12 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
4004
4153
|
insts = null;
|
|
4005
4154
|
cull = null;
|
|
4006
4155
|
byPart.clear();
|
|
4156
|
+
for (const o of root.children)
|
|
4157
|
+
if (o.children.length === 0) {
|
|
4158
|
+
o.updateMatrix();
|
|
4159
|
+
o.matrixAutoUpdate = false;
|
|
4160
|
+
o.matrixWorldNeedsUpdate = true;
|
|
4161
|
+
}
|
|
4007
4162
|
return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, box, texturesReady, trimmed };
|
|
4008
4163
|
}
|
|
4009
4164
|
function buildLdrScene(insts, pack, P, color, mark) {
|
|
@@ -4082,7 +4237,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
|
|
|
4082
4237
|
await new Promise((r) => setTimeout(r, 0));
|
|
4083
4238
|
}
|
|
4084
4239
|
}
|
|
4085
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4240
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/scene.ts
|
|
4086
4241
|
import * as THREE2 from "three";
|
|
4087
4242
|
var _box = new THREE2.Box3;
|
|
4088
4243
|
var _m4 = new THREE2.Matrix4;
|
|
@@ -4437,10 +4592,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
|
|
|
4437
4592
|
return finish();
|
|
4438
4593
|
})();
|
|
4439
4594
|
}
|
|
4440
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4595
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/parts-cdn.ts
|
|
4441
4596
|
import { decompress as decompress2 } from "fzstd";
|
|
4442
4597
|
|
|
4443
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4598
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/embedded.ts
|
|
4444
4599
|
function splitFiles(text, fallback) {
|
|
4445
4600
|
const files = new Map;
|
|
4446
4601
|
let cur = null, saw = false, skip = false;
|
|
@@ -4515,7 +4670,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
|
|
|
4515
4670
|
return out;
|
|
4516
4671
|
}
|
|
4517
4672
|
|
|
4518
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4673
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/parts-cdn.ts
|
|
4519
4674
|
var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
|
|
4520
4675
|
var indexCache = new Map;
|
|
4521
4676
|
var shardCache = new Map;
|
|
@@ -4769,10 +4924,10 @@ async function prepareModel(source, o = {}) {
|
|
|
4769
4924
|
return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
|
|
4770
4925
|
}
|
|
4771
4926
|
|
|
4772
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4927
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/load-worker.gen.ts
|
|
4773
4928
|
var load_worker_gen_default = 'var Ft=ArrayBuffer,ee=Uint8Array,we=Uint16Array,Rt=Int16Array;var Me=Int32Array,Ie=function(e,t,n){if(ee.prototype.slice)return ee.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new ee(n-t);return r.set(e.subarray(t,n)),r},he=function(e,t,n,r){if(ee.prototype.fill)return ee.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},Bt=function(e,t,n,r){if(ee.prototype.copyWithin)return ee.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var Dt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],te=function(e,t,n){var r=Error(t||Dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,te);if(!n)throw r;return r},Qe=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Ut=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ot=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)te(0);var u=6-s,f=i==3?4:i,a=Qe(e,u,f);u+=f;var l=c?1<<c:s,m=Qe(e,u,l)+(c==1&&256),g=m;if(!s){var d=1<<10+(e[5]>>3);g=d+(d>>3)*(e[5]&7)}if(g>2145386496)te(1);var b=new ee((t==1?m||g:t?0:g)+12);return b[0]=1,b[4]=4,b[8]=8,{b:u+l,y:0,l:0,d:a,w:t&&t!=1?t:b.subarray(12),e:g,o:new Me(b.buffer,0,3),u:m,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return Ut(e,4)+8;te(0)},le=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ge=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)te(3);var o=1<<s,i=o,c=-1,u=-1,f=-1,a=o,l=new Ft(512+(o<<2)),m=new Rt(l,0,256),g=new we(l,0,256),d=new we(l,512,o),b=512+(o<<1),C=new ee(l,b,o),A=new ee(l,b+o);while(c<255&&i>0){var p=le(i+1),h=r>>3,M=(1<<p+1)-1,D=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(r&7)&M,v=(1<<p)-1,L=M-i-1,R=D&v;if(R<L)r+=p,D=R;else if(r+=p+1,D>v)D-=L;if(m[++c]=--D,D==-1)i+=D,C[--a]=c;else i-=D;if(!D)do{var T=r>>3;u=(e[T]|e[T+1]<<8)>>(r&7)&3,r+=2,c+=u}while(u==3)}if(c>255||i)te(0);var x=0,w=(o>>1)+(o>>3)+3,E=o-1;for(var z=0;z<=c;++z){var k=m[z];if(k<1){g[z]=-k;continue}for(f=0;f<k;++f){C[x]=z;do x=x+w&E;while(x>=a)}}if(x)te(0);for(f=0;f<o;++f){var P=g[C[f]]++,Y=A[f]=s-le(P);d[f]=(P<<Y)-o}return[r+7>>3,{b:s,s:C,n:A,t:d}]},Nt=function(e,t){var n=0,r=-1,s=new ee(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),u=new we(s.buffer,268);if(o<128){var f=ge(e,t+1,6),a=f[0],l=f[1];t+=o;var m=a<<3,g=e[t];if(!g)te(0);var d=0,b=0,C=l.b,A=C,p=(++t<<3)-8+le(g);for(;;){if(p-=C,p<m)break;var h=p>>3;if(d+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<C)-1,i[++r]=l.s[d],p-=A,p<m)break;h=p>>3,b+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<A)-1,i[++r]=l.s[b],C=l.n[d],d=l.t[d],A=l.n[b],b=l.t[b]}if(++r>255)te(0)}else{r=o-127;for(;n<r;n+=2){var M=e[++t];i[n]=M>>4,i[n+1]=M&15}++t}var D=0;for(n=0;n<r;++n){var v=i[n];if(v>11)te(0);D+=v&&1<<v-1}var L=le(D)+1,R=1<<L,T=R-D;if(T&T-1)te(0);i[r++]=le(T)+1;for(n=0;n<r;++n){var v=i[n];++c[i[n]=v&&L+1-v]}var x=new ee(R<<1),w=x.subarray(0,R),E=x.subarray(R);u[L]=0;for(n=L;n>0;--n){var z=u[n];he(E,n,z,u[n-1]=z+c[n]*(1<<L-n))}if(u[0]!=R)te(0);for(n=0;n<r;++n){var k=i[n];if(k){var P=u[k];he(w,n,P,u[k]=P+(1<<L-k))}}return[t,{n:E,b:L,s:w}]},zt=ge(new ee([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],$t=ge(new ee([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],jt=ge(new ee([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],qe=function(e,t){var n=e.length,r=new Me(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Fe=new ee(new Me([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),Vt=qe(Fe,0),Re=new ee(new Me([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),_t=qe(Re,3),me=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)te(0);var u=0,f=n.b,a=(r<<3)-8+le(o)-f,l=-1;for(;a>c&&l<s;){var m=a>>3,g=(e[m]|e[m+1]<<8|e[m+2]<<16)>>(a&7);u=(u<<f|g)&i,t[++l]=n.s[u],a-=f=n.n[u]}if(a!=c||l+1!=s)te(0)},Ht=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;me(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),me(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),me(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),me(e.subarray(r),t.subarray(c),n)},Gt=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,u=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return he(n,e[s],t.y,t.y+=c),n;return he(new ee(c),e[s])}if(u>e.length)return;if(i==0){if(t.b=u,n)return n.set(e.subarray(s,u),t.y),t.y+=c,n;return Ie(e,s,u)}if(i==2){var f=e[s],a=f&3,l=f>>2&3,m=f>>4,g=0,d=0;if(a<2)if(l&1)m|=e[++s]<<4|(l&2&&e[++s]<<12);else m=f>>3;else if(d=l,l<2)m|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(l==2)m|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else m|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new ee(t.m),C=b.length-m;if(a==0)b.set(e.subarray(s,s+=m),C);else if(a==1)he(b,e[s++],C);else{var A=t.h;if(a==2){var p=Nt(e,s);g+=s-(s=p[0]),t.h=A=p[1]}else if(!A)te(0);(d?Ht:me)(e.subarray(s,s+=g),b.subarray(C),A)}var h=e[s++];if(h){if(h==255)h=(e[s++]|e[s++]<<8)+32512;else if(h>127)h=h-128<<8|e[s++];var M=e[s++];if(M&3)te(0);var D=[$t,jt,zt];for(var v=2;v>-1;--v){var L=M>>(v<<1)+2&3;if(L==1){var R=new ee([0,0,e[s++]]);D[v]={s:R.subarray(2,3),n:R.subarray(0,1),t:new we(R.buffer,0,1),b:0}}else if(L==2)r=ge(e,s,9-(v&1)),s=r[0],D[v]=r[1];else if(L==3){if(!t.t)te(0);D[v]=t.t[v]}}var T=t.t=D,x=T[0],w=T[1],E=T[2],z=e[u-1];if(!z)te(0);var k=(u<<3)-8+le(z)-E.b,P=k>>3,Y=0,I=(e[P]|e[P+1]<<8)>>(k&7)&(1<<E.b)-1;P=(k-=w.b)>>3;var j=(e[P]|e[P+1]<<8)>>(k&7)&(1<<w.b)-1;P=(k-=x.b)>>3;var H=(e[P]|e[P+1]<<8)>>(k&7)&(1<<x.b)-1;for(++h;--h;){var Z=E.s[I],O=E.n[I],G=x.s[H],K=x.n[H],J=w.s[j],Q=w.n[j];P=(k-=J)>>3;var S=1<<J,y=S+((e[P]|e[P+1]<<8|e[P+2]<<16|e[P+3]<<24)>>>(k&7)&S-1);P=(k-=Re[G])>>3;var B=_t[G]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Re[G])-1);P=(k-=Fe[Z])>>3;var _=Vt[Z]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Fe[Z])-1);if(P=(k-=O)>>3,I=E.t[I]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<O)-1),P=(k-=K)>>3,H=x.t[H]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<K)-1),P=(k-=Q)>>3,j=w.t[j]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<Q)-1),y>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=y-=3;else{var W=y-(_!=0);if(W){if(y=W==3?t.o[0]-1:t.o[W],W>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=y}else y=t.o[0]}for(var v=0;v<_;++v)b[Y+v]=b[C+v];Y+=_,C+=_;var X=Y-y;if(X<0){var N=-X,q=t.e+X;if(N>B)N=B;for(var v=0;v<N;++v)b[Y+v]=t.w[q+v];Y+=N,B-=N,X=0}for(var v=0;v<B;++v)b[Y+v]=b[X+v];Y+=B}if(Y!=C)while(C<b.length)b[Y++]=b[C++];else Y=b.length;if(n)t.y+=Y;else b=Ie(b,0,Y)}else if(n){if(t.y+=m,C)for(var v=0;v<m;++v)b[v]=b[C+v]}else if(C)b=Ie(b,C);return t.b=u,b}te(2)},Wt=function(e,t){if(e.length==1)return e[0];var n=new ee(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function Ae(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Ot(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var c=Gt(e,i,t);if(!c)te(5);if(t)i.e=i.y;else n.push(c),o+=c.length,Bt(i.w,0,c.length),i.w.set(c,i.w.length-c.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return Wt(n,o)}async function Kt(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(Ae(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function et(e){return new TextDecoder().decode(await Kt(e))}var tt=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function ve(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var ne=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),De=/^[A-Za-z][A-Za-z0-9_]*$/,Be=new Map;function Ue(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!Be.has(r))Be.set(r,t);return r}function Oe(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&De.test(e))return Ue(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var nt=/^~?\\s*moved\\s+to\\s+(.+)$/i,Xt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Zt=new Set(["FILE","NOFILE","!DATA"]),ut=1000000000000000,ft=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Yt=new Set(["model","submodel","configuration"]),Jt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function rt(e){let t=Jt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return ft.has(n)||Yt.has(n)?n:void 0}function Qt(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function qt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((l)=>Number.isFinite(l)&&Math.abs(l)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let l=0;l<s;l++)c=c.replace(/^\\S+\\s*/,"");let u=Qt(c);if(!u.length)return null;let f={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:u[0]};if(s>=10)f.a=i[9];if(s===11)f.b=i[10];let a=u.findIndex((l,m)=>m>0&&l.toUpperCase()==="GLOSSMAP");if(a>0&&u[a+1])f.glossmap=u[a+1];if(t)f.next=!0;return f}var en=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,"");if(t.length%4===1)t=t.slice(0,-1);let n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function tn(e){let t=e.length,n=1,r=(a)=>a===32||a===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let a=n;while(n<t&&!r(e.charCodeAt(n)))n++;return a<n?e.slice(a,n):null},o=s();if(o===null)return null;let i=Array(12);for(let a=0;a<12;a++){let l=s();if(l===null)return null;let m=+l;if(!Number.isFinite(m))return null;i[a]=m}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let c=e.slice(n),u=/[ \\t]{2,}|\\t/.test(c)?c.split(/\\s+/).join(" "):c,f=Oe(o);if(!Number.isFinite(f))return null;return{t:1,color:f,m:i,file:ne(u)}}var nn=[0,12,6,9,12,12];function st(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=Oe(e[1]),r=nn[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=ne(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function pt(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,u=null,f=[],a=null,l=()=>{if(!u)return;let p=en(u.chunks.join("")),h=p[0]===137&&p[1]===80&&p[2]===78&&p[3]===71;(c??=new Map).set(ne(u.name),{name:u.name,bytes:p,...h?{mime:"image/png"}:{}}),u=null},m=!0,g=(p)=>{if(l(),o={name:ne(p),cmds:[]},s.set(o.name,o),!i)i=o.name;f=[],a=null,m=!0},d=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},A=(p,h)=>{if(a){p.tex=a,a=null;return}let M=f[f.length-1];if(!M)return;if(M.fallback){if(!h)p.fallback=!0}else p.tex=M.map};for(let p of e.split(`\n`)){let h=p.trim();if(!h)continue;if(r&&h.charCodeAt(0)>=50&&h.charCodeAt(0)<=53&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){if(u||d)continue;if(!o)g(t);let L=h.slice(2).trimStart(),R=L.search(/\\s/),T={t:h.charCodeAt(0)-48,color:Oe(R<0?L:L.slice(0,R)),p:[],src:h};A(T,!1),o.cmds.push(T),m=!1;continue}if(h.charCodeAt(0)===48&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){let L=2;while(h.charCodeAt(L)===32||h.charCodeAt(L)===9)L++;let R=L;while(R<h.length&&h.charCodeAt(R)!==32&&h.charCodeAt(R)!==9)R++;let T=h.slice(L,R),x=/[^\\x21-\\x7e]/.test(T)?h.slice(L).trim().split(/\\s+/)[0]:T;if(!Xt.has(x)&&!(x.length>=4&&x.length<=6&&Zt.has(x.toUpperCase()))){if(d||u)continue;if(!o)g(t);let w=h.slice(L),E={t:0,text:w};if(T.charCodeAt(0)===33)E.meta=T;if(a=null,m&&!o.org){let k=rt(w);if(k)o.org=k}let z=w.match(nt);if(z&&!o.movedTo){let k=z[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(k))k+=".dat";o.movedTo=ne(k)}o.cmds.push(E);continue}}if(h.charCodeAt(0)===49&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)&&!u&&!d){let L=tn(h);if(L){if(!o)g(t);A(L,!1),o.cmds.push(L),m=!1;continue}}let M=h.split(/\\s+/);if(+M[0]===0){let L=h.slice(1).trim(),R=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(R==="FILE"){let w=L.slice(5).trimStart().split("\\r")[0].trim();if(w){C(),d=!1,g(w);continue}}if(R==="NOFILE"){l(),o=null,d=!0;continue}if(R==="!DATA"){C(),l(),o=null,d=!1,u={name:L.slice(5).trim(),chunks:[]};continue}if(d)continue;if(u){if(M[1]==="!:")u.chunks.push(M.slice(2).join(""));continue}if(!o)g(t);let T={t:0,text:L};if(M[1]==="STEP")T.step=!0,f=[],a=null;else if(M[1]==="BFC")T.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(T.meta="ROTSTEP",T.step=!0,f=[],a=null,(M[2]??"").toUpperCase()==="END")T.rotstep={x:0,y:0,z:0,mode:"END"};else{let w=(M[5]??"REL").toUpperCase(),E=(z)=>{let k=Number(z);return Number.isFinite(k)?k:0};T.rotstep={x:E(M[2]),y:E(M[3]),z:E(M[4]),mode:["REL","ABS","ADD"].includes(w)?w:"REL"}}else if(M[1]==="BUFEXCHG"){T.meta="BUFEXCHG";let w=(M[2]??"").toUpperCase();T.bufexchg={op:w==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))T.meta=M[1];if(m&&!o.org){let w=rt(L);if(w)o.org=w}if(M[1]==="!TEXMAP"){let w=(M[2]??"").toUpperCase();if(a=null,w==="START"||w==="NEXT"){let E=qt(L.replace(/^!TEXMAP\\s+\\S+/i,""),w==="NEXT");if(T.texmap={op:w,...E?{map:E}:{}},E)if((o.texmaps??=[]).push(E),w==="START")f.push({map:E,fallback:!1});else a=E}else if(w==="FALLBACK"){T.texmap={op:w};let E=f[f.length-1];if(E)E.fallback=!0}else if(w==="END")T.texmap={op:w},f.pop()}else if(M[1]==="!:"){a=null;let w=st(M.slice(2));if(w)A(w,!0),T.geom=w}else a=null;let x=L.match(nt);if(x&&!o.movedTo){let w=x[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(w))w+=".dat";o.movedTo=ne(w)}o.cmds.push(T);continue}if(u||d)continue;if(!o)g(t);let v=st(M);if(!v){if(/^[2-5][ \\t]/.test(h))m=!1;continue}A(v,!1),o.cmds.push(v),m=!1}return l(),c?{main:i,files:s,data:c}:{main:i,files:s}}var Pn=Math.PI/180;function mt(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function ht(e,t){let[n,r,s,o,i,c,u,f,a,l,m,g]=e,[d,b,C,A,p,h,M,D,v,L,R,T]=t;return[o*d+i*b+c*C+n,u*d+f*b+a*C+r,l*d+m*b+g*C+s,o*A+i*M+c*L,o*p+i*D+c*R,o*h+i*v+c*T,u*A+f*M+a*L,u*p+f*D+a*R,u*h+f*v+a*T,l*A+m*M+g*L,l*p+m*D+g*R,l*h+m*v+g*T]}var Ne=[0,0,0,1,0,0,0,1,0,0,0,1];var ot=new WeakMap,rn=/^(s|8|48)\\//;function ze(e,t){let n=e.files.get(ne(t));if(!n)return"part";let r=ot.get(n);if(r)return r;if(n.org)r=ft.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&rn.test(s.file))?"part":"model";return ot.set(n,r),r}var it=new WeakMap;function gt(e){let t=it.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return it.set(e,t),t}var at=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Be.get(e)??String(e):String(e),sn=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${at(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${at(e.color)} ${e.p.join(" ")}`,$e=(e,t)=>`${ne(e)}#${t}`;function on(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:$e(e.name,t),cmds:n}}function dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...on(e,t).cmds.map(sn)].join(`\n`)+`\n`}function je(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function bt(e){let[t,n,r,s,o,i,c,u,f,a,l,m]=e,g=u*m-f*l,d=-(c*m-f*a),b=c*l-u*a,C=s*g+o*d+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let A=1/C,p=[g*A,-(o*m-i*l)*A,(o*f-i*u)*A,d*A,(s*m-i*a)*A,-(s*f-i*c)*A,b*A,-(s*l-o*a)*A,(s*u-o*c)*A];return[-(p[0]*t+p[1]*n+p[2]*r),-(p[3]*t+p[4]*n+p[5]*r),-(p[6]*t+p[7]*n+p[8]*r),...p]}var an=(e)=>String(+e.toFixed(6)||0),lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function yt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(an).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${lt(t.texture)}${t.glossmap?" GLOSSMAP "+lt(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${ne(e)}\n0 !TEXMAP END\n`;return{name:`${ne(e)}#tex-${je(r)}`,source:r}}var ln=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function cn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),u=Math.sin(n*r),f=Math.cos(n*r);return[c*f,-c*u,i,o*u+s*i*f,o*f-s*i*u,-s*c,s*u-o*i*f,s*f+o*i*u,o*c]}var ct=new WeakMap;function xt(e){let t=ct.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=cn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:ln(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),ct.set(e,n),n}class Ve extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var un=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=ut))return!1;return!0},wt=999999,vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Ct=new WeakMap,Mt=new WeakMap;function fn(e,t){let n=Mt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Ct.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},Mt.set(t,n);let r=n.parts.get(e);if(!r){let s=ne(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${je(o)}`,source:o},n.parts.set(e,r)}return r}function pn(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,u=0,f=new Set,a=t.maxInstances??2000000,l=0,m=(d,b)=>{let C=d.name+"#"+b,A=c.get(C);if(!A){let p;A=Object.assign(()=>p??=dt(d,b),{file:d,step:b}),c.set(C,A)}return A},g=(d,b,C,A,p,h,M,D,v=null,L=[],R=[],T=void 0,x=null)=>{let w=d.files.get(b);if(!w||M>r||f.has(w))return;if(++l>a)throw new Ve("model",a);f.add(w);let E=x,z=0,k=M>0?++u:0,P=i&&k?[...L,k]:L,Y=i&&k?[...R,C]:R,I=i&&!v?new Map:null,j=-1,H=0,Z=(S,y,B,_,W,X,N)=>{if(j!==z)j=z,H=0;let q=I?.get(z+"|"+y);if(q)return q.n++,g(S,S===d?y:S.main,B,_,p+"/"+y,[...W,wt],M+1,X,[...W,wt],P,Y,N,E);let U=[...W,H++],F=n.length;g(S,S===d?y:S.main,B,_,p+"/"+y,U,M+1,X,v,P,Y,N,E),I?.set(z+"|"+y,{n:1,from:F,to:n.length})},O=xt(w),G=s?gt(w):[],K=0,J=(S,y,B,_,W,X,N,q,U)=>{if(v)_=v;if(++l>a)throw new Ve("model",a);let F={part:S,color:y,m:B,step:_[0],steps:_,localStep:W,path:p};if(q)F.colour=q;if(k){if(F.sub=k,i)F.subPath=P,F.subMats=Y}if(X)F.embedded=!0;if(N){let re=yt(S,N);F.texPart=re.name,F.texSource=re.source}else if(U){let re=fn(S,U);F.colPart=re.name,F.colSource=re.source}let V=O[W];if(V)F.view=V;return n.push(F),F},Q=(S)=>{while(K<G.length&&G[K]<=S){let y=G[K++];J($e(w.name,y),A,C,[...h,y],y,!1,null,T,x).source=m(w,y)}};for(let S of w.cmds){if(S.t===0&&S.step){z++;continue}let y=S;if(y.t>=2||y.t===0&&y.geom&&y.geom.t>=2){Q(z);continue}if(y.t===0){if(y.meta==="!COLOUR"){let V=hn(y.text);if(V&&V.code!==16&&V.code!==24)Ct.set(V,y.text),(E=new Map(E??[])).set(V.code,V);continue}if(o&&y.geom?.t===1)y=y.geom;else continue}if(y.t!==1)continue;if(o&&y.fallback)continue;let B=ht(C,y.m);if(!un(B))continue;let _=y.color===16?A:y.color,W=y.color===16?T:E?.get(y.color),X=[...h,z],N=o?y.tex??D:null,q=N?bt(y.m):null,U=N&&q?mt(N,q):null;if(d.files.has(y.file)){if(ze(d,y.file)==="model"){Z(d,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!0,U,W,E);continue}let F=t.resolveModel?.(y.file);if(F){Z(F,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!1,U,W,E)}if(Q(1/0),f.delete(w),I){for(let S of I.values())if(S.n>1)for(let y=S.from;y<S.to;y++)n[y].mult??=S.n}};if(ze(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ne],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,Ne,16,e.main,[],0,null),n}function Tt(e,t="main.ldr",n){return pn(pt(e,t,{geometryText:!0}),n)}var mn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function _e(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function At(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=_e(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function hn(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,u=0,f={type:"default"},a=1;while(a<n.length){let l=n[a].toUpperCase(),m=n[a+1];if(l==="CODE")s=m!==void 0&&De.test(m)?Ue(m):m!==void 0&&/^\\d+$/.test(m)?+m:NaN,a+=2;else if(l==="VALUE"){let g=_e(m);if(g)o=g;a+=2}else if(l==="EDGE")i=_e(m)??m,a+=2;else if(l==="ALPHA")c=+m,a+=2;else if(l==="LUMINANCE")u=+m,a+=2;else if(l==="CHROME")f={type:"chrome"},a+=1;else if(l==="PEARLESCENT")f={type:"pearlescent"},a+=1;else if(l==="RUBBER")f={type:"rubber"},a+=1;else if(l==="MATTE_METALLIC")f={type:"matte_metallic"},a+=1;else if(l==="METAL")f={type:"metal"},a+=1;else if(l==="MATERIAL"){let g=(n[a+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:d,next:b}=At(n,a+2);f={type:"glitter",material:d},a=b}else if(g==="SPECKLE"){let{grain:d,next:b}=At(n,a+2);f={type:"speckle",material:d},a=b}else if(g==="FABRIC"){let d=(n[a+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(d)?d.toLowerCase():void 0;f={type:"fabric",kind:b},a+=b?3:2}else a=n.length}else if(mn.has(l))a+=1;else a+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(u)?u:0,finish:f}}function gn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function He(e){let t=gn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function dn(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(ne(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(ne(t),r)}let u=i.trim().replace(/\\s+/g," ");if(u)r.push(u)}return n}var bn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?ne(t.slice(14).join(" ")):null};function yn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Lt(e,t,n="main.ldr"){let r=dn(e,n),s=new Map;for(let o of t){let i=ne(o);if(!r.has(i)||s.has(i))continue;let c=new Set([i]),u=[i];while(u.length)for(let a of r.get(u.pop())){let l=bn(a);if(l&&r.has(l)&&!c.has(l))c.add(l),u.push(l)}let f=[i,...[...c].filter((a)=>a!==i).sort()].map((a)=>"0 FILE "+(a===i?"":a)+`\n`+r.get(a).join(`\n`)).join(`\n`);s.set(i,`emb/${yn(f)}.dat`)}return s}var St=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Et=new WeakMap;function Ge(e,t){let n=Et.get(e);if(!n)Et.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],u=[];s.studs.forEach((m,g)=>{c.push(m[0]),u.push(m[1]);for(let d=0;d<12;d++)i[g*12+d]=m[2+d]});let f=null,a=0,l=0;if(s.mask){a=s.mask[0],l=s.mask[1];let m=s.mask[2];f=new Uint8Array(m.length);for(let g=0;g<m.length;g++)f[g]=m.charCodeAt(g)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:c,color:u,mask:f,nx:a,nz:l}),r}var fe=1073741824;class We{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,c=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&c[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,c=this.b,u=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,c[s]=t,u[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&c[s]===t&&u[s]===n){let f=this.vals[s];return this.vals[s]=r,f}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var pe=(e,t,n)=>e>-fe&&e<fe&&t>-fe&&t<fe&&n>-fe&&n<fe,de=2147483647;function xn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function wn(e,t,n){let s=new Map,o=(I)=>{let j=s.get(I);if(j===void 0)s.set(I,j=xn(t,I));return j},i=[],c=[],u=[],f=[],a=[],l=[],m=[],g=[],d=[],b=new We(e.length*2),C=[],A=[];for(let I=0;I<e.length;I++){let j=e[I],H=j.m,Z=t.parts[j.part];if(!Z||!Z.mask||!St(H)||o(j.color))continue;let O=Z.bbox,G=1/0,K=-1/0,J=1/0,Q=-1/0;for(let U=0;U<2;U++)for(let F=0;F<2;F++){let V=U?O[3]:O[0],re=F?O[5]:O[2],oe=H[0]+H[3]*V+H[5]*re,se=H[2]+H[9]*V+H[11]*re;if(oe<G)G=oe;if(oe>K)K=oe;if(se<J)J=se;if(se>Q)Q=se}let S=Math.round((H[1]+O[4])*2),y=Ge(t,j.part),B=Math.floor(G/40),_=Math.floor(K/40),W=Math.floor(J/40),X=Math.floor(Q/40);if(!((_-B+1)*(X-W+1)<=65536)||!pe(S,B,W)||!pe(S,_,X))continue;let N=-1;for(let U=b.get(S,B,W),F=0;U>=0&&F<8;U=C[U],F++){let V=A[U];if(i[V]!==G||c[V]!==K||u[V]!==J||f[V]!==Q||m[V]!==y)continue;let re=e[a[V]].m,oe=!0;for(let se=0;se<12;se++)if(re[se]!==H[se]){oe=!1;break}if(oe){N=V;break}}if(N>=0){let U=n?n[I]:0;if(n&&U<n[a[N]])l[N]=a[N],a[N]=I;else if(l[N]<0||n&&U<n[l[N]])l[N]=I;continue}let q=a.length;i.push(G),c.push(K),u.push(J),f.push(Q),a.push(I),l.push(-1),m.push(y),g.push(O[0]),d.push(O[2]);for(let U=B;U<=_;U++)for(let F=W;F<=X;F++){if(!pe(S,U,F))continue;let V=A.length;A.push(q),C.push(b.put(S,U,F,V))}}let p=[0,5,-5,5,-5],h=[0,5,5,-5,-5],M=NaN,D=NaN,v=NaN,L=-1,R=(I,j,H,Z)=>{let O=Math.round(j*2),G=Math.floor(I/40),K=Math.floor(H/40);if(!pe(O,G,K))return de;let J=de;if(O!==M||G!==D||K!==v)M=O,D=G,v=K,L=b.get(O,G,K);for(let Q=L;Q>=0;Q=C[Q]){let S=A[Q],y=a[S];if(y===Z&&(y=l[S])<0)continue;if(!(I-6>=i[S]-0.5&&I+6<=c[S]+0.5&&H-6>=u[S]-0.5&&H+6<=f[S]+0.5))continue;let B=e[a[S]].m,_=m[S],W=g[S],X=d[S],N=I-B[0],q=j-B[1],U=H-B[2],F=B[3]*N+B[6]*q+B[9]*U,V=B[5]*N+B[8]*q+B[11]*U,{nx:re,nz:oe,mask:se}=_,ce=!0;for(let ie=0;ie<5;ie++){let ae=Math.floor((F+p[ie]-W)/20),ue=Math.floor((V+h[ie]-X)/20);if(ae<0||ue<0||ae>=re||ue>=oe||se[ae*oe+ue]!==1){ce=!1;break}}if(ce){if(!n)return 0;let ie=n[y];if(ie<J)J=ie}}return J},T=0;for(let I of e){let j=Ge(t,I.part);if(j)T+=j.nStuds}let x=new Uint8Array(T),w=new Uint8Array(T),E=new We(T),z=0,k=n?new Int32Array(T).fill(de):void 0;for(let I=0,j=0;I<e.length;I++){let H=e[I],Z=Ge(t,H.part);if(!Z)continue;let O=H.m,G=Z.studM,K=O[0],J=O[1],Q=O[2],S=O[3],y=O[4],B=O[5],_=O[6],W=O[7],X=O[8],N=O[9],q=O[10],U=O[11];for(let F=0;F<Z.nStuds;F++,j++){let V=F*12,re=G[V+4],oe=G[V+7],se=G[V+10];if(!(Math.abs(_*re+W*oe+X*se-1)<0.001&&Math.abs(S*re+y*oe+B*se)<0.001&&Math.abs(N*re+q*oe+U*se)<0.001))continue;w[j]=1;let ce=G[V],ie=G[V+1],ae=G[V+2],ue=K+S*ce+y*ie+B*ae,Ke=J+_*ce+W*ie+X*ae,Xe=Q+N*ce+q*ie+U*ae,Ze=R(ue,Ke,Xe,I);if(Ze!==de){if(x[j]=1,z++,k)k[j]=Ze}let be=Math.round(ue),ye=Math.round(Ke),xe=Math.round(Xe);if(!pe(be,ye,xe))continue;if(!n){E.put(be,ye,xe,1);continue}let Ye=n[I],Je=E.get(be,ye,xe);if(Je<0||Ye<Je)E.put(be,ye,xe,Ye)}}let P=new Uint8Array(e.length),Y=n?new Int32Array(e.length).fill(de):void 0;for(let I=0;I<e.length;I++){let j=e[I],H=t.parts[j.part];if(!H||!H.under||!St(j.m)||o(j.color))continue;let Z=H.bbox,O=Math.round((Z[3]-Z[0])/20),G=Math.round((Z[5]-Z[2])/20);if(!O||!G||O*G>4096)continue;let K=j.m,J=!0,Q=0;for(let S=0;S<O&&J;S++)for(let y=0;y<G;y++){let B=Z[0]+10+20*S,_=Z[2]+10+20*y,W=K[0]+K[3]*B+K[5]*_,X=K[2]+K[9]*B+K[11]*_,N=Math.round(W),q=Math.round(K[1]+Z[4]),U=Math.round(X),F=pe(N,q,U)?E.get(N,q,U):-1;if(F<0){J=!1;break}if(F>Q)Q=F}if(J){if(P[I]=1,Y)Y[I]=Q}}return{nStuds:T,studHidden:x,studUp:w,underHidden:P,studsHidden:z,studHideStep:k,underHideStep:Y}}function Mn(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let m=l.colour;if(!m)return String(l.color);let g=o.get(m);if(g!==void 0)return g;let d=t.colorTable?.[l.color],b=d?.hex??t.colors?.[l.color],C=d?He({alpha:d.alpha??255,luminance:d.luminance??0,finish:d.finish??{type:"default"}}):"default:op",A=He(m);if(g=b&&b.toUpperCase()===m.hex.toUpperCase()&&C===A?String(l.color):m.hex.toUpperCase()+"/"+A,g!==String(l.color))s.set(g,m);return o.set(m,g),g},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),u=c.map((l)=>vt(l.steps)),f=[...new Set(u)].sort(),a=new Map(f.map((l,m)=>[l,m]));return{all:c,stepOf:u.map((l)=>a.get(l)),nSteps:f.length,localColours:s}}function Ce(e,t,n=!0){let r=Mn(e,t,n);return wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var ke="https://ldr-demo.vercel.app/cdn/v1/",Le=new Map,Te=new Map;function Se(e=ke,t=fetch){let n=Le.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>Le.delete(e)),Le.set(e,n);return n}var An=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),Ee=(e,t)=>An(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Ee(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ee(r,t)])):e;function vn(e,t={}){let n=[],r=0,s={},o={};for(let m of e){let g=m.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let d=new DataView(g).getUint32(0,!0),b=new Uint8Array(g,4+d),C=r;n.push(b),r+=b.byteLength;let A=(4-r%4)%4;if(A)n.push(new Uint8Array(A)),r+=A;for(let[p,h]of Object.entries(m.header.parts??{}))if(!(p in s))s[p]=Ee(h,C);for(let[p,h]of Object.entries(m.header.studKinds??{}))if(!(p in o))o[p]=Ee(h,C)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),u=(4-(4+c.length)%4)%4,f=4+c.length+u,a=new Uint8Array(f+r);new DataView(a.buffer).setUint32(0,c.length+u,!0),a.set(c,4),a.fill(32,4+c.length,f);let l=f;for(let m of n)a.set(m,l),l+=m.byteLength;return ve(a.buffer)}async function Cn(e,t={}){e=[...e];try{return await kt(e,t)}catch(n){let r=t.cdn??ke,s=t.fetch??fetch;Le.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await kt(e,{...t,fetch:o})}catch{throw n}}}async function kt(e,t){let n=t.cdn??ke,r=t.fetch??fetch,s=t.gap??16384,o=await Se(n,r),i=[...new Set([...e].map(ne))],c=[],u=[];for(let p of i){if(Te.has(n+p))continue;let h=o.parts[p];if(h)u.push({name:p,off:h[0],len:h[1],file:h[2]??0});else c.push(p)}u.sort((p,h)=>p.file-h.file||p.off-h.off);let f=[];for(let p of u){let h=f[f.length-1];if(h&&h.file===p.file&&p.off-h.end<=s)h.end=Math.max(h.end,p.off+p.len),h.items.push(p);else f.push({file:p.file,start:p.off,end:p.off+p.len,items:[p]})}let a=0,l=0,m=0,g=new Map,d=async()=>{while(m<f.length){let p=f[m++],h=g.get(p.file);if(h)h=h.subarray(p.start,p.end);else{let M=await r(new URL(o.archives[p.file],n).href,{headers:{Range:`bytes=${p.start}-${p.end-1}`,"Accept-Encoding":"identity"}});if(!M.ok)throw Error(`ldr: parts CDN ${M.status}`);if(l++,h=new Uint8Array(await M.arrayBuffer()),a+=h.byteLength,M.status===200)g.set(p.file,h),h=h.subarray(p.start,p.end)}for(let M of p.items){let D=Ae(h.subarray(M.off-p.start,M.off-p.start+M.len)),v=D.buffer.slice(D.byteOffset,D.byteOffset+D.byteLength);Te.set(n+M.name,ve(v))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,f.length)},d));let b=i.filter((p)=>Te.has(n+p)).map((p)=>Te.get(n+p)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?vn(b,C):ve(Tn(C)),missing:c,requests:l,bytes:a}}function Tn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function Ln(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function Pt(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let c of e){let u=c.embedded?t.get(c.part):ne(c.part),f=u?n.parts[u]:void 0;if(!f)continue;if(f[3]!=null)o=!0,r+=f[3];if(!i.has(u))i.add(u),s+=f[1]}return{bodyTris:r,packBytes:s,known:o}}class Pe extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function It(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Se(t.cdn??ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(x)=>{if(!x.ok)throw Error(`ldr: ${x.status} fetching ${e}`);return et(await x.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":tt(e)),u=Tt(o,c,{looseGeometry:!1,callouts:t.callouts}),f=performance.now();t.onParsed?.(u),await s;let a=Lt(o,new Set(u.filter((x)=>x.embedded).map((x)=>x.part)),c),l=(x,w)=>t.maxBodyTris!=null&&x>t.maxBodyTris||t.maxPackBytes!=null&&w>t.maxPackBytes,m=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(x)=>new Pe({...x,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),d="full";if(m){let x=Pt(u,a,await s);if(l(x.known?x.bodyTris:0,x.packBytes)){if(!t.lowCdn)throw g(x);let w=await Se(t.lowCdn,r).catch(()=>null);if(!w)throw g(x);let E=Pt(u,a,w);if(l(E.known?E.bodyTris:0,E.packBytes))throw g(E);d="low"}}let b=[...u.filter((x)=>!x.embedded).map((x)=>x.part),...a.values()],C=async()=>{let x=await Cn(b,d==="low"?{...t,cdn:t.lowCdn}:t);for(let[w,E]of a){let z=x.pack.header.parts[E];if(z)x.pack.header.parts[w]=z}return{...x,packBytes:x.pack.buffer?.byteLength??x.pack.bytes??0,bodyTris:Ln(u,x.pack)}},A=await C();if(m&&l(A.bodyTris,A.packBytes)&&d==="full"&&t.lowCdn&&await Se(t.lowCdn,r).then(()=>!0,()=>!1)){d="low";let x=A;A=await C(),A.requests+=x.requests,A.bytes+=x.bytes}if(m&&l(A.bodyTris,A.packBytes))throw g(A);let{pack:p,missing:h,requests:M,bytes:D}=A,v=new Map([...a].map(([x,w])=>[w,x])),L=h.map((x)=>v.get(x)??x),R=performance.now(),T=t.cull?Ce(u,p.header,t.textures!==!1):void 0;return{insts:u,pack:p,tier:d,missing:L,requests:M,bytes:D,cull:T,timings:{fetchModel:i-n,parse:f-i,parts:R-f,...T?{cull:performance.now()-R}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await It(n,{...r,cull:!1,onParsed:(a)=>self.postMessage({id:t,insts:a})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),c=Ce(s.insts,s.pack.header,r.textures!==!1),u=performance.now()-i,f=[];for(let a of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(a)f.push(a.buffer);self.postMessage({id:t,cull:c,ms:u},f)}catch(s){if(s instanceof Pe||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
|
|
4774
4929
|
|
|
4775
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4930
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cdn.ts
|
|
4776
4931
|
var worker;
|
|
4777
4932
|
var seq = 0;
|
|
4778
4933
|
var pending = new Map;
|
package/dist/node/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/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;
|
|
@@ -802,7 +802,7 @@ function fileStepViews(f) {
|
|
|
802
802
|
viewMemo.set(f, out);
|
|
803
803
|
return out;
|
|
804
804
|
}
|
|
805
|
-
// ../../../../../../../tmp/ldr-build-
|
|
805
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/model.ts
|
|
806
806
|
class ModelLimitError extends Error {
|
|
807
807
|
limit;
|
|
808
808
|
code = "ldr-model-limit";
|
|
@@ -1243,7 +1243,7 @@ function blendedColourHex(code) {
|
|
|
1243
1243
|
const a = LDRAW_EXE_16[code - 256 >> 4], b = LDRAW_EXE_16[code - 256 & 15];
|
|
1244
1244
|
return "#" + [0, 1, 2].map((k) => (a[k] + b[k] >> 1).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1245
1245
|
}
|
|
1246
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1246
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/instructions.ts
|
|
1247
1247
|
var MIN_VIS = 0.5;
|
|
1248
1248
|
var REORIENT = 0.35;
|
|
1249
1249
|
var deg = Math.PI / 180;
|
|
@@ -1611,10 +1611,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
|
|
|
1611
1611
|
}
|
|
1612
1612
|
};
|
|
1613
1613
|
}
|
|
1614
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1614
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/render.ts
|
|
1615
1615
|
import * as THREE from "three";
|
|
1616
1616
|
|
|
1617
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1617
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/pack-io.ts
|
|
1618
1618
|
import { decompress } from "fzstd";
|
|
1619
1619
|
async function decompressPack(data) {
|
|
1620
1620
|
const u = data instanceof Uint8Array ? data : new Uint8Array(data);
|
|
@@ -1637,7 +1637,7 @@ function decodePack(buf) {
|
|
|
1637
1637
|
return { header, arr, bytes: buf.byteLength, buffer: buf };
|
|
1638
1638
|
}
|
|
1639
1639
|
|
|
1640
|
-
// ../../../../../../../tmp/ldr-build-
|
|
1640
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cull.ts
|
|
1641
1641
|
var upright = (m, o = 0) => Math.abs(m[o + 7] - 1) < 0.001 && Math.abs(m[o + 4]) < 0.001 && Math.abs(m[o + 10]) < 0.001;
|
|
1642
1642
|
var prepCache = new WeakMap;
|
|
1643
1643
|
function prepPart(H, part) {
|
|
@@ -2020,7 +2020,7 @@ function precomputeCull(instances, H, useTex = true) {
|
|
|
2020
2020
|
return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
|
|
2021
2021
|
}
|
|
2022
2022
|
|
|
2023
|
-
// ../../../../../../../tmp/ldr-build-
|
|
2023
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/render.ts
|
|
2024
2024
|
async function loadPack(url) {
|
|
2025
2025
|
const res = await fetch(url);
|
|
2026
2026
|
if (!res.ok)
|
|
@@ -2732,21 +2732,134 @@ function studBoxGeom(w) {
|
|
|
2732
2732
|
_studBox.set(w, g);
|
|
2733
2733
|
return g;
|
|
2734
2734
|
}
|
|
2735
|
+
var _studTube = new Map;
|
|
2736
|
+
function studTubeGeom(w, wi) {
|
|
2737
|
+
const key = w + "," + wi;
|
|
2738
|
+
let g = _studTube.get(key);
|
|
2739
|
+
if (g)
|
|
2740
|
+
return g;
|
|
2741
|
+
const y = -4, s = Math.SQRT1_2;
|
|
2742
|
+
const sq = (h) => [[-h, -h], [h, -h], [h, h], [-h, h]];
|
|
2743
|
+
const C = sq(w), Ci = sq(wi);
|
|
2744
|
+
const pos = [], nrm = [], idx = [];
|
|
2745
|
+
for (const [x, z] of C) {
|
|
2746
|
+
pos.push(x, y, z);
|
|
2747
|
+
nrm.push(0, -1, 0);
|
|
2748
|
+
}
|
|
2749
|
+
for (const [x, z] of Ci) {
|
|
2750
|
+
pos.push(x, y, z);
|
|
2751
|
+
nrm.push(0, -1, 0);
|
|
2752
|
+
}
|
|
2753
|
+
for (const [x, z] of C) {
|
|
2754
|
+
pos.push(x, y, z, x, 0, z);
|
|
2755
|
+
nrm.push(Math.sign(x) * s, 0, Math.sign(z) * s, Math.sign(x) * s, 0, Math.sign(z) * s);
|
|
2756
|
+
}
|
|
2757
|
+
for (const [x, z] of Ci) {
|
|
2758
|
+
pos.push(x, y, z, x, 0, z);
|
|
2759
|
+
nrm.push(-Math.sign(x) * s, 0, -Math.sign(z) * s, -Math.sign(x) * s, 0, -Math.sign(z) * s);
|
|
2760
|
+
}
|
|
2761
|
+
const tri = (a, b, c, out) => {
|
|
2762
|
+
const P = (i) => pos.slice(i * 3, i * 3 + 3);
|
|
2763
|
+
const [A, B, Cc] = [P(a), P(b), P(c)];
|
|
2764
|
+
const u = [B[0] - A[0], B[1] - A[1], B[2] - A[2]], v = [Cc[0] - A[0], Cc[1] - A[1], Cc[2] - A[2]];
|
|
2765
|
+
const n = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];
|
|
2766
|
+
if (n[0] * out[0] + n[1] * out[1] + n[2] * out[2] < 0)
|
|
2767
|
+
idx.push(a, c, b);
|
|
2768
|
+
else
|
|
2769
|
+
idx.push(a, b, c);
|
|
2770
|
+
};
|
|
2771
|
+
for (let i = 0;i < 4; i++) {
|
|
2772
|
+
const j = (i + 1) % 4;
|
|
2773
|
+
tri(i, j, 4 + j, [0, -1, 0]);
|
|
2774
|
+
tri(i, 4 + j, 4 + i, [0, -1, 0]);
|
|
2775
|
+
const mid = [(C[i][0] + C[j][0]) / 2, 0, (C[i][1] + C[j][1]) / 2];
|
|
2776
|
+
{
|
|
2777
|
+
const ti = 8 + i * 2, bi = ti + 1, tj = 8 + j * 2, bj = tj + 1;
|
|
2778
|
+
tri(ti, tj, bj, mid);
|
|
2779
|
+
tri(ti, bj, bi, mid);
|
|
2780
|
+
}
|
|
2781
|
+
{
|
|
2782
|
+
const ti = 16 + i * 2, bi = ti + 1, tj = 16 + j * 2, bj = tj + 1;
|
|
2783
|
+
const inn = [-mid[0], 0, -mid[2]];
|
|
2784
|
+
tri(ti, tj, bj, inn);
|
|
2785
|
+
tri(ti, bj, bi, inn);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
const nv = pos.length / 3;
|
|
2789
|
+
const col = new Uint8Array(nv * 4);
|
|
2790
|
+
for (let i = 0;i < nv; i++) {
|
|
2791
|
+
col[i * 4] = 255;
|
|
2792
|
+
col[i * 4 + 1] = 255;
|
|
2793
|
+
col[i * 4 + 2] = 255;
|
|
2794
|
+
col[i * 4 + 3] = 0;
|
|
2795
|
+
}
|
|
2796
|
+
g = new THREE.BufferGeometry;
|
|
2797
|
+
g.setAttribute("position", new THREE.Float16BufferAttribute(toF16(new Float32Array(pos)), 3));
|
|
2798
|
+
g.setAttribute("normal", new THREE.BufferAttribute(toI8(new Float32Array(nrm)), 3, true));
|
|
2799
|
+
g.setAttribute("ldrColor", new THREE.BufferAttribute(col, 4, true));
|
|
2800
|
+
g.setIndex(new THREE.BufferAttribute(new Uint16Array(idx), 1));
|
|
2801
|
+
g.computeBoundingSphere();
|
|
2802
|
+
g.computeBoundingBox();
|
|
2803
|
+
_studTube.set(key, g);
|
|
2804
|
+
return g;
|
|
2805
|
+
}
|
|
2806
|
+
var _hole = new WeakMap;
|
|
2807
|
+
function studHole(b, arr = (r) => r) {
|
|
2808
|
+
if (!b)
|
|
2809
|
+
return null;
|
|
2810
|
+
let v = _hole.get(b);
|
|
2811
|
+
if (v !== undefined)
|
|
2812
|
+
return v;
|
|
2813
|
+
v = null;
|
|
2814
|
+
const p = arr(b.pos);
|
|
2815
|
+
let rin = Infinity, out = Infinity, ok = p.length >= 9;
|
|
2816
|
+
for (let i = 0;i < p.length && ok; i += 3) {
|
|
2817
|
+
const y = p[i + 1], r = Math.hypot(p[i], p[i + 2]);
|
|
2818
|
+
if (y < -4.01 || y > 0.01 || r > 6.02)
|
|
2819
|
+
ok = false;
|
|
2820
|
+
else if (r < 5.8)
|
|
2821
|
+
rin = Math.min(rin, r);
|
|
2822
|
+
else
|
|
2823
|
+
out = Math.min(out, r);
|
|
2824
|
+
}
|
|
2825
|
+
if (ok && rin >= 3.5 && rin <= 4.5) {
|
|
2826
|
+
let top = false, foot = false;
|
|
2827
|
+
for (let i = 0;i < p.length && ok; i += 3) {
|
|
2828
|
+
const r = Math.hypot(p[i], p[i + 2]);
|
|
2829
|
+
if (r >= 5.8)
|
|
2830
|
+
continue;
|
|
2831
|
+
if (r - rin > 0.1)
|
|
2832
|
+
ok = false;
|
|
2833
|
+
else if (Math.abs(p[i + 1] + 4) < 0.01)
|
|
2834
|
+
top = true;
|
|
2835
|
+
else if (Math.abs(p[i + 1]) < 0.01)
|
|
2836
|
+
foot = true;
|
|
2837
|
+
}
|
|
2838
|
+
if (ok && top && foot)
|
|
2839
|
+
v = { r: rin, out };
|
|
2840
|
+
}
|
|
2841
|
+
_hole.set(b, v);
|
|
2842
|
+
return v;
|
|
2843
|
+
}
|
|
2735
2844
|
var _topClosed = new WeakMap;
|
|
2736
|
-
function studSquareLines(E, w) {
|
|
2845
|
+
function studSquareLines(E, w, hole) {
|
|
2737
2846
|
const n = Math.floor(E.length / 6);
|
|
2738
2847
|
if (!n)
|
|
2739
2848
|
return null;
|
|
2740
2849
|
const loops = new Map;
|
|
2850
|
+
const cls = (q) => {
|
|
2851
|
+
const r = Math.hypot(E[q], E[q + 2]);
|
|
2852
|
+
return Math.abs(r - 6) <= 0.02 ? "o" : hole && Math.abs(r - hole.r) <= 0.02 ? "i" : null;
|
|
2853
|
+
};
|
|
2741
2854
|
for (let s = 0;s < n; s++) {
|
|
2742
2855
|
const o = s * 6;
|
|
2743
2856
|
const y0 = E[o + 1], y1 = E[o + 4];
|
|
2744
2857
|
if (Math.abs(y0 - y1) > 0.001)
|
|
2745
2858
|
return null;
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
const k = String(Math.round(y0 * 100) / 100 + 0);
|
|
2859
|
+
const c0 = cls(o);
|
|
2860
|
+
if (!c0 || cls(o + 3) !== c0)
|
|
2861
|
+
return null;
|
|
2862
|
+
const k = String(Math.round(y0 * 100) / 100 + 0) + c0;
|
|
2750
2863
|
const L = loops.get(k) || loops.set(k, { segs: 0, len: 0, deg: new Map }).get(k);
|
|
2751
2864
|
L.segs++;
|
|
2752
2865
|
L.len = Math.max(L.len, Math.hypot(E[o + 3] - E[o], E[o + 5] - E[o + 2]));
|
|
@@ -2762,10 +2875,10 @@ function studSquareLines(E, w) {
|
|
|
2762
2875
|
const C = [[-w, -w], [w, -w], [w, w], [-w, w]];
|
|
2763
2876
|
const pos = new Float32Array(ord.length * 24), lens = new Float32Array(ord.length * 4);
|
|
2764
2877
|
ord.forEach(([yk, L], i) => {
|
|
2765
|
-
const y =
|
|
2878
|
+
const y = parseFloat(yk), h = yk.endsWith("i") ? hole.w / w : 1;
|
|
2766
2879
|
for (let c = 0;c < 4; c++) {
|
|
2767
2880
|
const a = C[c], b = C[(c + 1) % 4];
|
|
2768
|
-
pos.set([a[0], y, a[1], b[0], y, b[1]], (i * 4 + c) * 6);
|
|
2881
|
+
pos.set([a[0] * h, y, a[1] * h, b[0] * h, y, b[1] * h], (i * 4 + c) * 6);
|
|
2769
2882
|
lens[i * 4 + c] = L.len;
|
|
2770
2883
|
}
|
|
2771
2884
|
});
|
|
@@ -2827,11 +2940,44 @@ class LdrLodRoot extends THREE.LOD {
|
|
|
2827
2940
|
apply = () => {};
|
|
2828
2941
|
inv = new THREE.Matrix4;
|
|
2829
2942
|
cp = new THREE.Vector3;
|
|
2943
|
+
lastW = new Float32Array(16).fill(NaN);
|
|
2830
2944
|
constructor() {
|
|
2831
2945
|
super();
|
|
2832
2946
|
this.autoUpdate = true;
|
|
2833
2947
|
}
|
|
2834
2948
|
raycast() {}
|
|
2949
|
+
updateMatrixWorld(force) {
|
|
2950
|
+
if (this.matrixAutoUpdate)
|
|
2951
|
+
this.updateMatrix();
|
|
2952
|
+
let moved = false;
|
|
2953
|
+
if (this.matrixWorldNeedsUpdate || force) {
|
|
2954
|
+
if (this.matrixWorldAutoUpdate) {
|
|
2955
|
+
if (this.parent === null)
|
|
2956
|
+
this.matrixWorld.copy(this.matrix);
|
|
2957
|
+
else
|
|
2958
|
+
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
|
|
2959
|
+
}
|
|
2960
|
+
this.matrixWorldNeedsUpdate = false;
|
|
2961
|
+
const e = this.matrixWorld.elements, l = this.lastW;
|
|
2962
|
+
for (let i = 0;i < 16; i++)
|
|
2963
|
+
if (e[i] !== l[i]) {
|
|
2964
|
+
l[i] = e[i];
|
|
2965
|
+
moved = true;
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
const ch = this.children;
|
|
2969
|
+
for (let i = 0, n = ch.length;i < n; i++) {
|
|
2970
|
+
const c = ch[i];
|
|
2971
|
+
if (!c.matrixAutoUpdate && c.children.length === 0) {
|
|
2972
|
+
if (moved || c.matrixWorldNeedsUpdate) {
|
|
2973
|
+
if (c.matrixWorldAutoUpdate)
|
|
2974
|
+
c.matrixWorld.multiplyMatrices(this.matrixWorld, c.matrix);
|
|
2975
|
+
c.matrixWorldNeedsUpdate = false;
|
|
2976
|
+
}
|
|
2977
|
+
} else
|
|
2978
|
+
c.updateMatrixWorld(moved || force);
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2835
2981
|
update(camera) {
|
|
2836
2982
|
if (!this.enabled || !this.clusters.length)
|
|
2837
2983
|
return;
|
|
@@ -3804,8 +3950,11 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3804
3950
|
cl.studLineLv = 0;
|
|
3805
3951
|
cl.lv.push({ objs: [im], err: 0 });
|
|
3806
3952
|
const discObjs = [];
|
|
3807
|
-
|
|
3808
|
-
|
|
3953
|
+
const sqW = /(^|[\\/])8[\\/]/.test(kind) ? STUD_BOX_W_LOW : 6;
|
|
3954
|
+
const h = studTopClosed(k.body, arr) ? null : studHole(k.body, arr);
|
|
3955
|
+
const hole = h ? { r: h.r, w: h.r * Math.sqrt(Math.PI) / 2 } : undefined;
|
|
3956
|
+
if (LOD && (hole || studTopClosed(k.body, arr)) && (im.geometry.getIndex()?.count ?? im.geometry.getAttribute("position").count) > 30) {
|
|
3957
|
+
const box = new THREE.InstancedMesh(hole ? studTubeGeom(sqW, hole.w) : studBoxGeom(sqW), im.material, 0);
|
|
3809
3958
|
box.userData = { ldrStud: true, ldrLod: true };
|
|
3810
3959
|
box.instanceMatrix = im.instanceMatrix;
|
|
3811
3960
|
box.count = im.count;
|
|
@@ -3815,7 +3964,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3815
3964
|
box.onBeforeRender = trackVp;
|
|
3816
3965
|
root.add(box);
|
|
3817
3966
|
discObjs.push(box);
|
|
3818
|
-
cl.lv.push({ objs: [box], err: STUD_BOX_ERR });
|
|
3967
|
+
cl.lv.push({ objs: [box], err: h ? Math.max(STUD_BOX_ERR, 6 * Math.SQRT2 - h.out) : STUD_BOX_ERR });
|
|
3819
3968
|
cl.studLineLv = 1;
|
|
3820
3969
|
}
|
|
3821
3970
|
if (LOD) {
|
|
@@ -3836,7 +3985,7 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
3836
3985
|
const round = addLines(k.edges, im, cl);
|
|
3837
3986
|
let sq = cl.studLineLv === 1 && round ? sqLineKey.get(kind) : null;
|
|
3838
3987
|
if (sq === undefined) {
|
|
3839
|
-
const r = studSquareLines(arr(k.edges),
|
|
3988
|
+
const r = studSquareLines(arr(k.edges), sqW, hole);
|
|
3840
3989
|
sqLineKey.set(kind, sq = r && { sq: r });
|
|
3841
3990
|
}
|
|
3842
3991
|
if (sq && round) {
|
|
@@ -4028,6 +4177,12 @@ function* buildLdrSceneGen(insts, pack, P, color, mark) {
|
|
|
4028
4177
|
insts = null;
|
|
4029
4178
|
cull = null;
|
|
4030
4179
|
byPart.clear();
|
|
4180
|
+
for (const o of root.children)
|
|
4181
|
+
if (o.children.length === 0) {
|
|
4182
|
+
o.updateMatrix();
|
|
4183
|
+
o.matrixAutoUpdate = false;
|
|
4184
|
+
o.matrixWorldNeedsUpdate = true;
|
|
4185
|
+
}
|
|
4031
4186
|
return { root, stats, setCull, setSide, setEdges, setCond, setLod, setStep, box, texturesReady, trimmed };
|
|
4032
4187
|
}
|
|
4033
4188
|
function buildLdrScene(insts, pack, P, color, mark) {
|
|
@@ -4106,7 +4261,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
|
|
|
4106
4261
|
await new Promise((r) => setTimeout(r, 0));
|
|
4107
4262
|
}
|
|
4108
4263
|
}
|
|
4109
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4264
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/scene.ts
|
|
4110
4265
|
import * as THREE2 from "three";
|
|
4111
4266
|
var _box = new THREE2.Box3;
|
|
4112
4267
|
var _m4 = new THREE2.Matrix4;
|
|
@@ -4461,10 +4616,10 @@ function createLdrObjectInner(instances, pack, options, progressive) {
|
|
|
4461
4616
|
return finish();
|
|
4462
4617
|
})();
|
|
4463
4618
|
}
|
|
4464
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4619
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/parts-cdn.ts
|
|
4465
4620
|
import { decompress as decompress2 } from "fzstd";
|
|
4466
4621
|
|
|
4467
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4622
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/embedded.ts
|
|
4468
4623
|
function splitFiles(text, fallback) {
|
|
4469
4624
|
const files = new Map;
|
|
4470
4625
|
let cur = null, saw = false, skip = false;
|
|
@@ -4539,7 +4694,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
|
|
|
4539
4694
|
return out;
|
|
4540
4695
|
}
|
|
4541
4696
|
|
|
4542
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4697
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/parts-cdn.ts
|
|
4543
4698
|
var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
|
|
4544
4699
|
var indexCache = new Map;
|
|
4545
4700
|
var shardCache = new Map;
|
|
@@ -4793,10 +4948,10 @@ async function prepareModel(source, o = {}) {
|
|
|
4793
4948
|
return { insts, pack, tier, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
|
|
4794
4949
|
}
|
|
4795
4950
|
|
|
4796
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4951
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/load-worker.gen.ts
|
|
4797
4952
|
var load_worker_gen_default = 'var Ft=ArrayBuffer,ee=Uint8Array,we=Uint16Array,Rt=Int16Array;var Me=Int32Array,Ie=function(e,t,n){if(ee.prototype.slice)return ee.prototype.slice.call(e,t,n);if(t==null||t<0)t=0;if(n==null||n>e.length)n=e.length;var r=new ee(n-t);return r.set(e.subarray(t,n)),r},he=function(e,t,n,r){if(ee.prototype.fill)return ee.prototype.fill.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;for(;n<r;++n)e[n]=t;return e},Bt=function(e,t,n,r){if(ee.prototype.copyWithin)return ee.prototype.copyWithin.call(e,t,n,r);if(n==null||n<0)n=0;if(r==null||r>e.length)r=e.length;while(n<r)e[t++]=e[n++]};var Dt=["invalid zstd data","window size too large (>2046MB)","invalid block type","FSE accuracy too high","match distance too far back","unexpected EOF"],te=function(e,t,n){var r=Error(t||Dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,te);if(!n)throw r;return r},Qe=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},Ut=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ot=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,c=r>>6;if(r&8)te(0);var u=6-s,f=i==3?4:i,a=Qe(e,u,f);u+=f;var l=c?1<<c:s,m=Qe(e,u,l)+(c==1&&256),g=m;if(!s){var d=1<<10+(e[5]>>3);g=d+(d>>3)*(e[5]&7)}if(g>2145386496)te(1);var b=new ee((t==1?m||g:t?0:g)+12);return b[0]=1,b[4]=4,b[8]=8,{b:u+l,y:0,l:0,d:a,w:t&&t!=1?t:b.subarray(12),e:g,o:new Me(b.buffer,0,3),u:m,c:o,m:Math.min(131072,g)}}else if((n>>4|e[3]<<20)==25481893)return Ut(e,4)+8;te(0)},le=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ge=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)te(3);var o=1<<s,i=o,c=-1,u=-1,f=-1,a=o,l=new Ft(512+(o<<2)),m=new Rt(l,0,256),g=new we(l,0,256),d=new we(l,512,o),b=512+(o<<1),C=new ee(l,b,o),A=new ee(l,b+o);while(c<255&&i>0){var p=le(i+1),h=r>>3,M=(1<<p+1)-1,D=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(r&7)&M,v=(1<<p)-1,L=M-i-1,R=D&v;if(R<L)r+=p,D=R;else if(r+=p+1,D>v)D-=L;if(m[++c]=--D,D==-1)i+=D,C[--a]=c;else i-=D;if(!D)do{var T=r>>3;u=(e[T]|e[T+1]<<8)>>(r&7)&3,r+=2,c+=u}while(u==3)}if(c>255||i)te(0);var x=0,w=(o>>1)+(o>>3)+3,E=o-1;for(var z=0;z<=c;++z){var k=m[z];if(k<1){g[z]=-k;continue}for(f=0;f<k;++f){C[x]=z;do x=x+w&E;while(x>=a)}}if(x)te(0);for(f=0;f<o;++f){var P=g[C[f]]++,Y=A[f]=s-le(P);d[f]=(P<<Y)-o}return[r+7>>3,{b:s,s:C,n:A,t:d}]},Nt=function(e,t){var n=0,r=-1,s=new ee(292),o=e[t],i=s.subarray(0,256),c=s.subarray(256,268),u=new we(s.buffer,268);if(o<128){var f=ge(e,t+1,6),a=f[0],l=f[1];t+=o;var m=a<<3,g=e[t];if(!g)te(0);var d=0,b=0,C=l.b,A=C,p=(++t<<3)-8+le(g);for(;;){if(p-=C,p<m)break;var h=p>>3;if(d+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<C)-1,i[++r]=l.s[d],p-=A,p<m)break;h=p>>3,b+=(e[h]|e[h+1]<<8)>>(p&7)&(1<<A)-1,i[++r]=l.s[b],C=l.n[d],d=l.t[d],A=l.n[b],b=l.t[b]}if(++r>255)te(0)}else{r=o-127;for(;n<r;n+=2){var M=e[++t];i[n]=M>>4,i[n+1]=M&15}++t}var D=0;for(n=0;n<r;++n){var v=i[n];if(v>11)te(0);D+=v&&1<<v-1}var L=le(D)+1,R=1<<L,T=R-D;if(T&T-1)te(0);i[r++]=le(T)+1;for(n=0;n<r;++n){var v=i[n];++c[i[n]=v&&L+1-v]}var x=new ee(R<<1),w=x.subarray(0,R),E=x.subarray(R);u[L]=0;for(n=L;n>0;--n){var z=u[n];he(E,n,z,u[n-1]=z+c[n]*(1<<L-n))}if(u[0]!=R)te(0);for(n=0;n<r;++n){var k=i[n];if(k){var P=u[k];he(w,n,P,u[k]=P+(1<<L-k))}}return[t,{n:E,b:L,s:w}]},zt=ge(new ee([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],$t=ge(new ee([33,20,196,24,99,140,33,132,16,66,8,33,132,16,66,8,33,68,68,68,68,68,68,68,68,36,9]),0,6)[1],jt=ge(new ee([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],qe=function(e,t){var n=e.length,r=new Me(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Fe=new ee(new Me([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),Vt=qe(Fe,0),Re=new ee(new Me([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),_t=qe(Re,3),me=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,c=-n.b;if(!o)te(0);var u=0,f=n.b,a=(r<<3)-8+le(o)-f,l=-1;for(;a>c&&l<s;){var m=a>>3,g=(e[m]|e[m+1]<<8|e[m+2]<<16)>>(a&7);u=(u<<f|g)&i,t[++l]=n.s[u],a-=f=n.n[u]}if(a!=c||l+1!=s)te(0)},Ht=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,c=o+i;me(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),me(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),me(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,c),n),me(e.subarray(r),t.subarray(c),n)},Gt=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var c=o>>3|e[s+1]<<5|e[s+2]<<13,u=(s+=3)+c;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return he(n,e[s],t.y,t.y+=c),n;return he(new ee(c),e[s])}if(u>e.length)return;if(i==0){if(t.b=u,n)return n.set(e.subarray(s,u),t.y),t.y+=c,n;return Ie(e,s,u)}if(i==2){var f=e[s],a=f&3,l=f>>2&3,m=f>>4,g=0,d=0;if(a<2)if(l&1)m|=e[++s]<<4|(l&2&&e[++s]<<12);else m=f>>3;else if(d=l,l<2)m|=(e[++s]&63)<<4,g=e[s]>>6|e[++s]<<2;else if(l==2)m|=e[++s]<<4|(e[++s]&3)<<12,g=e[s]>>2|e[++s]<<6;else m|=e[++s]<<4|(e[++s]&63)<<12,g=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var b=n?n.subarray(t.y,t.y+t.m):new ee(t.m),C=b.length-m;if(a==0)b.set(e.subarray(s,s+=m),C);else if(a==1)he(b,e[s++],C);else{var A=t.h;if(a==2){var p=Nt(e,s);g+=s-(s=p[0]),t.h=A=p[1]}else if(!A)te(0);(d?Ht:me)(e.subarray(s,s+=g),b.subarray(C),A)}var h=e[s++];if(h){if(h==255)h=(e[s++]|e[s++]<<8)+32512;else if(h>127)h=h-128<<8|e[s++];var M=e[s++];if(M&3)te(0);var D=[$t,jt,zt];for(var v=2;v>-1;--v){var L=M>>(v<<1)+2&3;if(L==1){var R=new ee([0,0,e[s++]]);D[v]={s:R.subarray(2,3),n:R.subarray(0,1),t:new we(R.buffer,0,1),b:0}}else if(L==2)r=ge(e,s,9-(v&1)),s=r[0],D[v]=r[1];else if(L==3){if(!t.t)te(0);D[v]=t.t[v]}}var T=t.t=D,x=T[0],w=T[1],E=T[2],z=e[u-1];if(!z)te(0);var k=(u<<3)-8+le(z)-E.b,P=k>>3,Y=0,I=(e[P]|e[P+1]<<8)>>(k&7)&(1<<E.b)-1;P=(k-=w.b)>>3;var j=(e[P]|e[P+1]<<8)>>(k&7)&(1<<w.b)-1;P=(k-=x.b)>>3;var H=(e[P]|e[P+1]<<8)>>(k&7)&(1<<x.b)-1;for(++h;--h;){var Z=E.s[I],O=E.n[I],G=x.s[H],K=x.n[H],J=w.s[j],Q=w.n[j];P=(k-=J)>>3;var S=1<<J,y=S+((e[P]|e[P+1]<<8|e[P+2]<<16|e[P+3]<<24)>>>(k&7)&S-1);P=(k-=Re[G])>>3;var B=_t[G]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Re[G])-1);P=(k-=Fe[Z])>>3;var _=Vt[Z]+((e[P]|e[P+1]<<8|e[P+2]<<16)>>(k&7)&(1<<Fe[Z])-1);if(P=(k-=O)>>3,I=E.t[I]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<O)-1),P=(k-=K)>>3,H=x.t[H]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<K)-1),P=(k-=Q)>>3,j=w.t[j]+((e[P]|e[P+1]<<8)>>(k&7)&(1<<Q)-1),y>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=y-=3;else{var W=y-(_!=0);if(W){if(y=W==3?t.o[0]-1:t.o[W],W>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=y}else y=t.o[0]}for(var v=0;v<_;++v)b[Y+v]=b[C+v];Y+=_,C+=_;var X=Y-y;if(X<0){var N=-X,q=t.e+X;if(N>B)N=B;for(var v=0;v<N;++v)b[Y+v]=t.w[q+v];Y+=N,B-=N,X=0}for(var v=0;v<B;++v)b[Y+v]=b[X+v];Y+=B}if(Y!=C)while(C<b.length)b[Y++]=b[C++];else Y=b.length;if(n)t.y+=Y;else b=Ie(b,0,Y)}else if(n){if(t.y+=m,C)for(var v=0;v<m;++v)b[v]=b[C+v]}else if(C)b=Ie(b,C);return t.b=u,b}te(2)},Wt=function(e,t){if(e.length==1)return e[0];var n=new ee(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function Ae(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=Ot(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var c=Gt(e,i,t);if(!c)te(5);if(t)i.e=i.y;else n.push(c),o+=c.length,Bt(i.w,0,c.length),i.w.set(c,i.w.length-c.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return Wt(n,o)}async function Kt(e){let t=e instanceof Uint8Array?e:new Uint8Array(e),n=(r)=>r.buffer.slice(r.byteOffset,r.byteOffset+r.byteLength);if(t[0]===40&&t[1]===181&&t[2]===47&&t[3]===253)return n(Ae(t));if(t[0]===31&&t[1]===139)return new Response(new Blob([t]).stream().pipeThrough(new DecompressionStream("gzip"))).arrayBuffer();return n(t)}async function et(e){return new TextDecoder().decode(await Kt(e))}var tt=(e)=>decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr").replace(/\\.(zst|gz)$/i,"")||"main.ldr";function ve(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var ne=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/"),De=/^[A-Za-z][A-Za-z0-9_]*$/,Be=new Map;function Ue(e){let t=e.toLowerCase(),n=2166136261;for(let s=0;s<t.length;s++)n^=t.charCodeAt(s),n=Math.imul(n,16777619);let r=-1-(n>>>0&1073741823);if(!Be.has(r))Be.set(r,t);return r}function Oe(e){let t=e.charCodeAt(0)|32;if(t>=97&&t<=122&&De.test(e))return Ue(e);if(/^0x/i.test(e))return parseInt(e,16);return+e}var nt=/^~?\\s*moved\\s+to\\s+(.+)$/i,Xt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Zt=new Set(["FILE","NOFILE","!DATA"]),ut=1000000000000000,ft=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),Yt=new Set(["model","submodel","configuration"]),Jt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function rt(e){let t=Jt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return ft.has(n)||Yt.has(n)?n:void 0}function Qt(e){let t=[],n=0;while(n<e.length){while(e[n]===" "||e[n]==="\\t")n++;if(n>=e.length)break;if(e[n]===\'"\'){let r="";n++;while(n<e.length&&e[n]!==\'"\'){if(e[n]==="\\\\"&&n+1<e.length)n++;r+=e[n++]}n++,t.push(r)}else{let r=n;while(r<e.length&&e[r]!==" "&&e[r]!=="\\t")r++;t.push(e.slice(n,r)),n=r}}return t}function qt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every((l)=>Number.isFinite(l)&&Math.abs(l)<=1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000))return null;if(s>=10&&!(Math.abs(i[9])>=0.000001)||s===11&&!(Math.abs(i[10])>=0.000001))return null;let c=n[2].trim();for(let l=0;l<s;l++)c=c.replace(/^\\S+\\s*/,"");let u=Qt(c);if(!u.length)return null;let f={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:u[0]};if(s>=10)f.a=i[9];if(s===11)f.b=i[10];let a=u.findIndex((l,m)=>m>0&&l.toUpperCase()==="GLOSSMAP");if(a>0&&u[a+1])f.glossmap=u[a+1];if(t)f.next=!0;return f}var en=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,"");if(t.length%4===1)t=t.slice(0,-1);let n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function tn(e){let t=e.length,n=1,r=(a)=>a===32||a===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let a=n;while(n<t&&!r(e.charCodeAt(n)))n++;return a<n?e.slice(a,n):null},o=s();if(o===null)return null;let i=Array(12);for(let a=0;a<12;a++){let l=s();if(l===null)return null;let m=+l;if(!Number.isFinite(m))return null;i[a]=m}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let c=e.slice(n),u=/[ \\t]{2,}|\\t/.test(c)?c.split(/\\s+/).join(" "):c,f=Oe(o);if(!Number.isFinite(f))return null;return{t:1,color:f,m:i,file:ne(u)}}var nn=[0,12,6,9,12,12];function st(e){let t=+e[0];if(!(t>=1&&t<=5&&Number.isInteger(t))||e.length<2)return null;let n=Oe(e[1]),r=nn[t];if(!Number.isFinite(n)||e.length<2+r+(t===1?1:0))return null;let s=Array(r);for(let o=0;o<r;o++){let i=+e[2+o];if(!Number.isFinite(i))return null;s[o]=i}if(t===1){let o=ne(e.slice(14).join(" "));return o?{t:1,color:n,m:s,file:o}:null}if(t===2)return{t:2,color:n,p:s};if(t===3)return{t:3,color:n,p:s};if(t===4)return{t:4,color:n,p:s};return{t:5,color:n,p:s}}function pt(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",c,u=null,f=[],a=null,l=()=>{if(!u)return;let p=en(u.chunks.join("")),h=p[0]===137&&p[1]===80&&p[2]===78&&p[3]===71;(c??=new Map).set(ne(u.name),{name:u.name,bytes:p,...h?{mime:"image/png"}:{}}),u=null},m=!0,g=(p)=>{if(l(),o={name:ne(p),cmds:[]},s.set(o.name,o),!i)i=o.name;f=[],a=null,m=!0},d=!1,b=!1,C=()=>{if(b)return;b=!0,s.clear(),o=null,i=""},A=(p,h)=>{if(a){p.tex=a,a=null;return}let M=f[f.length-1];if(!M)return;if(M.fallback){if(!h)p.fallback=!0}else p.tex=M.map};for(let p of e.split(`\n`)){let h=p.trim();if(!h)continue;if(r&&h.charCodeAt(0)>=50&&h.charCodeAt(0)<=53&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){if(u||d)continue;if(!o)g(t);let L=h.slice(2).trimStart(),R=L.search(/\\s/),T={t:h.charCodeAt(0)-48,color:Oe(R<0?L:L.slice(0,R)),p:[],src:h};A(T,!1),o.cmds.push(T),m=!1;continue}if(h.charCodeAt(0)===48&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)){let L=2;while(h.charCodeAt(L)===32||h.charCodeAt(L)===9)L++;let R=L;while(R<h.length&&h.charCodeAt(R)!==32&&h.charCodeAt(R)!==9)R++;let T=h.slice(L,R),x=/[^\\x21-\\x7e]/.test(T)?h.slice(L).trim().split(/\\s+/)[0]:T;if(!Xt.has(x)&&!(x.length>=4&&x.length<=6&&Zt.has(x.toUpperCase()))){if(d||u)continue;if(!o)g(t);let w=h.slice(L),E={t:0,text:w};if(T.charCodeAt(0)===33)E.meta=T;if(a=null,m&&!o.org){let k=rt(w);if(k)o.org=k}let z=w.match(nt);if(z&&!o.movedTo){let k=z[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(k))k+=".dat";o.movedTo=ne(k)}o.cmds.push(E);continue}}if(h.charCodeAt(0)===49&&(h.charCodeAt(1)===32||h.charCodeAt(1)===9)&&!u&&!d){let L=tn(h);if(L){if(!o)g(t);A(L,!1),o.cmds.push(L),m=!1;continue}}let M=h.split(/\\s+/);if(+M[0]===0){let L=h.slice(1).trim(),R=M.length>1&&M[1].length>=4&&M[1].length<=6?M[1].toUpperCase():M[1];if(R==="FILE"){let w=L.slice(5).trimStart().split("\\r")[0].trim();if(w){C(),d=!1,g(w);continue}}if(R==="NOFILE"){l(),o=null,d=!0;continue}if(R==="!DATA"){C(),l(),o=null,d=!1,u={name:L.slice(5).trim(),chunks:[]};continue}if(d)continue;if(u){if(M[1]==="!:")u.chunks.push(M.slice(2).join(""));continue}if(!o)g(t);let T={t:0,text:L};if(M[1]==="STEP")T.step=!0,f=[],a=null;else if(M[1]==="BFC")T.bfc=M.slice(2).join(" ");else if(M[1]==="ROTSTEP")if(T.meta="ROTSTEP",T.step=!0,f=[],a=null,(M[2]??"").toUpperCase()==="END")T.rotstep={x:0,y:0,z:0,mode:"END"};else{let w=(M[5]??"REL").toUpperCase(),E=(z)=>{let k=Number(z);return Number.isFinite(k)?k:0};T.rotstep={x:E(M[2]),y:E(M[3]),z:E(M[4]),mode:["REL","ABS","ADD"].includes(w)?w:"REL"}}else if(M[1]==="BUFEXCHG"){T.meta="BUFEXCHG";let w=(M[2]??"").toUpperCase();T.bufexchg={op:w==="RETRIEVE"?"RETRIEVE":"STORE",buf:M[3]??"A"}}else if(M[1]?.startsWith("!"))T.meta=M[1];if(m&&!o.org){let w=rt(L);if(w)o.org=w}if(M[1]==="!TEXMAP"){let w=(M[2]??"").toUpperCase();if(a=null,w==="START"||w==="NEXT"){let E=qt(L.replace(/^!TEXMAP\\s+\\S+/i,""),w==="NEXT");if(T.texmap={op:w,...E?{map:E}:{}},E)if((o.texmaps??=[]).push(E),w==="START")f.push({map:E,fallback:!1});else a=E}else if(w==="FALLBACK"){T.texmap={op:w};let E=f[f.length-1];if(E)E.fallback=!0}else if(w==="END")T.texmap={op:w},f.pop()}else if(M[1]==="!:"){a=null;let w=st(M.slice(2));if(w)A(w,!0),T.geom=w}else a=null;let x=L.match(nt);if(x&&!o.movedTo){let w=x[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(w))w+=".dat";o.movedTo=ne(w)}o.cmds.push(T);continue}if(u||d)continue;if(!o)g(t);let v=st(M);if(!v){if(/^[2-5][ \\t]/.test(h))m=!1;continue}A(v,!1),o.cmds.push(v),m=!1}return l(),c?{main:i,files:s,data:c}:{main:i,files:s}}var Pn=Math.PI/180;function mt(e,t){let n=(r)=>[t[3]*r[0]+t[4]*r[1]+t[5]*r[2]+t[0],t[6]*r[0]+t[7]*r[1]+t[8]*r[2]+t[1],t[9]*r[0]+t[10]*r[1]+t[11]*r[2]+t[2]];return{...e,p1:n(e.p1),p2:n(e.p2),p3:n(e.p3)}}function ht(e,t){let[n,r,s,o,i,c,u,f,a,l,m,g]=e,[d,b,C,A,p,h,M,D,v,L,R,T]=t;return[o*d+i*b+c*C+n,u*d+f*b+a*C+r,l*d+m*b+g*C+s,o*A+i*M+c*L,o*p+i*D+c*R,o*h+i*v+c*T,u*A+f*M+a*L,u*p+f*D+a*R,u*h+f*v+a*T,l*A+m*M+g*L,l*p+m*D+g*R,l*h+m*v+g*T]}var Ne=[0,0,0,1,0,0,0,1,0,0,0,1];var ot=new WeakMap,rn=/^(s|8|48)\\//;function ze(e,t){let n=e.files.get(ne(t));if(!n)return"part";let r=ot.get(n);if(r)return r;if(n.org)r=ft.has(n.org)?"part":"model";else if(n.name===e.main)r="model";else r=n.cmds.some((s)=>s.t>=2||s.t===0&&!!s.geom||s.t===1&&rn.test(s.file))?"part":"model";return ot.set(n,r),r}var it=new WeakMap;function gt(e){let t=it.get(e);if(t)return t;t=[];let n=0;for(let r of e.cmds){if(r.t===0&&r.step){n++;continue}if((r.t>=2||r.t===0&&r.geom&&r.geom.t>=2)&&t[t.length-1]!==n)t.push(n)}return it.set(e,t),t}var at=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():e<0?Be.get(e)??String(e):String(e),sn=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${at(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${at(e.color)} ${e.p.join(" ")}`,$e=(e,t)=>`${ne(e)}#${t}`;function on(e,t){let n=[],r=0,s=(o)=>!!o&&o.t===0&&o.texmap?.op==="NEXT";for(let o of e.cmds){if(o.t===0){if(o.step){r++;continue}if(o.bfc!==void 0||o.meta==="!COLOUR"){n.push(o);continue}if(r!==t)continue;if(o.texmap)n.push(o);else if(o.geom){if(o.geom.t>=2)n.push(o);else if(s(n[n.length-1]))n.pop()}continue}if(r!==t)continue;if(o.t===1){if(s(n[n.length-1]))n.pop();continue}n.push(o)}return{name:$e(e.name,t),cmds:n}}function dt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...on(e,t).cmds.map(sn)].join(`\n`)+`\n`}function je(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function bt(e){let[t,n,r,s,o,i,c,u,f,a,l,m]=e,g=u*m-f*l,d=-(c*m-f*a),b=c*l-u*a,C=s*g+o*d+i*b;if(!Number.isFinite(C)||Math.abs(C)<0.000000000001)return null;let A=1/C,p=[g*A,-(o*m-i*l)*A,(o*f-i*u)*A,d*A,(s*m-i*a)*A,-(s*f-i*c)*A,b*A,-(s*l-o*a)*A,(s*u-o*c)*A];return[-(p[0]*t+p[1]*n+p[2]*r),-(p[3]*t+p[4]*n+p[5]*r),-(p[6]*t+p[7]*n+p[8]*r),...p]}var an=(e)=>String(+e.toFixed(6)||0),lt=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function yt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map(an).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${lt(t.texture)}${t.glossmap?" GLOSSMAP "+lt(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${ne(e)}\n0 !TEXMAP END\n`;return{name:`${ne(e)}#tex-${je(r)}`,source:r}}var ln=(e,t)=>{let n=[,,,,,,,,,];for(let r=0;r<3;r++)for(let s=0;s<3;s++)n[r*3+s]=e[r*3]*t[s]+e[r*3+1]*t[3+s]+e[r*3+2]*t[6+s];return n};function cn(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),c=Math.cos(t*r),u=Math.sin(n*r),f=Math.cos(n*r);return[c*f,-c*u,i,o*u+s*i*f,o*f-s*i*u,-s*c,s*u-o*i*f,s*f+o*i*u,o*c]}var ct=new WeakMap;function xt(e){let t=ct.get(e);if(t)return t;let n=[],r=null;for(let s of e.cmds){if(s.t!==0||!s.step)continue;let o=s.rotstep;if(o)if(o.mode==="END")r=null;else{let i=cn(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:ln(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),ct.set(e,n),n}class Ve extends Error{limit;code="ldr-model-limit";constructor(e,t){super(`ldr: ${e} expands past ${t.toLocaleString("en-US")} (see maxInstances)`);this.limit=t;this.name="ModelLimitError"}}var un=(e)=>{for(let t=0;t<12;t++)if(!(Math.abs(e[t])<=ut))return!1;return!0},wt=999999,vt=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~",Ct=new WeakMap,Mt=new WeakMap;function fn(e,t){let n=Mt.get(t);if(!n)n={head:[...t.values()].map((o)=>{let i=Ct.get(o)??"",c=i.indexOf("!COLOUR");return c<0?"":"0 "+i.slice(c).trim().replace(/\\s+/g," ")}).filter(Boolean).join(`\n`),parts:new Map},Mt.set(t,n);let r=n.parts.get(e);if(!r){let s=ne(e),o=`0 ldr: ${s} placed in a model\'s !COLOUR scope\n0 BFC CERTIFY CCW\n${n.head}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${s}\n`;r={name:`${s}#col-${je(o)}`,source:o},n.parts.set(e,r)}return r}function pn(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,c=new Map,u=0,f=new Set,a=t.maxInstances??2000000,l=0,m=(d,b)=>{let C=d.name+"#"+b,A=c.get(C);if(!A){let p;A=Object.assign(()=>p??=dt(d,b),{file:d,step:b}),c.set(C,A)}return A},g=(d,b,C,A,p,h,M,D,v=null,L=[],R=[],T=void 0,x=null)=>{let w=d.files.get(b);if(!w||M>r||f.has(w))return;if(++l>a)throw new Ve("model",a);f.add(w);let E=x,z=0,k=M>0?++u:0,P=i&&k?[...L,k]:L,Y=i&&k?[...R,C]:R,I=i&&!v?new Map:null,j=-1,H=0,Z=(S,y,B,_,W,X,N)=>{if(j!==z)j=z,H=0;let q=I?.get(z+"|"+y);if(q)return q.n++,g(S,S===d?y:S.main,B,_,p+"/"+y,[...W,wt],M+1,X,[...W,wt],P,Y,N,E);let U=[...W,H++],F=n.length;g(S,S===d?y:S.main,B,_,p+"/"+y,U,M+1,X,v,P,Y,N,E),I?.set(z+"|"+y,{n:1,from:F,to:n.length})},O=xt(w),G=s?gt(w):[],K=0,J=(S,y,B,_,W,X,N,q,U)=>{if(v)_=v;if(++l>a)throw new Ve("model",a);let F={part:S,color:y,m:B,step:_[0],steps:_,localStep:W,path:p};if(q)F.colour=q;if(k){if(F.sub=k,i)F.subPath=P,F.subMats=Y}if(X)F.embedded=!0;if(N){let re=yt(S,N);F.texPart=re.name,F.texSource=re.source}else if(U){let re=fn(S,U);F.colPart=re.name,F.colSource=re.source}let V=O[W];if(V)F.view=V;return n.push(F),F},Q=(S)=>{while(K<G.length&&G[K]<=S){let y=G[K++];J($e(w.name,y),A,C,[...h,y],y,!1,null,T,x).source=m(w,y)}};for(let S of w.cmds){if(S.t===0&&S.step){z++;continue}let y=S;if(y.t>=2||y.t===0&&y.geom&&y.geom.t>=2){Q(z);continue}if(y.t===0){if(y.meta==="!COLOUR"){let V=hn(y.text);if(V&&V.code!==16&&V.code!==24)Ct.set(V,y.text),(E=new Map(E??[])).set(V.code,V);continue}if(o&&y.geom?.t===1)y=y.geom;else continue}if(y.t!==1)continue;if(o&&y.fallback)continue;let B=ht(C,y.m);if(!un(B))continue;let _=y.color===16?A:y.color,W=y.color===16?T:E?.get(y.color),X=[...h,z],N=o?y.tex??D:null,q=N?bt(y.m):null,U=N&&q?mt(N,q):null;if(d.files.has(y.file)){if(ze(d,y.file)==="model"){Z(d,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!0,U,W,E);continue}let F=t.resolveModel?.(y.file);if(F){Z(F,y.file,B,_,X,U,W);continue}J(y.file,_,B,X,z,!1,U,W,E)}if(Q(1/0),f.delete(w),I){for(let S of I.values())if(S.n>1)for(let y=S.from;y<S.to;y++)n[y].mult??=S.n}};if(ze(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Ne],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return g(e,e.main,Ne,16,e.main,[],0,null),n}function Tt(e,t="main.ldr",n){return pn(pt(e,t,{geometryText:!0}),n)}var mn=new Set(["CHROME","PEARLESCENT","RUBBER","MATTE_METALLIC","METAL","MATERIAL"]);function _e(e){if(!e)return null;if(e.startsWith("#")&&/^#[0-9A-Fa-f]{6}$/.test(e))return e.toUpperCase();if(/^0x[0-9A-Fa-f]{6}$/i.test(e))return("#"+e.slice(2)).toUpperCase();return null}function At(e,t){let n={value:"#FFFFFF",fraction:0.5};while(t<e.length){let r=e[t].toUpperCase(),s=e[t+1];if(r==="VALUE"){let o=_e(s);if(o)n.value=o;t+=2}else if(r==="ALPHA")n.alpha=+s,t+=2;else if(r==="LUMINANCE")n.luminance=+s,t+=2;else if(r==="FRACTION")n.fraction=+s,t+=2;else if(r==="VFRACTION")n.vfraction=+s,t+=2;else if(r==="SIZE")n.size=+s,t+=2;else if(r==="MINSIZE")n.minsize=+s,t+=2;else if(r==="MAXSIZE")n.maxsize=+s,t+=2;else break}return{grain:n,next:t}}function hn(e){let t=e.indexOf("!COLOUR");if(t<0)return null;let n=e.slice(t+7).trim().split(/\\s+/).filter(Boolean);if(n.length<2)return null;let r=n[0],s=NaN,o="#FF00FF",i="#333333",c=255,u=0,f={type:"default"},a=1;while(a<n.length){let l=n[a].toUpperCase(),m=n[a+1];if(l==="CODE")s=m!==void 0&&De.test(m)?Ue(m):m!==void 0&&/^\\d+$/.test(m)?+m:NaN,a+=2;else if(l==="VALUE"){let g=_e(m);if(g)o=g;a+=2}else if(l==="EDGE")i=_e(m)??m,a+=2;else if(l==="ALPHA")c=+m,a+=2;else if(l==="LUMINANCE")u=+m,a+=2;else if(l==="CHROME")f={type:"chrome"},a+=1;else if(l==="PEARLESCENT")f={type:"pearlescent"},a+=1;else if(l==="RUBBER")f={type:"rubber"},a+=1;else if(l==="MATTE_METALLIC")f={type:"matte_metallic"},a+=1;else if(l==="METAL")f={type:"metal"},a+=1;else if(l==="MATERIAL"){let g=(n[a+1]||"").toUpperCase();if(g==="GLITTER"){let{grain:d,next:b}=At(n,a+2);f={type:"glitter",material:d},a=b}else if(g==="SPECKLE"){let{grain:d,next:b}=At(n,a+2);f={type:"speckle",material:d},a=b}else if(g==="FABRIC"){let d=(n[a+2]||"").toUpperCase(),b=["VELVET","CANVAS","STRING","FUR"].includes(d)?d.toLowerCase():void 0;f={type:"fabric",kind:b},a+=b?3:2}else a=n.length}else if(mn.has(l))a+=1;else a+=1}if(Number.isNaN(s)||!o)return null;return{code:s,name:r,hex:o,edge:i,alpha:Number.isFinite(c)?c:255,luminance:Number.isFinite(u)?u:0,finish:f}}function gn(e){let t=Math.max(0,Math.min(1,(e.alpha??255)/255)),n=t<1,r=Math.max(0,Math.min(1,(e.luminance??0)/255)),s={opacity:t,transparent:n,depthWrite:!n,emissive:r,clearcoat:0,clearcoatRoughness:0,sheen:0,sheenRoughness:0};switch(e.finish?.type??"default"){case"chrome":return{...s,metalness:1,roughness:0,finish:"chrome"};case"pearlescent":return{...s,metalness:0.25,roughness:0.3,clearcoat:0.5,clearcoatRoughness:0.25,sheen:0.4,sheenRoughness:0.35,finish:"pearlescent"};case"rubber":return{...s,metalness:0,roughness:0.9,finish:"rubber"};case"matte_metallic":return{...s,metalness:0.4,roughness:0.8,finish:"matte_metallic"};case"metal":return{...s,metalness:0.85,roughness:0.2,finish:"metal"};case"glitter":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.35,roughness:0.25,clearcoat:1,clearcoatRoughness:0.08,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"glitter"}}case"speckle":{let i=e.finish.material,c=i.size??(i.minsize!=null&&i.maxsize!=null?(i.minsize+i.maxsize)/2:1);return{...s,metalness:0.2,roughness:0.55,particleHex:i.value,particleFraction:i.fraction,particleSize:c,finish:"speckle"}}case"fabric":return{...s,metalness:0,roughness:0.85,sheen:0.65,sheenRoughness:0.75,finish:"fabric"};default:return{...s,metalness:0,roughness:0.45,finish:"default"}}}function He(e){let t=gn(e),n=!t.transparent?"op":t.opacity>=0.75?"a200":t.opacity>=0.4?"a128":`a${Math.round(t.opacity*255)}`,r=t.emissive>0?`L${Math.round(t.emissive*16)}`:"",s=`${t.finish}:${n}${r}`;if(t.particleHex)s+=`:${t.particleHex}:${(t.particleFraction??0).toFixed(2)}`;return s}function dn(e,t){let n=new Map,r=null,s=!1,o=!1;for(let i of e.split(/\\r?\\n/)){let c=/^\\s*0\\s+FILE\\s+(\\S[^\\r]*)/i.exec(i);if(c){if(!s)n.clear();s=!0,o=!1,r=[],n.set(ne(c[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(i)){if(!s&&/!DATA/i.test(i))n.clear(),s=!0;r=null,o=!0;continue}if(!r){if(s||o)continue;r=[],n.set(ne(t),r)}let u=i.trim().replace(/\\s+/g," ");if(u)r.push(u)}return n}var bn=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?ne(t.slice(14).join(" ")):null};function yn(e){let t=2166136261,n=1523705862;for(let r=0;r<e.length;r++){let s=e.charCodeAt(r);t=Math.imul(t^s,16777619),n=Math.imul(n^s,16777629)^n>>>15}return(t>>>0).toString(16).padStart(8,"0")+(n>>>0).toString(16).padStart(8,"0")}function Lt(e,t,n="main.ldr"){let r=dn(e,n),s=new Map;for(let o of t){let i=ne(o);if(!r.has(i)||s.has(i))continue;let c=new Set([i]),u=[i];while(u.length)for(let a of r.get(u.pop())){let l=bn(a);if(l&&r.has(l)&&!c.has(l))c.add(l),u.push(l)}let f=[i,...[...c].filter((a)=>a!==i).sort()].map((a)=>"0 FILE "+(a===i?"":a)+`\n`+r.get(a).join(`\n`)).join(`\n`);s.set(i,`emb/${yn(f)}.dat`)}return s}var St=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,Et=new WeakMap;function Ge(e,t){let n=Et.get(e);if(!n)Et.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),c=[],u=[];s.studs.forEach((m,g)=>{c.push(m[0]),u.push(m[1]);for(let d=0;d<12;d++)i[g*12+d]=m[2+d]});let f=null,a=0,l=0;if(s.mask){a=s.mask[0],l=s.mask[1];let m=s.mask[2];f=new Uint8Array(m.length);for(let g=0;g<m.length;g++)f[g]=m.charCodeAt(g)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:c,color:u,mask:f,nx:a,nz:l}),r}var fe=1073741824;class We{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,c=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&c[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,c=this.b,u=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,c[s]=t,u[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&c[s]===t&&u[s]===n){let f=this.vals[s];return this.vals[s]=r,f}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var pe=(e,t,n)=>e>-fe&&e<fe&&t>-fe&&t<fe&&n>-fe&&n<fe,de=2147483647;function xn(e,t){let n=e.colorTable?.[t];if(n)return(n.alpha??255)<255;return t.charCodeAt(0)===35&&/\\/[^:/]*:a\\d/.test(t)}function wn(e,t,n){let s=new Map,o=(I)=>{let j=s.get(I);if(j===void 0)s.set(I,j=xn(t,I));return j},i=[],c=[],u=[],f=[],a=[],l=[],m=[],g=[],d=[],b=new We(e.length*2),C=[],A=[];for(let I=0;I<e.length;I++){let j=e[I],H=j.m,Z=t.parts[j.part];if(!Z||!Z.mask||!St(H)||o(j.color))continue;let O=Z.bbox,G=1/0,K=-1/0,J=1/0,Q=-1/0;for(let U=0;U<2;U++)for(let F=0;F<2;F++){let V=U?O[3]:O[0],re=F?O[5]:O[2],oe=H[0]+H[3]*V+H[5]*re,se=H[2]+H[9]*V+H[11]*re;if(oe<G)G=oe;if(oe>K)K=oe;if(se<J)J=se;if(se>Q)Q=se}let S=Math.round((H[1]+O[4])*2),y=Ge(t,j.part),B=Math.floor(G/40),_=Math.floor(K/40),W=Math.floor(J/40),X=Math.floor(Q/40);if(!((_-B+1)*(X-W+1)<=65536)||!pe(S,B,W)||!pe(S,_,X))continue;let N=-1;for(let U=b.get(S,B,W),F=0;U>=0&&F<8;U=C[U],F++){let V=A[U];if(i[V]!==G||c[V]!==K||u[V]!==J||f[V]!==Q||m[V]!==y)continue;let re=e[a[V]].m,oe=!0;for(let se=0;se<12;se++)if(re[se]!==H[se]){oe=!1;break}if(oe){N=V;break}}if(N>=0){let U=n?n[I]:0;if(n&&U<n[a[N]])l[N]=a[N],a[N]=I;else if(l[N]<0||n&&U<n[l[N]])l[N]=I;continue}let q=a.length;i.push(G),c.push(K),u.push(J),f.push(Q),a.push(I),l.push(-1),m.push(y),g.push(O[0]),d.push(O[2]);for(let U=B;U<=_;U++)for(let F=W;F<=X;F++){if(!pe(S,U,F))continue;let V=A.length;A.push(q),C.push(b.put(S,U,F,V))}}let p=[0,5,-5,5,-5],h=[0,5,5,-5,-5],M=NaN,D=NaN,v=NaN,L=-1,R=(I,j,H,Z)=>{let O=Math.round(j*2),G=Math.floor(I/40),K=Math.floor(H/40);if(!pe(O,G,K))return de;let J=de;if(O!==M||G!==D||K!==v)M=O,D=G,v=K,L=b.get(O,G,K);for(let Q=L;Q>=0;Q=C[Q]){let S=A[Q],y=a[S];if(y===Z&&(y=l[S])<0)continue;if(!(I-6>=i[S]-0.5&&I+6<=c[S]+0.5&&H-6>=u[S]-0.5&&H+6<=f[S]+0.5))continue;let B=e[a[S]].m,_=m[S],W=g[S],X=d[S],N=I-B[0],q=j-B[1],U=H-B[2],F=B[3]*N+B[6]*q+B[9]*U,V=B[5]*N+B[8]*q+B[11]*U,{nx:re,nz:oe,mask:se}=_,ce=!0;for(let ie=0;ie<5;ie++){let ae=Math.floor((F+p[ie]-W)/20),ue=Math.floor((V+h[ie]-X)/20);if(ae<0||ue<0||ae>=re||ue>=oe||se[ae*oe+ue]!==1){ce=!1;break}}if(ce){if(!n)return 0;let ie=n[y];if(ie<J)J=ie}}return J},T=0;for(let I of e){let j=Ge(t,I.part);if(j)T+=j.nStuds}let x=new Uint8Array(T),w=new Uint8Array(T),E=new We(T),z=0,k=n?new Int32Array(T).fill(de):void 0;for(let I=0,j=0;I<e.length;I++){let H=e[I],Z=Ge(t,H.part);if(!Z)continue;let O=H.m,G=Z.studM,K=O[0],J=O[1],Q=O[2],S=O[3],y=O[4],B=O[5],_=O[6],W=O[7],X=O[8],N=O[9],q=O[10],U=O[11];for(let F=0;F<Z.nStuds;F++,j++){let V=F*12,re=G[V+4],oe=G[V+7],se=G[V+10];if(!(Math.abs(_*re+W*oe+X*se-1)<0.001&&Math.abs(S*re+y*oe+B*se)<0.001&&Math.abs(N*re+q*oe+U*se)<0.001))continue;w[j]=1;let ce=G[V],ie=G[V+1],ae=G[V+2],ue=K+S*ce+y*ie+B*ae,Ke=J+_*ce+W*ie+X*ae,Xe=Q+N*ce+q*ie+U*ae,Ze=R(ue,Ke,Xe,I);if(Ze!==de){if(x[j]=1,z++,k)k[j]=Ze}let be=Math.round(ue),ye=Math.round(Ke),xe=Math.round(Xe);if(!pe(be,ye,xe))continue;if(!n){E.put(be,ye,xe,1);continue}let Ye=n[I],Je=E.get(be,ye,xe);if(Je<0||Ye<Je)E.put(be,ye,xe,Ye)}}let P=new Uint8Array(e.length),Y=n?new Int32Array(e.length).fill(de):void 0;for(let I=0;I<e.length;I++){let j=e[I],H=t.parts[j.part];if(!H||!H.under||!St(j.m)||o(j.color))continue;let Z=H.bbox,O=Math.round((Z[3]-Z[0])/20),G=Math.round((Z[5]-Z[2])/20);if(!O||!G||O*G>4096)continue;let K=j.m,J=!0,Q=0;for(let S=0;S<O&&J;S++)for(let y=0;y<G;y++){let B=Z[0]+10+20*S,_=Z[2]+10+20*y,W=K[0]+K[3]*B+K[5]*_,X=K[2]+K[9]*B+K[11]*_,N=Math.round(W),q=Math.round(K[1]+Z[4]),U=Math.round(X),F=pe(N,q,U)?E.get(N,q,U):-1;if(F<0){J=!1;break}if(F>Q)Q=F}if(J){if(P[I]=1,Y)Y[I]=Q}}return{nStuds:T,studHidden:x,studUp:w,underHidden:P,studsHidden:z,studHideStep:k,underHideStep:Y}}function Mn(e,t,n){let r=(l)=>l.colPart&&t.parts[l.colPart]?l.colPart:n&&l.texPart&&t.parts[l.texPart]?l.texPart:l.part,s=new Map,o=new Map,i=(l)=>{let m=l.colour;if(!m)return String(l.color);let g=o.get(m);if(g!==void 0)return g;let d=t.colorTable?.[l.color],b=d?.hex??t.colors?.[l.color],C=d?He({alpha:d.alpha??255,luminance:d.luminance??0,finish:d.finish??{type:"default"}}):"default:op",A=He(m);if(g=b&&b.toUpperCase()===m.hex.toUpperCase()&&C===A?String(l.color):m.hex.toUpperCase()+"/"+A,g!==String(l.color))s.set(g,m);return o.set(m,g),g},c=e.map((l)=>({part:r(l),color:i(l),m:l.m,steps:l.steps})),u=c.map((l)=>vt(l.steps)),f=[...new Set(u)].sort(),a=new Map(f.map((l,m)=>[l,m]));return{all:c,stepOf:u.map((l)=>a.get(l)),nSteps:f.length,localColours:s}}function Ce(e,t,n=!0){let r=Mn(e,t,n);return wn(r.all,t,r.nSteps>1?r.stepOf:void 0)}var ke="https://ldr-demo.vercel.app/cdn/v1/",Le=new Map,Te=new Map;function Se(e=ke,t=fetch){let n=Le.get(e);if(!n)n=t(e+"parts.json").then((r)=>{if(!r.ok)throw Error(`ldr: parts CDN index ${r.status} (${e}parts.json)`);return r.json()}),n.catch(()=>Le.delete(e)),Le.set(e,n);return n}var An=(e)=>Array.isArray(e)&&e.length===3&&typeof e[0]==="number"&&typeof e[1]==="number"&&(e[2]==="f32"||e[2]==="u16"||e[2]==="u8"||e[2]==="u32"),Ee=(e,t)=>An(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>Ee(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,Ee(r,t)])):e;function vn(e,t={}){let n=[],r=0,s={},o={};for(let m of e){let g=m.buffer;if(!g)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let d=new DataView(g).getUint32(0,!0),b=new Uint8Array(g,4+d),C=r;n.push(b),r+=b.byteLength;let A=(4-r%4)%4;if(A)n.push(new Uint8Array(A)),r+=A;for(let[p,h]of Object.entries(m.header.parts??{}))if(!(p in s))s[p]=Ee(h,C);for(let[p,h]of Object.entries(m.header.studKinds??{}))if(!(p in o))o[p]=Ee(h,C)}let i=e[0]?.header??{version:1,weld:!0},c=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),u=(4-(4+c.length)%4)%4,f=4+c.length+u,a=new Uint8Array(f+r);new DataView(a.buffer).setUint32(0,c.length+u,!0),a.set(c,4),a.fill(32,4+c.length,f);let l=f;for(let m of n)a.set(m,l),l+=m.byteLength;return ve(a.buffer)}async function Cn(e,t={}){e=[...e];try{return await kt(e,t)}catch(n){let r=t.cdn??ke,s=t.fetch??fetch;Le.delete(r);let o=(i,c)=>s(i,{...c,cache:"reload"});try{return await kt(e,{...t,fetch:o})}catch{throw n}}}async function kt(e,t){let n=t.cdn??ke,r=t.fetch??fetch,s=t.gap??16384,o=await Se(n,r),i=[...new Set([...e].map(ne))],c=[],u=[];for(let p of i){if(Te.has(n+p))continue;let h=o.parts[p];if(h)u.push({name:p,off:h[0],len:h[1],file:h[2]??0});else c.push(p)}u.sort((p,h)=>p.file-h.file||p.off-h.off);let f=[];for(let p of u){let h=f[f.length-1];if(h&&h.file===p.file&&p.off-h.end<=s)h.end=Math.max(h.end,p.off+p.len),h.items.push(p);else f.push({file:p.file,start:p.off,end:p.off+p.len,items:[p]})}let a=0,l=0,m=0,g=new Map,d=async()=>{while(m<f.length){let p=f[m++],h=g.get(p.file);if(h)h=h.subarray(p.start,p.end);else{let M=await r(new URL(o.archives[p.file],n).href,{headers:{Range:`bytes=${p.start}-${p.end-1}`,"Accept-Encoding":"identity"}});if(!M.ok)throw Error(`ldr: parts CDN ${M.status}`);if(l++,h=new Uint8Array(await M.arrayBuffer()),a+=h.byteLength,M.status===200)g.set(p.file,h),h=h.subarray(p.start,p.end)}for(let M of p.items){let D=Ae(h.subarray(M.off-p.start,M.off-p.start+M.len)),v=D.buffer.slice(D.byteOffset,D.byteOffset+D.byteLength);Te.set(n+M.name,ve(v))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,f.length)},d));let b=i.filter((p)=>Te.has(n+p)).map((p)=>Te.get(n+p)),C={colors:o.colors,...o.colorTable?{colorTable:o.colorTable}:{}};return{pack:b.length?vn(b,C):ve(Tn(C)),missing:c,requests:l,bytes:a}}function Tn(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},...e})),n=(4-(4+t.length)%4)%4,r=new Uint8Array(4+t.length+n).fill(32);return new DataView(r.buffer).setUint32(0,t.length+n,!0),r.set(t,4),r.buffer}function Ln(e,t){let n=t.header.parts;if(!n)return 0;let r=0;for(let s of e){let o=n[s.part]?.body?.tris;if(o)r+=o}return r}function Pt(e,t,n){let r=0,s=0,o=!1,i=new Set;for(let c of e){let u=c.embedded?t.get(c.part):ne(c.part),f=u?n.parts[u]:void 0;if(!f)continue;if(f[3]!=null)o=!0,r+=f[3];if(!i.has(u))i.add(u),s+=f[1]}return{bodyTris:r,packBytes:s,known:o}}class Pe extends Error{code="ldr-budget";bodyTris;packBytes;maxBodyTris;maxPackBytes;constructor(e){let t=[e.maxBodyTris!=null&&e.bodyTris>e.maxBodyTris?`${e.bodyTris} triangles (limit ${e.maxBodyTris})`:"",e.maxPackBytes!=null&&e.packBytes>e.maxPackBytes?`${(e.packBytes/1e6).toFixed(1)} MB parts pack (limit ${(e.maxPackBytes/1e6).toFixed(0)} MB)`:""].filter(Boolean).join(", ");super(`ldr: model exceeds device budget: ${t}`);this.name="BudgetError",this.bodyTris=e.bodyTris,this.packBytes=e.packBytes,this.maxBodyTris=e.maxBodyTris,this.maxPackBytes=e.maxPackBytes}}async function It(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=Se(t.cdn??ke,r);s.catch(()=>{});let o=t.text?e:await r(e).then(async(x)=>{if(!x.ok)throw Error(`ldr: ${x.status} fetching ${e}`);return et(await x.arrayBuffer())}),i=performance.now(),c=t.name??(t.text?"main.ldr":tt(e)),u=Tt(o,c,{looseGeometry:!1,callouts:t.callouts}),f=performance.now();t.onParsed?.(u),await s;let a=Lt(o,new Set(u.filter((x)=>x.embedded).map((x)=>x.part)),c),l=(x,w)=>t.maxBodyTris!=null&&x>t.maxBodyTris||t.maxPackBytes!=null&&w>t.maxPackBytes,m=t.maxBodyTris!=null||t.maxPackBytes!=null,g=(x)=>new Pe({...x,maxBodyTris:t.maxBodyTris,maxPackBytes:t.maxPackBytes}),d="full";if(m){let x=Pt(u,a,await s);if(l(x.known?x.bodyTris:0,x.packBytes)){if(!t.lowCdn)throw g(x);let w=await Se(t.lowCdn,r).catch(()=>null);if(!w)throw g(x);let E=Pt(u,a,w);if(l(E.known?E.bodyTris:0,E.packBytes))throw g(E);d="low"}}let b=[...u.filter((x)=>!x.embedded).map((x)=>x.part),...a.values()],C=async()=>{let x=await Cn(b,d==="low"?{...t,cdn:t.lowCdn}:t);for(let[w,E]of a){let z=x.pack.header.parts[E];if(z)x.pack.header.parts[w]=z}return{...x,packBytes:x.pack.buffer?.byteLength??x.pack.bytes??0,bodyTris:Ln(u,x.pack)}},A=await C();if(m&&l(A.bodyTris,A.packBytes)&&d==="full"&&t.lowCdn&&await Se(t.lowCdn,r).then(()=>!0,()=>!1)){d="low";let x=A;A=await C(),A.requests+=x.requests,A.bytes+=x.bytes}if(m&&l(A.bodyTris,A.packBytes))throw g(A);let{pack:p,missing:h,requests:M,bytes:D}=A,v=new Map([...a].map(([x,w])=>[w,x])),L=h.map((x)=>v.get(x)??x),R=performance.now(),T=t.cull?Ce(u,p.header,t.textures!==!1):void 0;return{insts:u,pack:p,tier:d,missing:L,requests:M,bytes:D,cull:T,timings:{fetchModel:i-n,parse:f-i,parts:R-f,...T?{cull:performance.now()-R}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await It(n,{...r,cull:!1,onParsed:(a)=>self.postMessage({id:t,insts:a})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,tier:s.tier,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),c=Ce(s.insts,s.pack.header,r.textures!==!1),u=performance.now()-i,f=[];for(let a of[c.studHidden,c.studUp,c.underHidden,c.studHideStep,c.underHideStep])if(a)f.push(a.buffer);self.postMessage({id:t,cull:c,ms:u},f)}catch(s){if(s instanceof Pe||s?.code==="ldr-budget")self.postMessage({id:t,phase:"error",error:String(s?.message??s),budget:{bodyTris:s.bodyTris,packBytes:s.packBytes,maxBodyTris:s.maxBodyTris,maxPackBytes:s.maxPackBytes}});else self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
|
|
4798
4953
|
|
|
4799
|
-
// ../../../../../../../tmp/ldr-build-
|
|
4954
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/cdn.ts
|
|
4800
4955
|
var worker;
|
|
4801
4956
|
var seq = 0;
|
|
4802
4957
|
var pending = new Map;
|
|
@@ -4910,7 +5065,7 @@ async function loadModel(source, o = {}) {
|
|
|
4910
5065
|
timings: { ...prep.timings, parts: t3 - t0 - prep.timings.fetchModel - prep.timings.parse, build: t4 - t3, total: t4 - t0 }
|
|
4911
5066
|
});
|
|
4912
5067
|
}
|
|
4913
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5068
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/library.ts
|
|
4914
5069
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
4915
5070
|
import { join } from "path";
|
|
4916
5071
|
var xf = (m, x, y, z) => [m[3] * x + m[4] * y + m[5] * z + m[0], m[6] * x + m[7] * y + m[8] * z + m[1], m[9] * x + m[10] * y + m[11] * z + m[2]];
|
|
@@ -5260,11 +5415,11 @@ class Library {
|
|
|
5260
5415
|
return insts;
|
|
5261
5416
|
}
|
|
5262
5417
|
}
|
|
5263
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5418
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/build-pack.ts
|
|
5264
5419
|
import fs3 from "node:fs";
|
|
5265
5420
|
import path3 from "node:path";
|
|
5266
5421
|
|
|
5267
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5422
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/resolver.ts
|
|
5268
5423
|
import fs from "node:fs";
|
|
5269
5424
|
import path from "node:path";
|
|
5270
5425
|
var TOP_STUD_RE = /^(stud|studa|stud2|stud2a|stud6|stud6a|stud10|stud15|stud2s|stud2s2|stud-logo\d*|stud2-logo\d*)\.dat$/i;
|
|
@@ -5593,11 +5748,11 @@ function collectDeps(lib, refs) {
|
|
|
5593
5748
|
return out;
|
|
5594
5749
|
}
|
|
5595
5750
|
|
|
5596
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5751
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/compile.ts
|
|
5597
5752
|
import fs2 from "node:fs";
|
|
5598
5753
|
import path2 from "node:path";
|
|
5599
5754
|
|
|
5600
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5755
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/lod.ts
|
|
5601
5756
|
import { MeshoptSimplifier, MeshoptEncoder } from "meshoptimizer";
|
|
5602
5757
|
await Promise.all([MeshoptSimplifier.ready, MeshoptEncoder.ready]);
|
|
5603
5758
|
function reorderMesh(P, N, C, I) {
|
|
@@ -5620,7 +5775,7 @@ function reorderMesh(P, N, C, I) {
|
|
|
5620
5775
|
}
|
|
5621
5776
|
return { P: P2, N: N2, C: C2, I: idx };
|
|
5622
5777
|
}
|
|
5623
|
-
var TARGETS = [0.25, 0.
|
|
5778
|
+
var TARGETS = [0.25, 0.16, 0.1, 0.065, 0.04, 0.025];
|
|
5624
5779
|
var HALF = 0.4;
|
|
5625
5780
|
var HALF_ERR_SCALE = 1.5;
|
|
5626
5781
|
var MIN_TRIS = 64;
|
|
@@ -5800,10 +5955,16 @@ function lodChain(P, C, I, half = false) {
|
|
|
5800
5955
|
out.unshift(h);
|
|
5801
5956
|
}
|
|
5802
5957
|
}
|
|
5958
|
+
for (let i = out.length - 2, min = out.length ? out[out.length - 1].err : 0;i >= 0; i--) {
|
|
5959
|
+
if (out[i].err >= min)
|
|
5960
|
+
out.splice(i, 1);
|
|
5961
|
+
else
|
|
5962
|
+
min = out[i].err;
|
|
5963
|
+
}
|
|
5803
5964
|
return out;
|
|
5804
5965
|
}
|
|
5805
5966
|
|
|
5806
|
-
// ../../../../../../../tmp/ldr-build-
|
|
5967
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/compile.ts
|
|
5807
5968
|
class BfcState {
|
|
5808
5969
|
accum;
|
|
5809
5970
|
ccw = true;
|
|
@@ -6735,7 +6896,7 @@ function encodePack(parts, studKinds, weld, extra, options = {}) {
|
|
|
6735
6896
|
return Buffer.concat([head, ...chunks.map((c) => new Uint8Array(c.buffer, c.byteOffset, c.byteLength))]);
|
|
6736
6897
|
}
|
|
6737
6898
|
|
|
6738
|
-
// ../../../../../../../tmp/ldr-build-
|
|
6899
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/build-pack.ts
|
|
6739
6900
|
function packCompilerOpts(o) {
|
|
6740
6901
|
return { studs: o.studs ?? "low", prims: o.primitives ?? "full", weld: o.weld ?? true, separateStuds: true, cond: !!o.cond, tex: !!o.textures, ...o.partWorkLimit ? { workLimit: o.partWorkLimit } : {} };
|
|
6741
6902
|
}
|
|
@@ -6807,7 +6968,7 @@ function buildPack(o) {
|
|
|
6807
6968
|
const warnings = [...lib.conflicts].map((n) => `${n}: defined differently by two models; the first definition is used`);
|
|
6808
6969
|
return { data: encodePack(parts, kinds, comp.opts.weld, extra, { texture, lod: o.lod !== false, reorder: !!o.reorder }), parts: parts.size, studKinds: kinds.size, missing: [...missing], ...warnings.length ? { warnings } : {} };
|
|
6809
6970
|
}
|
|
6810
|
-
// ../../../../../../../tmp/ldr-build-
|
|
6971
|
+
// ../../../../../../../tmp/ldr-build-QsxkBH/src/node/promote.ts
|
|
6811
6972
|
var GEOM = /^\s*[2-5]\s/;
|
|
6812
6973
|
var REF = /^\s*1\s/;
|
|
6813
6974
|
var FILE = /^\s*0\s+FILE\s+(\S.*?)\s*$/i;
|
package/dist/render.d.ts
CHANGED
|
@@ -84,12 +84,19 @@ export declare function computeCulling(insts: Inst[], H: any): {
|
|
|
84
84
|
}[];
|
|
85
85
|
underHidden: boolean[];
|
|
86
86
|
};
|
|
87
|
+
export declare function studHole(b: any, arr?: (r: any) => any): {
|
|
88
|
+
r: number;
|
|
89
|
+
out: number;
|
|
90
|
+
} | null;
|
|
87
91
|
/** Square-stud outline (Round 67): a stud kind whose edge lines are only horizontal round loops of radius 6 about its axis (the
|
|
88
92
|
* plain stud: top and foot circle) gets, per loop, the 4-segment square of the square-stud level (half-width `w`) at that height,
|
|
89
93
|
* in place of its 8- / 16-segment circle. Its corners are as far out as the square stud's (2.49 LDU at w = 6), so it is drawn where
|
|
90
94
|
* the square stud is. Each segment keeps its round loop's segment length for edge LOD, so a loop is drawn at exactly the distances
|
|
91
95
|
* its circle was. Null for anything else (partial loops, other radii, slanted lines): those keep their round lines. */
|
|
92
|
-
export declare function studSquareLines(E: ArrayLike<number>, w: number
|
|
96
|
+
export declare function studSquareLines(E: ArrayLike<number>, w: number, hole?: {
|
|
97
|
+
r: number;
|
|
98
|
+
w: number;
|
|
99
|
+
}): {
|
|
93
100
|
pos: Float32Array;
|
|
94
101
|
lens: Float32Array;
|
|
95
102
|
} | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ldr",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.8",
|
|
4
4
|
"description": "High-performance LEGO (LDraw) rendering for three.js: instanced parts packs, hidden stud/tube culling, low-detail studs, indexed edges, build steps.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Evan Bacon",
|