ldr 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/spec.ts
1
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/spec.ts
2
2
  var norm = (s) => s.trim().toLowerCase().replace(/\\/g, "/").replace(/\/+/g, "/");
3
3
  function parseColor(tok) {
4
4
  if (/^0x/i.test(tok))
@@ -689,7 +689,7 @@ function fileStepViews(f) {
689
689
  viewMemo.set(f, out);
690
690
  return out;
691
691
  }
692
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/model.ts
692
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/model.ts
693
693
  var CALLOUT_END = 999999;
694
694
  var stepKey = (steps) => steps.map((x) => String(x).padStart(6, "0")).join(".") + "~";
695
695
  function flatten(doc, opts = {}) {
@@ -847,7 +847,7 @@ function parseLDConfig(text) {
847
847
  }
848
848
  return out;
849
849
  }
850
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/instructions.ts
850
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/instructions.ts
851
851
  var MIN_VIS = 0.5;
852
852
  var REORIENT = 0.35;
853
853
  var deg = Math.PI / 180;
@@ -1215,10 +1215,10 @@ function planStepViews(insts, parts, stepOf, nSteps, o = {}) {
1215
1215
  }
1216
1216
  };
1217
1217
  }
1218
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/render.ts
1218
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/render.ts
1219
1219
  import * as THREE from "three";
1220
1220
 
1221
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/pack-io.ts
1221
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/pack-io.ts
1222
1222
  import { decompress } from "fzstd";
1223
1223
  async function decompressPack(data) {
1224
1224
  const u = data instanceof Uint8Array ? data : new Uint8Array(data);
@@ -1237,7 +1237,7 @@ function decodePack(buf) {
1237
1237
  return { header, arr, bytes: buf.byteLength, buffer: buf };
1238
1238
  }
1239
1239
 
1240
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/cull.ts
1240
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/cull.ts
1241
1241
  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;
1242
1242
  var prepCache = new WeakMap;
1243
1243
  function prepPart(H, part) {
@@ -1554,7 +1554,7 @@ function precomputeCull(instances, H, useTex = true) {
1554
1554
  return cullCore(s.all, H, s.nSteps > 1 ? s.stepOf : undefined);
1555
1555
  }
1556
1556
 
1557
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/render.ts
1557
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/render.ts
1558
1558
  async function loadPack(url) {
1559
1559
  const res = await fetch(url);
1560
1560
  if (!res.ok)
@@ -1619,7 +1619,9 @@ function makeMaterial(side) {
1619
1619
  m.onBeforeCompile = (s) => {
1620
1620
  s.vertexShader = `attribute vec4 ldrColor;
1621
1621
  ` + s.vertexShader.replace("#include <color_vertex>", `#include <color_vertex>
1622
- #ifdef USE_INSTANCING_COLOR
1622
+ #ifdef USE_BATCHING_COLOR
1623
+ vColor.rgb = ldrColor.a > 0.5 ? pow(ldrColor.rgb, vec3(2.2)) : getBatchingColor(getIndirectIndex(gl_DrawID)).rgb;
1624
+ #elif defined(USE_INSTANCING_COLOR)
1623
1625
  vColor.rgb = ldrColor.a > 0.5 ? pow(ldrColor.rgb, vec3(2.2)) : instanceColor.rgb; // baked LDConfig colours are sRGB
1624
1626
  #else
1625
1627
  vColor.rgb = pow(ldrColor.rgb, vec3(2.2));
@@ -1995,6 +1997,24 @@ class LdrLodRoot extends THREE.LOD {
1995
1997
  L = -1;
1996
1998
  if (c.boxErr !== undefined && c.boxErr * ppl <= tau)
1997
1999
  L = -1;
2000
+ if (c.mergedLod && L >= 0) {
2001
+ const { bm, gids, errs, underHid, cullUnder } = c.mergedLod;
2002
+ for (let i = 0;i < gids.length; i++) {
2003
+ let Li = 0;
2004
+ const er = errs[i];
2005
+ for (let j = er.length - 1;j > 0; j--)
2006
+ if (er[j] * ppl <= tau) {
2007
+ Li = j;
2008
+ break;
2009
+ }
2010
+ const gd = gids[i];
2011
+ if (gd?.length)
2012
+ bm.setGeometryIdAt(i, gd[Math.min(Li, gd.length - 1)]);
2013
+ if (underHid && !bm.userData._stepMode)
2014
+ bm.setVisibleAt(i, !(cullUnder && underHid[i]));
2015
+ }
2016
+ L = 0;
2017
+ }
1998
2018
  const e = ppl >= eppl;
1999
2019
  if (L !== c.cur || e !== c.edgeOk) {
2000
2020
  c.cur = L;
@@ -2192,6 +2212,7 @@ function buildLdrScene(insts, pack, P, color, mark) {
2192
2212
  let cull = P.cull ?? cullCore(insts, H, steps);
2193
2213
  mark("culling");
2194
2214
  const stepBatches = [];
2215
+ const stepBatched = [];
2195
2216
  const instM = steps ? new Float64Array(insts.length * 12) : null;
2196
2217
  const instPP = [];
2197
2218
  const palette = [];
@@ -2314,96 +2335,359 @@ function buildLdrScene(insts, pack, P, color, mark) {
2314
2335
  });
2315
2336
  const tris = (b) => b ? b.tris ?? 0 : 0;
2316
2337
  const kFor = (t) => LOD ? Math.max(256, Math.min(16384, Math.round(262144 / Math.max(1, t)))) : Infinity;
2338
+ const MERGE_MAX = 16;
2339
+ const geomVerts = (b) => {
2340
+ if (!b)
2341
+ return 0;
2342
+ const p = arr(b.pos);
2343
+ return p.length / 3;
2344
+ };
2345
+ const geomIdx = (b) => {
2346
+ if (!b)
2347
+ return 0;
2348
+ if (!b.idx)
2349
+ return geomVerts(b);
2350
+ return arr(b.idx).length;
2351
+ };
2352
+ const coldByMat = new Map;
2317
2353
  for (const [pk, idsAll] of byPart) {
2318
2354
  const part = pk.replace(/#m$/, "");
2319
2355
  const p = H.parts[part];
2320
2356
  const mat = p.uncert ? (nUncert++, matD) : pk.endsWith("#m") ? matB : matF;
2321
2357
  const textured = wantTex && !!p.tex;
2322
- const bodyB = textured ? p.tbody : p.body;
2323
- const body = geom(bodyB, arr);
2324
- const groups = gridClusters(idsAll.length, (i) => insts[idsAll[i]].m[0], (i) => insts[idsAll[i]].m[2], textured ? Infinity : kFor(tris(p.body) + tris(p.under)));
2325
- for (const g of groups) {
2326
- const ids = Array.from(g, (i) => idsAll[i]);
2327
- let bodyIm = null;
2328
- const lv0 = [];
2329
- const place = (im) => {
2330
- fillInstances(im, ids, insts, color);
2331
- instancedBoundingSphere(im);
2332
- im.userData.ldrPart = part;
2333
- root.add(im);
2334
- };
2335
- if (body) {
2336
- const im = bodyIm = newIM(body, mat, ids.length);
2337
- place(im);
2338
- lv0.push(im);
2339
- }
2340
- if (textured)
2341
- for (const tb of p.tex) {
2342
- const gg = geom(tb, arr);
2343
- const im = newIM(gg, texMat(tb.t, mat, !!tb.wrapU), ids.length);
2344
- texBatches++;
2358
+ if (textured || idsAll.length > MERGE_MAX) {
2359
+ const bodyB = textured ? p.tbody : p.body;
2360
+ const body = geom(bodyB, arr);
2361
+ const groups = gridClusters(idsAll.length, (i) => insts[idsAll[i]].m[0], (i) => insts[idsAll[i]].m[2], textured ? Infinity : kFor(tris(p.body) + tris(p.under)));
2362
+ for (const g of groups) {
2363
+ const ids = Array.from(g, (i) => idsAll[i]);
2364
+ let bodyIm = null;
2365
+ const lv0 = [];
2366
+ const place = (im) => {
2367
+ fillInstances(im, ids, insts, color);
2368
+ instancedBoundingSphere(im);
2369
+ im.userData.ldrPart = part;
2370
+ root.add(im);
2371
+ };
2372
+ if (body) {
2373
+ const im = bodyIm = newIM(body, mat, ids.length);
2374
+ place(im);
2345
2375
  lv0.push(im);
2346
- if (bodyIm) {
2347
- im.instanceMatrix = bodyIm.instanceMatrix;
2348
- im.instanceColor = bodyIm.instanceColor;
2349
- im.boundingSphere = bodyIm.boundingSphere;
2350
- root.add(im);
2351
- } else {
2352
- place(im);
2353
- bodyIm = im;
2376
+ }
2377
+ if (textured)
2378
+ for (const tb of p.tex) {
2379
+ const gg = geom(tb, arr);
2380
+ const im = newIM(gg, texMat(tb.t, mat, !!tb.wrapU), ids.length);
2381
+ texBatches++;
2382
+ lv0.push(im);
2383
+ if (bodyIm) {
2384
+ im.instanceMatrix = bodyIm.instanceMatrix;
2385
+ im.instanceColor = bodyIm.instanceColor;
2386
+ im.boundingSphere = bodyIm.boundingSphere;
2387
+ root.add(im);
2388
+ } else {
2389
+ place(im);
2390
+ bodyIm = im;
2391
+ }
2392
+ }
2393
+ if (bodyIm) {
2394
+ const cl = newCluster(bodyIm.boundingSphere);
2395
+ lv0.forEach((o) => o.onBeforeRender = trackVp);
2396
+ cl.lv.push({ objs: lv0, err: 0 }, ...textured ? [] : lodLevels(p.body, bodyIm, mat));
2397
+ if (EDGES && p.edges)
2398
+ addLines(p.edges, bodyIm, cl);
2399
+ addCond(p, bodyIm, cl);
2400
+ if (steps)
2401
+ stepBatches.push({ im: bodyIm, objs: [...cl.lv.flatMap((l) => l.objs), ...cl.lines, ...cl.cond], own: Int32Array.from(ids, (id) => steps[id]), hide: null, flag: "body", inst: Int32Array.from(ids), stud: null, col: Uint16Array.from(ids, (id) => instCol[id]) });
2402
+ }
2403
+ const under = geom(p.under, arr);
2404
+ const uGroups = !under ? [] : LOD && P.lodUnder !== false ? undersideGroups(ids, insts) : [{ ids, ax: null }];
2405
+ for (const { ids: uids, ax } of uGroups) {
2406
+ const ord = [...uids.filter((i) => !cull.underHidden[i]), ...uids.filter((i) => cull.underHidden[i])];
2407
+ const vis = uids.length - uids.reduce((a, i) => a + cull.underHidden[i], 0);
2408
+ stats.undersTotal += uids.length;
2409
+ stats.undersHidden += uids.length - vis;
2410
+ const im = newIM(under, mat, uids.length);
2411
+ fillInstances(im, ord, insts, color);
2412
+ im.onBeforeRender = trackVp;
2413
+ im.userData.ldrUnder = true;
2414
+ im.userData.ldrPart = part;
2415
+ instancedBoundingSphere(im);
2416
+ im.count = P.cullUnder ? vis : uids.length;
2417
+ root.add(im);
2418
+ const cl = newCluster(im.boundingSphere);
2419
+ cl.lv.push({ objs: [im], err: 0 }, ...lodLevels(p.under, im, mat));
2420
+ {
2421
+ const bl = p.body?.lod;
2422
+ const last = bl?.[bl.length - 1];
2423
+ if (LOD && P.lodUnder !== false && last && last.tris === 12)
2424
+ cl.boxErr = last.err;
2354
2425
  }
2426
+ if (ax) {
2427
+ let below = Infinity;
2428
+ for (const id of uids) {
2429
+ const m = insts[id].m;
2430
+ below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2431
+ }
2432
+ cl.below = below;
2433
+ cl.ax = ax.slice(0, 3);
2434
+ }
2435
+ addCond(p, im, cl, "under");
2436
+ const objs = [...cl.lv.flatMap((l) => l.objs), ...cl.cond];
2437
+ objs.forEach((o) => {
2438
+ if (!o.isInstancedMesh)
2439
+ o.geometry.instanceCount = im.count;
2440
+ });
2441
+ toggles.push({ mesh: countTo(() => objs), all: uids.length, visible: vis, flag: "under" });
2442
+ if (steps)
2443
+ stepBatches.push({ im, objs, own: Int32Array.from(ord, (id) => steps[id]), hide: Int32Array.from(ord, (id) => cull.underHideStep[id]), flag: "under", inst: Int32Array.from(ord), stud: null, col: Uint16Array.from(ord, (id) => instCol[id]) });
2444
+ }
2445
+ }
2446
+ } else {
2447
+ const list = coldByMat.get(mat) || coldByMat.set(mat, []).get(mat);
2448
+ list.push({ part, p, mat, ids: idsAll });
2449
+ }
2450
+ }
2451
+ const tmpM = new THREE.Matrix4;
2452
+ const tmpC = new THREE.Color;
2453
+ for (const [mat, items] of coldByMat) {
2454
+ const entries = [];
2455
+ for (const it of items)
2456
+ for (const id of it.ids)
2457
+ entries.push({ id, part: it.part, p: it.p });
2458
+ if (!entries.length)
2459
+ continue;
2460
+ const groups = gridClusters(entries.length, (i) => insts[entries[i].id].m[0], (i) => insts[entries[i].id].m[2], LOD ? 256 : Infinity);
2461
+ for (const g of groups) {
2462
+ const members = Array.from(g, (i) => entries[i]);
2463
+ const partSet = new Map;
2464
+ for (const m of members)
2465
+ partSet.set(m.part, m.p);
2466
+ let maxV = 0, maxI = 0;
2467
+ for (const p of partSet.values()) {
2468
+ for (const b of [p.body, ...p.body?.lod ?? []]) {
2469
+ maxV += geomVerts(b);
2470
+ maxI += geomIdx(b);
2471
+ }
2472
+ }
2473
+ if (maxV === 0)
2474
+ continue;
2475
+ const bm = new THREE.BatchedMesh(members.length, Math.max(1, maxV), Math.max(1, maxI), mat);
2476
+ bm.perObjectFrustumCulled = true;
2477
+ bm.sortObjects = false;
2478
+ bm.frustumCulled = true;
2479
+ bm.userData.ldrMerged = true;
2480
+ bm.onBeforeRender = trackVp;
2481
+ root.add(bm);
2482
+ const gidsByPart = new Map;
2483
+ for (const [part, p] of partSet) {
2484
+ const body = geom(p.body, arr);
2485
+ if (!body) {
2486
+ gidsByPart.set(part, []);
2487
+ continue;
2488
+ }
2489
+ const ids = [bm.addGeometry(body)];
2490
+ if (LOD && p.body?.lod)
2491
+ for (const l of p.body.lod)
2492
+ ids.push(bm.addGeometry(geom(l, arr)));
2493
+ gidsByPart.set(part, ids);
2494
+ }
2495
+ const live = members.filter((m) => (gidsByPart.get(m.part)?.length ?? 0) > 0);
2496
+ const instGids = new Array(live.length);
2497
+ const ownArr = steps ? new Int32Array(live.length) : null;
2498
+ const instArr = steps ? new Int32Array(live.length) : null;
2499
+ const m16 = new Float32Array(16);
2500
+ for (let i = 0;i < live.length; i++) {
2501
+ const { id, part, p } = live[i];
2502
+ const gids = gidsByPart.get(part);
2503
+ const iid = bm.addInstance(gids[0]);
2504
+ writeM4(m16, 0, insts[id].m);
2505
+ tmpM.fromArray(m16);
2506
+ bm.setMatrixAt(iid, tmpM);
2507
+ tmpC.copy(color(insts[id].color));
2508
+ bm.setColorAt(iid, tmpC);
2509
+ instGids[iid] = gids;
2510
+ if (ownArr) {
2511
+ ownArr[iid] = steps[id];
2512
+ instArr[iid] = id;
2513
+ }
2514
+ }
2515
+ members.length = 0;
2516
+ members.push(...live);
2517
+ bm.computeBoundingSphere();
2518
+ const cl = newCluster(bm.boundingSphere ?? new THREE.Sphere);
2519
+ const bodyErrs = live.map(({ p }) => [0, ...(p.body?.lod ?? []).map((l) => l.err)]);
2520
+ bm.userData.ldrMergeGids = instGids;
2521
+ cl.mergedLod = { bm, gids: instGids, errs: bodyErrs };
2522
+ cl.setMergedLevel = (L) => {
2523
+ bm.visible = L >= 0;
2524
+ };
2525
+ cl.lv.push({ objs: [bm], err: 0 });
2526
+ if (EDGES) {
2527
+ const byPartIds = new Map;
2528
+ for (const m of live) {
2529
+ const a = byPartIds.get(m.part) || byPartIds.set(m.part, []).get(m.part);
2530
+ a.push(m.id);
2355
2531
  }
2356
- if (bodyIm) {
2357
- const cl = newCluster(bodyIm.boundingSphere);
2358
- lv0.forEach((o) => o.onBeforeRender = trackVp);
2359
- cl.lv.push({ objs: lv0, err: 0 }, ...textured ? [] : lodLevels(p.body, bodyIm, mat));
2360
- if (EDGES && p.edges)
2361
- addLines(p.edges, bodyIm, cl);
2362
- addCond(p, bodyIm, cl);
2363
- if (steps)
2364
- stepBatches.push({ im: bodyIm, objs: [...cl.lv.flatMap((l) => l.objs), ...cl.lines, ...cl.cond], own: Int32Array.from(ids, (id) => steps[id]), hide: null, flag: "body", inst: Int32Array.from(ids), stud: null, col: Uint16Array.from(ids, (id) => instCol[id]) });
2365
- }
2366
- const under = geom(p.under, arr);
2367
- const uGroups = !under ? [] : LOD && P.lodUnder !== false ? undersideGroups(ids, insts) : [{ ids, ax: null }];
2368
- for (const { ids: uids, ax } of uGroups) {
2369
- const ord = [...uids.filter((i) => !cull.underHidden[i]), ...uids.filter((i) => cull.underHidden[i])];
2370
- const vis = uids.length - uids.reduce((a, i) => a + cull.underHidden[i], 0);
2371
- stats.undersTotal += uids.length;
2372
- stats.undersHidden += uids.length - vis;
2373
- const im = newIM(under, mat, uids.length);
2374
- fillInstances(im, ord, insts, color);
2375
- im.onBeforeRender = trackVp;
2376
- im.userData.ldrUnder = true;
2377
- im.userData.ldrPart = part;
2378
- instancedBoundingSphere(im);
2379
- im.count = P.cullUnder ? vis : uids.length;
2380
- root.add(im);
2381
- const cl = newCluster(im.boundingSphere);
2382
- cl.lv.push({ objs: [im], err: 0 }, ...lodLevels(p.under, im, mat));
2383
- {
2384
- const bl = p.body?.lod;
2385
- const last = bl?.[bl.length - 1];
2386
- if (LOD && P.lodUnder !== false && last && last.tris === 12)
2387
- cl.boxErr = last.err;
2532
+ for (const [partName, ids] of byPartIds) {
2533
+ const pp = partSet.get(partName);
2534
+ if (!pp)
2535
+ continue;
2536
+ if (!pp.edges && !(wantCond && (pp.condl || pp.condlu)))
2537
+ continue;
2538
+ const ghost = newIM(geom(pp.body, arr) || new THREE.BufferGeometry, mat, ids.length);
2539
+ fillInstances(ghost, ids, insts, color);
2540
+ const nL = cl.lines.length, nC = cl.cond.length;
2541
+ if (pp.edges)
2542
+ addLines(pp.edges, ghost, cl);
2543
+ addCond(pp, ghost, cl);
2544
+ if (steps)
2545
+ stepBatches.push({ im: ghost, objs: [ghost, ...cl.lines.slice(nL), ...cl.cond.slice(nC)], own: Int32Array.from(ids, (id) => steps[id]), hide: null, flag: "body", inst: Int32Array.from(ids), stud: null, col: Uint16Array.from(ids, (id) => instCol[id]) });
2388
2546
  }
2389
- if (ax) {
2390
- let below = Infinity;
2391
- for (const id of uids) {
2392
- const m = insts[id].m;
2393
- below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2547
+ }
2548
+ if (steps && ownArr)
2549
+ stepBatched.push({ bm, own: ownArr, hide: null, flag: "body", inst: instArr });
2550
+ const withUnder = members.filter((m) => m.p.under);
2551
+ if (withUnder.length) {
2552
+ const uEntries = withUnder.map((m) => m.id);
2553
+ const uGroups = LOD && P.lodUnder !== false ? undersideGroups(uEntries, insts) : [{ ids: uEntries, ax: null }];
2554
+ for (const { ids: uids, ax } of uGroups) {
2555
+ const byId = new Map(members.map((m) => [m.id, m]));
2556
+ const umembers = uids.map((id) => {
2557
+ const m = byId.get(id);
2558
+ return { ...m, hid: !!cull.underHidden[id] };
2559
+ });
2560
+ stats.undersTotal += umembers.length;
2561
+ stats.undersHidden += umembers.filter((m) => m.hid).length;
2562
+ const uPartSet = new Map;
2563
+ for (const m of umembers)
2564
+ uPartSet.set(m.part, m.p);
2565
+ let uV = 0, uI = 0;
2566
+ for (const p of uPartSet.values())
2567
+ for (const b of [p.under, ...p.under?.lod ?? []]) {
2568
+ uV += geomVerts(b);
2569
+ uI += geomIdx(b);
2570
+ }
2571
+ if (!uV)
2572
+ continue;
2573
+ const ubm = new THREE.BatchedMesh(umembers.length, Math.max(1, uV), Math.max(1, uI), mat);
2574
+ ubm.perObjectFrustumCulled = true;
2575
+ ubm.sortObjects = false;
2576
+ ubm.frustumCulled = true;
2577
+ ubm.userData.ldrMerged = true;
2578
+ ubm.userData.ldrUnder = true;
2579
+ ubm.onBeforeRender = trackVp;
2580
+ root.add(ubm);
2581
+ const uGidsByPart = new Map;
2582
+ for (const [part, p] of uPartSet) {
2583
+ const u = geom(p.under, arr);
2584
+ if (!u) {
2585
+ uGidsByPart.set(part, []);
2586
+ continue;
2587
+ }
2588
+ const ids = [ubm.addGeometry(u)];
2589
+ if (LOD && p.under?.lod)
2590
+ for (const l of p.under.lod)
2591
+ ids.push(ubm.addGeometry(geom(l, arr)));
2592
+ uGidsByPart.set(part, ids);
2593
+ }
2594
+ const uLive = umembers.filter((m) => (uGidsByPart.get(m.part)?.length ?? 0) > 0);
2595
+ const uInstGids = new Array(uLive.length);
2596
+ const uOwn = steps ? new Int32Array(uLive.length) : null;
2597
+ const uInst = steps ? new Int32Array(uLive.length) : null;
2598
+ const uHide = steps ? new Int32Array(uLive.length) : null;
2599
+ const uHid = new Uint8Array(uLive.length);
2600
+ for (let i = 0;i < uLive.length; i++) {
2601
+ const { id, part, p, hid } = uLive[i];
2602
+ const gids = uGidsByPart.get(part);
2603
+ const iid = ubm.addInstance(gids[0]);
2604
+ writeM4(m16, 0, insts[id].m);
2605
+ tmpM.fromArray(m16);
2606
+ ubm.setMatrixAt(iid, tmpM);
2607
+ tmpC.copy(color(insts[id].color));
2608
+ ubm.setColorAt(iid, tmpC);
2609
+ uInstGids[iid] = gids;
2610
+ uHid[iid] = hid ? 1 : 0;
2611
+ if (P.cullUnder && hid)
2612
+ ubm.setVisibleAt(iid, false);
2613
+ if (uOwn) {
2614
+ uOwn[iid] = steps[id];
2615
+ uInst[iid] = id;
2616
+ uHide[iid] = cull.underHideStep[id];
2617
+ }
2618
+ }
2619
+ umembers.length = 0;
2620
+ umembers.push(...uLive);
2621
+ ubm.computeBoundingSphere();
2622
+ const ucl = newCluster(ubm.boundingSphere ?? new THREE.Sphere);
2623
+ const uErrs = uLive.map(({ p }) => [0, ...(p.under?.lod ?? []).map((l) => l.err)]);
2624
+ ubm.userData._stepMode = !!steps;
2625
+ ubm.userData.ldrMergeGids = uInstGids;
2626
+ ucl.mergedLod = { bm: ubm, gids: uInstGids, errs: uErrs, underHid: uHid, cullUnder: !!P.cullUnder };
2627
+ ucl.setMergedLevel = (L) => {
2628
+ ubm.visible = L >= 0;
2629
+ };
2630
+ ucl.lv.push({ objs: [ubm], err: 0 });
2631
+ const underGhostCounts = [];
2632
+ if (wantCond) {
2633
+ const uByPart = new Map;
2634
+ for (const m of uLive) {
2635
+ const a = uByPart.get(m.part) || uByPart.set(m.part, []).get(m.part);
2636
+ a.push(m.id);
2637
+ }
2638
+ for (const [partName, ids] of uByPart) {
2639
+ const pp = uPartSet.get(partName);
2640
+ if (!pp?.condlu)
2641
+ continue;
2642
+ const ord = [...ids.filter((id) => !cull.underHidden[id]), ...ids.filter((id) => cull.underHidden[id])];
2643
+ const vis = ids.length - ids.reduce((a, id) => a + cull.underHidden[id], 0);
2644
+ const ghost = newIM(geom(pp.under, arr) || new THREE.BufferGeometry, mat, ord.length);
2645
+ fillInstances(ghost, ord, insts, color);
2646
+ const nC = ucl.cond.length;
2647
+ addCond(pp, ghost, ucl, "under");
2648
+ const lineObjs = ucl.cond.slice(nC);
2649
+ const setN = (n) => {
2650
+ ghost.count = n;
2651
+ for (const o of lineObjs)
2652
+ o.geometry.instanceCount = n;
2653
+ };
2654
+ setN(P.cullUnder ? vis : ord.length);
2655
+ underGhostCounts.push({ set: setN, all: ord.length, vis });
2656
+ if (steps)
2657
+ stepBatches.push({ im: ghost, objs: [ghost, ...lineObjs], own: Int32Array.from(ord, (id) => steps[id]), hide: Int32Array.from(ord, (id) => cull.underHideStep[id]), flag: "under", inst: Int32Array.from(ord), stud: null, col: Uint16Array.from(ord, (id) => instCol[id]) });
2658
+ }
2659
+ }
2660
+ {
2661
+ const sample = umembers[0]?.p;
2662
+ const bl = sample?.body?.lod;
2663
+ const last = bl?.[bl.length - 1];
2664
+ if (LOD && P.lodUnder !== false && last && last.tris === 12)
2665
+ ucl.boxErr = last.err;
2394
2666
  }
2395
- cl.below = below;
2396
- cl.ax = ax.slice(0, 3);
2667
+ if (ax) {
2668
+ let below = Infinity;
2669
+ for (const { id, p } of umembers) {
2670
+ const m = insts[id].m;
2671
+ below = Math.min(below, m[0] * ax[0] + m[1] * ax[1] + m[2] * ax[2] + p.bbox[4] * ax[3]);
2672
+ }
2673
+ ucl.below = below;
2674
+ ucl.ax = ax.slice(0, 3);
2675
+ }
2676
+ toggles.push({
2677
+ mesh: { set count(n) {
2678
+ const showAll = n >= umembers.length;
2679
+ for (let i = 0;i < uHid.length; i++)
2680
+ ubm.setVisibleAt(i, showAll || !uHid[i]);
2681
+ for (const g of underGhostCounts)
2682
+ g.set(showAll ? g.all : g.vis);
2683
+ } },
2684
+ all: umembers.length,
2685
+ visible: umembers.length - umembers.filter((m) => m.hid).length,
2686
+ flag: "under"
2687
+ });
2688
+ if (steps && uOwn)
2689
+ stepBatched.push({ bm: ubm, own: uOwn, hide: uHide, flag: "under", inst: uInst, underHidden: uHid });
2397
2690
  }
2398
- addCond(p, im, cl, "under");
2399
- const objs = [...cl.lv.flatMap((l) => l.objs), ...cl.cond];
2400
- objs.forEach((o) => {
2401
- if (!o.isInstancedMesh)
2402
- o.geometry.instanceCount = im.count;
2403
- });
2404
- toggles.push({ mesh: countTo(() => objs), all: uids.length, visible: vis, flag: "under" });
2405
- if (steps)
2406
- stepBatches.push({ im, objs, own: Int32Array.from(ord, (id) => steps[id]), hide: Int32Array.from(ord, (id) => cull.underHideStep[id]), flag: "under", inst: Int32Array.from(ord), stud: null, col: Uint16Array.from(ord, (id) => instCol[id]) });
2407
2691
  }
2408
2692
  }
2409
2693
  }
@@ -2444,11 +2728,14 @@ function buildLdrScene(insts, pack, P, color, mark) {
2444
2728
  stats.uncertBatches = nUncert;
2445
2729
  let condOn = true, edgesOn = true;
2446
2730
  root.apply = (c) => {
2447
- c.lv.forEach((l, i) => {
2448
- for (const o of l.objs)
2449
- o.visible = i === c.cur;
2450
- });
2451
- const lineVis = edgesOn && c.edgeOk && c.cur >= 0 && (c.cur === 0 || !LOD || c.lv[c.cur].objs.length > 0);
2731
+ if (c.setMergedLevel)
2732
+ c.setMergedLevel(c.cur);
2733
+ else
2734
+ c.lv.forEach((l, i) => {
2735
+ for (const o of l.objs)
2736
+ o.visible = i === c.cur;
2737
+ });
2738
+ const lineVis = edgesOn && c.edgeOk && c.cur >= 0 && (c.cur === 0 || !LOD || (c.setMergedLevel ? true : c.lv[c.cur].objs.length > 0));
2452
2739
  for (const o of c.lines)
2453
2740
  o.visible = lineVis;
2454
2741
  for (const o of c.cond)
@@ -2515,6 +2802,20 @@ function buildLdrScene(insts, pack, P, color, mark) {
2515
2802
  o.geometry.instanceCount = w;
2516
2803
  }
2517
2804
  }
2805
+ for (const b of stepBatched) {
2806
+ const useHide = b.flag === "under" ? cullU : false;
2807
+ const { own, hide, inst, bm } = b;
2808
+ for (let i = 0;i < own.length; i++) {
2809
+ const hid = !!hide && hide[i] <= S;
2810
+ if (b.flag === "under") {
2811
+ st.undersTotal++;
2812
+ if (hid)
2813
+ st.undersHidden++;
2814
+ }
2815
+ const on = own[i] <= S && !(useHide && hid) && !(O && !O[inst[i]]);
2816
+ bm.setVisibleAt(i, on);
2817
+ }
2818
+ }
2518
2819
  return st;
2519
2820
  };
2520
2821
  const setCull = (studs, under) => {
@@ -2570,6 +2871,12 @@ function buildLdrScene(insts, pack, P, color, mark) {
2570
2871
  c.edgeOk = true;
2571
2872
  for (const l of c.lines)
2572
2873
  l.geometry.drawRange.count = Infinity;
2874
+ if (c.mergedLod) {
2875
+ const { bm, gids } = c.mergedLod;
2876
+ for (let i = 0;i < gids.length; i++)
2877
+ if (gids[i]?.length)
2878
+ bm.setGeometryIdAt(i, gids[i][0]);
2879
+ }
2573
2880
  }
2574
2881
  refresh();
2575
2882
  }
@@ -2601,7 +2908,7 @@ async function warmPackGeometry(pack, stop = () => false, sliceMs = 8) {
2601
2908
  await new Promise((r) => setTimeout(r, 0));
2602
2909
  }
2603
2910
  }
2604
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/scene.ts
2911
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/scene.ts
2605
2912
  import * as THREE2 from "three";
2606
2913
  function colorFn(src, pack, fallback) {
2607
2914
  const table = new Map;
@@ -2757,10 +3064,10 @@ function createLdrObject(instances, pack, options = {}) {
2757
3064
  dispose: disposeCur
2758
3065
  });
2759
3066
  }
2760
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/parts-cdn.ts
3067
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/parts-cdn.ts
2761
3068
  import { decompress as decompress2 } from "fzstd";
2762
3069
 
2763
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/embedded.ts
3070
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/embedded.ts
2764
3071
  function splitFiles(text, fallback) {
2765
3072
  const files = new Map;
2766
3073
  let cur = null, saw = false;
@@ -2832,7 +3139,7 @@ function embeddedKeys(text, names, fallback = "main.ldr") {
2832
3139
  return out;
2833
3140
  }
2834
3141
 
2835
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/parts-cdn.ts
3142
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/parts-cdn.ts
2836
3143
  var DEFAULT_PARTS_CDN = "https://ldr-demo.vercel.app/cdn/v1/";
2837
3144
  var indexCache = new Map;
2838
3145
  var shardCache = new Map;
@@ -2992,10 +3299,10 @@ async function prepareModel(source, o = {}) {
2992
3299
  return { insts, pack, missing, requests, bytes, cull, timings: { fetchModel: t1 - t0, parse: t2 - t1, parts: t3 - t2, ...cull ? { cull: performance.now() - t3 } : {} } };
2993
3300
  }
2994
3301
 
2995
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/load-worker.gen.ts
3302
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/load-worker.gen.ts
2996
3303
  var load_worker_gen_default = 'var ht=ArrayBuffer,X=Uint8Array,ge=Uint16Array,gt=Int16Array;var be=Int32Array,Se=function(e,t,n){if(X.prototype.slice)return X.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 X(n-t);return r.set(e.subarray(t,n)),r},ce=function(e,t,n,r){if(X.prototype.fill)return X.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(X.prototype.copyWithin)return X.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"],W=function(e,t,n){var r=Error(t||dt[e]);if(r.code=e,Error.captureStackTrace)Error.captureStackTrace(r,W);if(!n)throw r;return r},Be=function(e,t,n){var r=0,s=0;for(;r<n;++r)s|=e[t++]<<(r<<3);return s},yt=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},xt=function(e,t){var n=e[0]|e[1]<<8|e[2]<<16;if(n==3126568&&e[3]==253){var r=e[4],s=r>>5&1,o=r>>2&1,i=r&3,l=r>>6;if(r&8)W(0);var a=6-s,c=i==3?4:i,p=Be(e,a,c);a+=c;var m=l?1<<l:s,h=Be(e,a,m)+(l==1&&256),d=h;if(!s){var S=1<<10+(e[5]>>3);d=S+(S>>3)*(e[5]&7)}if(d>2145386496)W(1);var u=new X((t==1?h||d:t?0:d)+12);return u[0]=1,u[4]=4,u[8]=8,{b:a+m,y:0,l:0,d:p,w:t&&t!=1?t:u.subarray(12),e:d,o:new be(u.buffer,0,3),u:h,c:o,m:Math.min(131072,d)}}else if((n>>4|e[3]<<20)==25481893)return yt(e,4)+8;W(0)},re=function(e){var t=0;for(;1<<t<=e;++t);return t-1},ue=function(e,t,n){var r=(t<<3)+4,s=(e[t]&15)+5;if(s>n)W(3);var o=1<<s,i=o,l=-1,a=-1,c=-1,p=o,m=new ht(512+(o<<2)),h=new gt(m,0,256),d=new ge(m,0,256),S=new ge(m,512,o),u=512+(o<<1),b=new X(m,u,o),P=new X(m,u+o);while(l<255&&i>0){var g=re(i+1),f=r>>3,A=(1<<g+1)-1,O=(e[f]|e[f+1]<<8|e[f+2]<<16)>>(r&7)&A,y=(1<<g)-1,M=A-i-1,E=O&y;if(E<M)r+=g,O=E;else if(r+=g+1,O>y)O-=M;if(h[++l]=--O,O==-1)i+=O,b[--p]=l;else i-=O;if(!O)do{var D=r>>3;a=(e[D]|e[D+1]<<8)>>(r&7)&3,r+=2,l+=a}while(a==3)}if(l>255||i)W(0);var C=0,U=(o>>1)+(o>>3)+3,_=o-1;for(var H=0;H<=l;++H){var v=h[H];if(v<1){d[H]=-v;continue}for(c=0;c<v;++c){b[C]=H;do C=C+U&_;while(C>=p)}}if(C)W(0);for(c=0;c<o;++c){var w=d[b[c]]++,L=P[c]=s-re(w);S[c]=(w<<L)-o}return[r+7>>3,{b:s,s:b,n:P,t:S}]},wt=function(e,t){var n=0,r=-1,s=new X(292),o=e[t],i=s.subarray(0,256),l=s.subarray(256,268),a=new ge(s.buffer,268);if(o<128){var c=ue(e,t+1,6),p=c[0],m=c[1];t+=o;var h=p<<3,d=e[t];if(!d)W(0);var S=0,u=0,b=m.b,P=b,g=(++t<<3)-8+re(d);for(;;){if(g-=b,g<h)break;var f=g>>3;if(S+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<b)-1,i[++r]=m.s[S],g-=P,g<h)break;f=g>>3,u+=(e[f]|e[f+1]<<8)>>(g&7)&(1<<P)-1,i[++r]=m.s[u],b=m.n[S],S=m.t[S],P=m.n[u],u=m.t[u]}if(++r>255)W(0)}else{r=o-127;for(;n<r;n+=2){var A=e[++t];i[n]=A>>4,i[n+1]=A&15}++t}var O=0;for(n=0;n<r;++n){var y=i[n];if(y>11)W(0);O+=y&&1<<y-1}var M=re(O)+1,E=1<<M,D=E-O;if(D&D-1)W(0);i[r++]=re(D)+1;for(n=0;n<r;++n){var y=i[n];++l[i[n]=y&&M+1-y]}var C=new X(E<<1),U=C.subarray(0,E),_=C.subarray(E);a[M]=0;for(n=M;n>0;--n){var H=a[n];ce(_,n,H,a[n-1]=H+l[n]*(1<<M-n))}if(a[0]!=E)W(0);for(n=0;n<r;++n){var v=i[n];if(v){var w=a[v];ce(U,n,w,a[v]=w+(1<<M-v))}}return[t,{n:_,b:M,s:U}]},At=ue(new X([81,16,99,140,49,198,24,99,12,33,196,24,99,102,102,134,70,146,4]),0,6)[1],vt=ue(new X([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],Mt=ue(new X([32,132,16,66,102,70,68,68,68,68,36,73,2]),0,5)[1],$e=function(e,t){var n=e.length,r=new be(n);for(var s=0;s<n;++s)r[s]=t,t+=1<<e[s];return r},Ce=new X(new be([0,0,0,0,16843009,50528770,134678020,202050057,269422093]).buffer,0,36),St=$e(Ce,0),Pe=new X(new be([0,0,0,0,0,0,0,0,16843009,50528770,117769220,185207048,252579084,16]).buffer,0,53),Ct=$e(Pe,3),le=function(e,t,n){var r=e.length,s=t.length,o=e[r-1],i=(1<<n.b)-1,l=-n.b;if(!o)W(0);var a=0,c=n.b,p=(r<<3)-8+re(o)-c,m=-1;for(;p>l&&m<s;){var h=p>>3,d=(e[h]|e[h+1]<<8|e[h+2]<<16)>>(p&7);a=(a<<c|d)&i,t[++m]=n.s[a],p-=c=n.n[a]}if(p!=l||m+1!=s)W(0)},Pt=function(e,t,n){var r=6,s=t.length,o=s+3>>2,i=o<<1,l=o+i;le(e.subarray(r,r+=e[0]|e[1]<<8),t.subarray(0,o),n),le(e.subarray(r,r+=e[2]|e[3]<<8),t.subarray(o,i),n),le(e.subarray(r,r+=e[4]|e[5]<<8),t.subarray(i,l),n),le(e.subarray(r),t.subarray(l),n)},Et=function(e,t,n){var r,s=t.b,o=e[s],i=o>>1&3;t.l=o&1;var l=o>>3|e[s+1]<<5|e[s+2]<<13,a=(s+=3)+l;if(i==1){if(s>=e.length)return;if(t.b=s+1,n)return ce(n,e[s],t.y,t.y+=l),n;return ce(new X(l),e[s])}if(a>e.length)return;if(i==0){if(t.b=a,n)return n.set(e.subarray(s,a),t.y),t.y+=l,n;return Se(e,s,a)}if(i==2){var c=e[s],p=c&3,m=c>>2&3,h=c>>4,d=0,S=0;if(p<2)if(m&1)h|=e[++s]<<4|(m&2&&e[++s]<<12);else h=c>>3;else if(S=m,m<2)h|=(e[++s]&63)<<4,d=e[s]>>6|e[++s]<<2;else if(m==2)h|=e[++s]<<4|(e[++s]&3)<<12,d=e[s]>>2|e[++s]<<6;else h|=e[++s]<<4|(e[++s]&63)<<12,d=e[s]>>6|e[++s]<<2|e[++s]<<10;++s;var u=n?n.subarray(t.y,t.y+t.m):new X(t.m),b=u.length-h;if(p==0)u.set(e.subarray(s,s+=h),b);else if(p==1)ce(u,e[s++],b);else{var P=t.h;if(p==2){var g=wt(e,s);d+=s-(s=g[0]),t.h=P=g[1]}else if(!P)W(0);(S?Pt:le)(e.subarray(s,s+=d),u.subarray(b),P)}var f=e[s++];if(f){if(f==255)f=(e[s++]|e[s++]<<8)+32512;else if(f>127)f=f-128<<8|e[s++];var A=e[s++];if(A&3)W(0);var O=[vt,Mt,At];for(var y=2;y>-1;--y){var M=A>>(y<<1)+2&3;if(M==1){var E=new X([0,0,e[s++]]);O[y]={s:E.subarray(2,3),n:E.subarray(0,1),t:new ge(E.buffer,0,1),b:0}}else if(M==2)r=ue(e,s,9-(y&1)),s=r[0],O[y]=r[1];else if(M==3){if(!t.t)W(0);O[y]=t.t[y]}}var D=t.t=O,C=D[0],U=D[1],_=D[2],H=e[a-1];if(!H)W(0);var v=(a<<3)-8+re(H)-_.b,w=v>>3,L=0,V=(e[w]|e[w+1]<<8)>>(v&7)&(1<<_.b)-1;w=(v-=U.b)>>3;var I=(e[w]|e[w+1]<<8)>>(v&7)&(1<<U.b)-1;w=(v-=C.b)>>3;var B=(e[w]|e[w+1]<<8)>>(v&7)&(1<<C.b)-1;for(++f;--f;){var T=_.s[V],x=_.n[V],N=C.s[B],F=C.n[B],R=U.s[I],z=U.n[I];w=(v-=R)>>3;var j=1<<R,k=j+((e[w]|e[w+1]<<8|e[w+2]<<16|e[w+3]<<24)>>>(v&7)&j-1);w=(v-=Pe[N])>>3;var G=Ct[N]+((e[w]|e[w+1]<<8|e[w+2]<<16)>>(v&7)&(1<<Pe[N])-1);w=(v-=Ce[T])>>3;var K=St[T]+((e[w]|e[w+1]<<8|e[w+2]<<16)>>(v&7)&(1<<Ce[T])-1);if(w=(v-=x)>>3,V=_.t[V]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<x)-1),w=(v-=F)>>3,B=C.t[B]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<F)-1),w=(v-=z)>>3,I=U.t[I]+((e[w]|e[w+1]<<8)>>(v&7)&(1<<z)-1),k>3)t.o[2]=t.o[1],t.o[1]=t.o[0],t.o[0]=k-=3;else{var Y=k-(K!=0);if(Y){if(k=Y==3?t.o[0]-1:t.o[Y],Y>1)t.o[2]=t.o[1];t.o[1]=t.o[0],t.o[0]=k}else k=t.o[0]}for(var y=0;y<K;++y)u[L+y]=u[b+y];L+=K,b+=K;var q=L-k;if(q<0){var Z=-q,ee=t.e+q;if(Z>G)Z=G;for(var y=0;y<Z;++y)u[L+y]=t.w[ee+y];L+=Z,G-=Z,q=0}for(var y=0;y<G;++y)u[L+y]=u[q+y];L+=G}if(L!=b)while(b<u.length)u[L++]=u[b++];else L=u.length;if(n)t.y+=L;else u=Se(u,0,L)}else if(n){if(t.y+=h,b)for(var y=0;y<h;++y)u[y]=u[b+y]}else if(b)u=Se(u,b);return t.b=a,u}W(2)},Tt=function(e,t){if(e.length==1)return e[0];var n=new X(t);for(var r=0,s=0;r<e.length;++r){var o=e[r];n.set(o,s),s+=o.length}return n};function je(e,t){var n=[],r=+!t,s=0,o=0;for(;e.length;){var i=xt(e,r||t);if(typeof i=="object"){if(r){if(t=null,i.w.length==i.u)n.push(t=i.w),o+=i.u}else n.push(t),i.e=0;for(;!i.l;){var l=Et(e,i,t);if(!l)W(5);if(t)i.e=i.y;else n.push(l),o+=l.length,bt(i.w,0,l.length),i.w.set(l,i.w.length-l.length)}s=i.b+i.c*4}else s=i;e=e.subarray(s)}return Tt(n,o)}function de(e){let t=new DataView(e).getUint32(0,!0),n=JSON.parse(new TextDecoder().decode(new Uint8Array(e,4,t))),r=4+t;return{header:n,arr:(o)=>o&&(o[2]==="f32"?new Float32Array(e,r+o[0],o[1]):o[2]==="u16"?new Uint16Array(e,r+o[0],o[1]):o[2]==="u8"?new Uint8Array(e,r+o[0],o[1]):new Uint32Array(e,r+o[0],o[1])),bytes:e.byteLength,buffer:e}}var J=(e)=>e.trim().toLowerCase().replace(/\\\\/g,"/").replace(/\\/+/g,"/");function Ee(e){if(/^0x/i.test(e))return parseInt(e,16);return+e}var Ve=/^~?\\s*moved\\s+to\\s+(.+)$/i,Lt=new Set(["FILE","NOFILE","!DATA","!:","STEP","BFC","ROTSTEP","BUFEXCHG","!TEXMAP"]),Je=new Set(["part","subpart","primitive","8_primitive","48_primitive","shortcut","helper"]),It=new Set(["model","submodel","configuration"]),kt=/^(?:!?LDRAW_ORG|Unofficial|Official\\s+LCAD)\\s+(\\S+)/i;function He(e){let t=kt.exec(e);if(!t)return;let n=t[1].toLowerCase().replace(/^unofficial_/,"");return Je.has(n)||It.has(n)?n:void 0}function Ft(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 Rt(e,t=!1){let n=/^\\s*(\\S+)\\s+(.*)$/.exec(e);if(!n)return null;let r=n[1].toUpperCase(),s=r==="PLANAR"?9:r==="CYLINDRICAL"?10:r==="SPHERICAL"?11:0;if(!s)return null;let o=n[2].trim().split(/\\s+/);if(o.length<s+1)return null;let i=o.slice(0,s).map(Number);if(!i.every(Number.isFinite))return null;let l=n[2].trim();for(let m=0;m<s;m++)l=l.replace(/^\\S+\\s*/,"");let a=Ft(l);if(!a.length)return null;let c={method:r,p1:i.slice(0,3),p2:i.slice(3,6),p3:i.slice(6,9),texture:a[0]};if(s>=10)c.a=i[9];if(s===11)c.b=i[10];let p=a.findIndex((m,h)=>h>0&&m.toUpperCase()==="GLOSSMAP");if(p>0&&a[p+1])c.glossmap=a[p+1];if(t)c.next=!0;return c}var Dt=(e)=>{let t=e.replace(/[^A-Za-z0-9+/]/g,""),n=t+"=".repeat((4-t.length%4)%4),r=atob(n),s=new Uint8Array(r.length);for(let o=0;o<r.length;o++)s[o]=r.charCodeAt(o);return s};function Ut(e){let t=e.length,n=1,r=(c)=>c===32||c===9,s=()=>{while(n<t&&r(e.charCodeAt(n)))n++;let c=n;while(n<t&&!r(e.charCodeAt(n)))n++;return c<n?e.slice(c,n):null},o=s();if(o===null)return null;let i=Array(12);for(let c=0;c<12;c++){let p=s();if(p===null)return null;i[c]=+p}while(n<t&&r(e.charCodeAt(n)))n++;if(n>=t)return null;let l=e.slice(n),a=/[ \\t]{2,}|\\t/.test(l)?l.split(/\\s+/).join(" "):l;return{t:1,color:Ee(o),m:i,file:J(a)}}function Ge(e){let t=+e[0];if(!(t>=1&&t<=5)||e.length<2)return null;let n=Ee(e[1]),r=e.slice(2).map(Number);if(t===1)return{t:1,color:n,m:r.slice(0,12),file:J(e.slice(14).join(" "))};if(t===2)return{t:2,color:n,p:r.slice(0,6)};if(t===3)return{t:3,color:n,p:r.slice(0,9)};if(t===4)return{t:4,color:n,p:r.slice(0,12)};return{t:5,color:n,p:r.slice(0,12)}}function Ze(e,t="main.ldr",n={}){let r=!!n.geometryText,s=new Map,o=null,i="",l,a=null,c=[],p=null,m=()=>{if(!a)return;let g=Dt(a.chunks.join("")),f=g[0]===137&&g[1]===80&&g[2]===78&&g[3]===71;(l??=new Map).set(J(a.name),{name:a.name,bytes:g,...f?{mime:"image/png"}:{}}),a=null},h=!0,d=(g)=>{if(m(),o={name:J(g),cmds:[]},s.set(o.name,o),!i)i=o.name;c=[],p=null,h=!0},S=!1,u=!1,b=()=>{if(u)return;u=!0,s.clear(),o=null,i=""},P=(g,f)=>{if(p){g.tex=p,p=null;return}let A=c[c.length-1];if(!A)return;if(A.fallback){if(!f)g.fallback=!0}else g.tex=A.map};for(let g of e.split(`\n`)){let f=g.trim();if(!f)continue;if(r&&f.charCodeAt(0)>=50&&f.charCodeAt(0)<=53&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){if(a||S)continue;if(!o)d(t);let M=f.slice(2).trimStart(),E=M.search(/\\s/),D={t:f.charCodeAt(0)-48,color:Ee(E<0?M:M.slice(0,E)),p:[],src:f};P(D,!1),o.cmds.push(D),h=!1;continue}if(f.charCodeAt(0)===48&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)){let M=2;while(f.charCodeAt(M)===32||f.charCodeAt(M)===9)M++;let E=M;while(E<f.length&&f.charCodeAt(E)!==32&&f.charCodeAt(E)!==9)E++;let D=f.slice(M,E);if(!Lt.has(D)){if(S||a)continue;if(!o)d(t);let C=f.slice(M),U={t:0,text:C};if(D.charCodeAt(0)===33)U.meta=D;if(p=null,h&&!o.org){let H=He(C);if(H)o.org=H}let _=C.match(Ve);if(_&&!o.movedTo){let H=_[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(H))H+=".dat";o.movedTo=J(H)}o.cmds.push(U);continue}}if(f.charCodeAt(0)===49&&(f.charCodeAt(1)===32||f.charCodeAt(1)===9)&&!a&&!S){let M=Ut(f);if(M){if(!o)d(t);P(M,!1),o.cmds.push(M),h=!1;continue}}let A=f.split(/\\s+/);if(+A[0]===0){let M=f.slice(1).trim();if(A[1]==="FILE"){b(),S=!1,d(M.slice(5));continue}if(A[1]==="NOFILE"){m(),o=null,S=!0;continue}if(A[1]==="!DATA"){b(),m(),o=null,S=!1,a={name:M.slice(5).trim(),chunks:[]};continue}if(S)continue;if(a){if(A[1]==="!:")a.chunks.push(A.slice(2).join(""));continue}if(!o)d(t);let E={t:0,text:M};if(A[1]==="STEP")E.step=!0,c=[],p=null;else if(A[1]==="BFC")E.bfc=A.slice(2).join(" ");else if(A[1]==="ROTSTEP")if(E.meta="ROTSTEP",E.step=!0,c=[],p=null,(A[2]??"").toUpperCase()==="END")E.rotstep={x:0,y:0,z:0,mode:"END"};else{let C=(A[5]??"REL").toUpperCase();E.rotstep={x:+A[2]||0,y:+A[3]||0,z:+A[4]||0,mode:["REL","ABS","ADD"].includes(C)?C:"REL"}}else if(A[1]==="BUFEXCHG"){E.meta="BUFEXCHG";let C=(A[2]??"").toUpperCase();E.bufexchg={op:C==="RETRIEVE"?"RETRIEVE":"STORE",buf:A[3]??"A"}}else if(A[1]?.startsWith("!"))E.meta=A[1];if(h&&!o.org){let C=He(M);if(C)o.org=C}if(A[1]==="!TEXMAP"){let C=(A[2]??"").toUpperCase();if(p=null,C==="START"||C==="NEXT"){let U=Rt(M.replace(/^!TEXMAP\\s+\\S+/i,""),C==="NEXT");if(E.texmap={op:C,...U?{map:U}:{}},U)if((o.texmaps??=[]).push(U),C==="START")c.push({map:U,fallback:!1});else p=U}else if(C==="FALLBACK"){E.texmap={op:C};let U=c[c.length-1];if(U)U.fallback=!0}else if(C==="END")E.texmap={op:C},c.pop()}else if(A[1]==="!:"){p=null;let C=Ge(A.slice(2));if(C)P(C,!0),E.geom=C}else p=null;let D=M.match(Ve);if(D&&!o.movedTo){let C=D[1].trim().replace(/\\\\/g,"/");if(!/\\.(dat|ldr|mpd)$/i.test(C))C+=".dat";o.movedTo=J(C)}o.cmds.push(E);continue}if(a||S)continue;if(!o)d(t);let y=Ge(A);if(!y)continue;P(y,!1),o.cmds.push(y),h=!1}return m(),l?{main:i,files:s,data:l}:{main:i,files:s}}var tn=Math.PI/180;function qe(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 Qe(e,t){let[n,r,s,o,i,l,a,c,p,m,h,d]=e,[S,u,b,P,g,f,A,O,y,M,E,D]=t;return[o*S+i*u+l*b+n,a*S+c*u+p*b+r,m*S+h*u+d*b+s,o*P+i*A+l*M,o*g+i*O+l*E,o*f+i*y+l*D,a*P+c*A+p*M,a*g+c*O+p*E,a*f+c*y+p*D,m*P+h*A+d*M,m*g+h*O+d*E,m*f+h*y+d*D]}var Te=[0,0,0,1,0,0,0,1,0,0,0,1];var Ke=new WeakMap,Ot=/^(s|8|48)\\//;function Le(e,t){let n=e.files.get(J(t));if(!n)return"part";let r=Ke.get(n);if(r)return r;if(n.org)r=Je.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&&Ot.test(s.file))?"part":"model";return Ke.set(n,r),r}var Xe=new WeakMap;function et(e){let t=Xe.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 Xe.set(e,t),t}var We=(e)=>e>16777215?"0x"+e.toString(16).toUpperCase():String(e),zt=(e)=>e.t===0?"0 "+e.text:e.t===1?`1 ${We(e.color)} ${e.m.join(" ")} ${e.file}`:e.src?e.src:`${e.t} ${We(e.color)} ${e.p.join(" ")}`,Ie=(e,t)=>`${J(e)}#${t}`;function Nt(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){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:Ie(e.name,t),cmds:n}}function tt(e,t){return[`0 ldr: own geometry of ${e.name}, step ${t}`,...Nt(e,t).cmds.map(zt)].join(`\n`)+`\n`}function Bt(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}function nt(e){let[t,n,r,s,o,i,l,a,c,p,m,h]=e,d=a*h-c*m,S=-(l*h-c*p),u=l*m-a*p,b=s*d+o*S+i*u;if(!Number.isFinite(b)||Math.abs(b)<0.000000000001)return null;let P=1/b,g=[d*P,-(o*h-i*m)*P,(o*c-i*a)*P,S*P,(s*h-i*p)*P,-(s*c-i*l)*P,u*P,-(s*m-o*p)*P,(s*a-o*l)*P];return[-(g[0]*t+g[1]*n+g[2]*r),-(g[3]*t+g[4]*n+g[5]*r),-(g[6]*t+g[7]*n+g[8]*r),...g]}var $t=(e)=>String(+e.toFixed(6)||0),_e=(e)=>\'"\'+e.replace(/\\\\/g,"\\\\\\\\").replace(/"/g,"\\\\\\"")+\'"\';function rt(e,t){let n=[...t.p1,...t.p2,...t.p3,...t.method!=="PLANAR"?[t.a??360]:[],...t.method==="SPHERICAL"?[t.b??180]:[]].map($t).join(" "),r=`0 ldr: ${e} with a model-level !TEXMAP\n0 BFC CERTIFY CCW\n0 !TEXMAP START ${t.method} ${n} ${_e(t.texture)}${t.glossmap?" GLOSSMAP "+_e(t.glossmap):""}\n1 16 0 0 0 1 0 0 0 1 0 0 0 1 ${J(e)}\n0 !TEXMAP END\n`;return{name:`${J(e)}#tex-${Bt(r)}`,source:r}}var jt=(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 Vt(e,t,n){let r=Math.PI/180,s=Math.sin(e*r),o=Math.cos(e*r),i=Math.sin(t*r),l=Math.cos(t*r),a=Math.sin(n*r),c=Math.cos(n*r);return[l*c,-l*a,i,o*a+s*i*c,o*c-s*i*a,-s*l,s*a-o*i*c,s*c+o*i*a,o*l]}var Ye=new WeakMap;function st(e){let t=Ye.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=Vt(o.x,o.y,o.z);r=o.mode==="ABS"?{abs:!0,m:i,rotstep:o}:o.mode==="ADD"&&r?{abs:r.abs,m:jt(r.m,i),rotstep:o}:{abs:!1,m:i,rotstep:o}}n.push(r)}return n.push(r),Ye.set(e,n),n}var ot=999999,it=(e)=>e.map((t)=>String(t).padStart(6,"0")).join(".")+"~";function Ht(e,t={}){let n=[],r=t.maxDepth??64,s=t.looseGeometry!==!1,o=!!t.textures,i=!!t.callouts,l=new Map,a=0,c=(m,h)=>{let d=m.name+"#"+h,S=l.get(d);if(!S){let u;S=Object.assign(()=>u??=tt(m,h),{file:m,step:h}),l.set(d,S)}return S},p=(m,h,d,S,u,b,P,g,f=null,A=[],O=[])=>{let y=m.files.get(h);if(!y||P>r)return;let M=0,E=P>0?++a:0,D=i&&E?[...A,E]:A,C=i&&E?[...O,d]:O,U=i&&!f?new Map:null,_=-1,H=0,v=(T,x,N,F,R,z)=>{if(_!==M)_=M,H=0;let j=U?.get(M+"|"+x);if(j)return j.n++,p(T,T===m?x:T.main,N,F,u+"/"+x,[...R,ot],P+1,z,[...R,ot],D,C);let k=[...R,H++],G=n.length;p(T,T===m?x:T.main,N,F,u+"/"+x,k,P+1,z,f,D,C),U?.set(M+"|"+x,{n:1,from:G,to:n.length})},w=st(y),L=s?et(y):[],V=0,I=(T,x,N,F,R,z,j)=>{if(f)F=f;let k={part:T,color:x,m:N,step:F[0],steps:F,localStep:R,path:u};if(E){if(k.sub=E,i)k.subPath=D,k.subMats=C}if(z)k.embedded=!0;if(j){let K=rt(T,j);k.texPart=K.name,k.texSource=K.source}let G=w[R];if(G)k.view=G;return n.push(k),k},B=(T)=>{while(V<L.length&&L[V]<=T){let x=L[V++];I(Ie(y.name,x),S,d,[...b,x],x,!1,null).source=c(y,x)}};for(let T of y.cmds){if(T.t===0&&T.step){M++;continue}let x=T;if(x.t>=2||x.t===0&&x.geom&&x.geom.t>=2){B(M);continue}if(x.t===0)if(o&&x.geom?.t===1)x=x.geom;else continue;if(x.t!==1)continue;if(o&&x.fallback)continue;let N=x.color===16?S:x.color,F=Qe(d,x.m),R=[...b,M],z=o?x.tex??g:null,j=z?nt(x.m):null,k=z&&j?qe(z,j):null;if(m.files.has(x.file)){if(Le(m,x.file)==="model"){v(m,x.file,F,N,R,k);continue}I(x.file,N,F,R,M,!0,k);continue}let G=t.resolveModel?.(x.file);if(G){v(G,x.file,F,N,R,k);continue}I(x.file,N,F,R,M,!1,k)}if(B(1/0),U){for(let T of U.values())if(T.n>1)for(let x=T.from;x<T.to;x++)n[x].mult??=T.n}};if(Le(e,e.main)==="part"){if(e.files.get(e.main))n.push({part:e.main,color:16,m:[...Te],step:0,steps:[0],localStep:0,path:e.main,embedded:!0});return n}return p(e,e.main,Te,16,e.main,[],0,null),n}function at(e,t="main.ldr",n){return Ht(Ze(e,t,{geometryText:!0}),n)}function Gt(e,t){let n=new Map,r=null,s=!1;for(let o of e.split(/\\r?\\n/)){let i=/^\\s*0\\s+FILE\\s+(.+)$/i.exec(o);if(i){if(!s)n.clear();s=!0,r=[],n.set(J(i[1]),r);continue}if(/^\\s*0\\s+(NOFILE|!DATA)(\\s|$)/i.test(o)){if(!s)n.clear();s=!0,r=null;continue}if(!r){if(s)continue;r=[],n.set(J(t),r)}let l=o.trim().replace(/\\s+/g," ");if(l)r.push(l)}return n}var Kt=(e)=>{if(!e.startsWith("1 "))return null;let t=e.split(" ");return t.length>=15?J(t.slice(14).join(" ")):null};function Xt(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=Gt(e,n),s=new Map;for(let o of t){let i=J(o);if(!r.has(i)||s.has(i))continue;let l=new Set([i]),a=[i];while(a.length)for(let p of r.get(a.pop())){let m=Kt(p);if(m&&r.has(m)&&!l.has(m))l.add(m),a.push(m)}let c=[i,...[...l].filter((p)=>p!==i).sort()].map((p)=>"0 FILE "+(p===i?"":p)+`\n`+r.get(p).join(`\n`)).join(`\n`);s.set(i,`emb/${Xt(c)}.dat`)}return s}var ct=(e,t=0)=>Math.abs(e[t+7]-1)<0.001&&Math.abs(e[t+4])<0.001&&Math.abs(e[t+10])<0.001,ut=new WeakMap;function ke(e,t){let n=ut.get(e);if(!n)ut.set(e,n=new Map);let r=n.get(t);if(r!==void 0)return r;let s=e.parts[t];if(!s)return n.set(t,null),null;let o=s.studs.length,i=new Float64Array(o*12),l=[],a=[];s.studs.forEach((h,d)=>{l.push(h[0]),a.push(h[1]);for(let S=0;S<12;S++)i[d*12+S]=h[2+S]});let c=null,p=0,m=0;if(s.mask){p=s.mask[0],m=s.mask[1];let h=s.mask[2];c=new Uint8Array(h.length);for(let d=0;d<h.length;d++)c[d]=h.charCodeAt(d)===49?1:0}return n.set(t,r={nStuds:o,studM:i,kind:l,color:a,mask:c,nx:p,nz:m}),r}var ie=1073741824;class Fe{a;b;c;vals;used;mask;size=0;constructor(e=1024){let t=1024;while(t<e*2)t*=2;this.a=new Int32Array(t),this.b=new Int32Array(t),this.c=new Int32Array(t),this.vals=new Int32Array(t),this.used=new Uint8Array(t),this.mask=t-1}slot(e,t,n){let r=Math.imul(e,2654435761)^Math.imul(t,2246822507)^Math.imul(n,3266489909);return r^=r>>>15,r=Math.imul(r,739982445),r^=r>>>12,r&this.mask}get(e,t,n){let r=this.slot(e,t,n),s=this.used,o=this.a,i=this.b,l=this.c;for(;;){if(!s[r])return-1;if(o[r]===e&&i[r]===t&&l[r]===n)return this.vals[r];r=r+1&this.mask}}put(e,t,n,r){if((this.size+1)*2>this.used.length)this.grow();let s=this.slot(e,t,n),o=this.used,i=this.a,l=this.b,a=this.c;for(;;){if(!o[s])return o[s]=1,i[s]=e,l[s]=t,a[s]=n,this.vals[s]=r,this.size++,-1;if(i[s]===e&&l[s]===t&&a[s]===n){let c=this.vals[s];return this.vals[s]=r,c}s=s+1&this.mask}}grow(){let{a:e,b:t,c:n,vals:r,used:s}=this,o=s.length*2;this.a=new Int32Array(o),this.b=new Int32Array(o),this.c=new Int32Array(o),this.vals=new Int32Array(o),this.used=new Uint8Array(o),this.mask=o-1,this.size=0;for(let i=0;i<s.length;i++)if(s[i])this.put(e[i],t[i],n[i],r[i])}}var ye=(e,t,n)=>e>-ie&&e<ie&&t>-ie&&t<ie&&n>-ie&&n<ie,fe=2147483647;function Wt(e,t,n){let s=[],o=[],i=[],l=[],a=[],c=[],p=[],m=[],h=new Fe(e.length*2),d=[],S=[];for(let v=0;v<e.length;v++){let w=e[v],L=w.m,V=t.parts[w.part];if(!V||!V.mask||!ct(L))continue;let I=V.bbox,B=1/0,T=-1/0,x=1/0,N=-1/0;for(let z=0;z<2;z++)for(let j=0;j<2;j++){let k=z?I[3]:I[0],G=j?I[5]:I[2],K=L[0]+L[3]*k+L[5]*G,Y=L[2]+L[9]*k+L[11]*G;if(K<B)B=K;if(K>T)T=K;if(Y<x)x=Y;if(Y>N)N=Y}let F=a.length;s.push(B),o.push(T),i.push(x),l.push(N),a.push(v),c.push(ke(t,w.part)),p.push(I[0]),m.push(I[2]);let R=Math.round((L[1]+I[4])*2);for(let z=Math.floor(B/40);z<=Math.floor(T/40);z++)for(let j=Math.floor(x/40);j<=Math.floor(N/40);j++){if(!ye(R,z,j))continue;let k=S.length;S.push(F),d.push(h.put(R,z,j,k))}}let u=[0,5,-5,5,-5],b=[0,5,5,-5,-5],P=NaN,g=NaN,f=NaN,A=-1,O=(v,w,L,V)=>{let I=Math.round(w*2),B=Math.floor(v/40),T=Math.floor(L/40);if(!ye(I,B,T))return fe;let x=fe;if(I!==P||B!==g||T!==f)P=I,g=B,f=T,A=h.get(I,B,T);for(let N=A;N>=0;N=d[N]){let F=S[N];if(a[F]===V||!(v-6>=s[F]-0.5&&v+6<=o[F]+0.5&&L-6>=i[F]-0.5&&L+6<=l[F]+0.5))continue;let R=e[a[F]].m,z=c[F],j=p[F],k=m[F],G=v-R[0],K=w-R[1],Y=L-R[2],q=R[3]*G+R[6]*K+R[9]*Y,Z=R[5]*G+R[8]*K+R[11]*Y,{nx:ee,nz:se,mask:ae}=z,oe=!0;for(let Q=0;Q<5;Q++){let te=Math.floor((q+u[Q]-j)/20),ne=Math.floor((Z+b[Q]-k)/20);if(te<0||ne<0||te>=ee||ne>=se||ae[te*se+ne]!==1){oe=!1;break}}if(oe){if(!n)return 0;let Q=n[a[F]];if(Q<x)x=Q}}return x},y=0;for(let v of e){let w=ke(t,v.part);if(w)y+=w.nStuds}let M=new Uint8Array(y),E=new Uint8Array(y),D=new Fe(y),C=0,U=n?new Int32Array(y).fill(fe):void 0;for(let v=0,w=0;v<e.length;v++){let L=e[v],V=ke(t,L.part);if(!V)continue;let I=L.m,B=V.studM,T=I[0],x=I[1],N=I[2],F=I[3],R=I[4],z=I[5],j=I[6],k=I[7],G=I[8],K=I[9],Y=I[10],q=I[11];for(let Z=0;Z<V.nStuds;Z++,w++){let ee=Z*12,se=B[ee+4],ae=B[ee+7],oe=B[ee+10];if(!(Math.abs(j*se+k*ae+G*oe-1)<0.001&&Math.abs(F*se+R*ae+z*oe)<0.001&&Math.abs(K*se+Y*ae+q*oe)<0.001))continue;E[w]=1;let Q=B[ee],te=B[ee+1],ne=B[ee+2],Re=T+F*Q+R*te+z*ne,De=x+j*Q+k*te+G*ne,Ue=N+K*Q+Y*te+q*ne,Oe=O(Re,De,Ue,v);if(Oe!==fe){if(M[w]=1,C++,U)U[w]=Oe}let pe=Math.round(Re),me=Math.round(De),he=Math.round(Ue);if(!ye(pe,me,he))continue;if(!n){D.put(pe,me,he,1);continue}let ze=n[v],Ne=D.get(pe,me,he);if(Ne<0||ze<Ne)D.put(pe,me,he,ze)}}let _=new Uint8Array(e.length),H=n?new Int32Array(e.length).fill(fe):void 0;for(let v=0;v<e.length;v++){let w=e[v],L=t.parts[w.part];if(!L||!L.under||!ct(w.m))continue;let V=L.bbox,I=Math.round((V[3]-V[0])/20),B=Math.round((V[5]-V[2])/20);if(!I||!B||I*B>4096)continue;let T=w.m,x=!0,N=0;for(let F=0;F<I&&x;F++)for(let R=0;R<B;R++){let z=V[0]+10+20*F,j=V[2]+10+20*R,k=T[0]+T[3]*z+T[5]*j,G=T[2]+T[9]*z+T[11]*j,K=Math.round(k),Y=Math.round(T[1]+V[4]),q=Math.round(G),Z=ye(K,Y,q)?D.get(K,Y,q):-1;if(Z<0){x=!1;break}if(Z>N)N=Z}if(x){if(_[v]=1,H)H[v]=N}}return{nStuds:y,studHidden:M,studUp:E,underHidden:_,studsHidden:C,studHideStep:U,underHideStep:H}}function _t(e,t,n){let r=(a)=>n&&a.texPart&&t.parts[a.texPart]?a.texPart:a.part,s=e.map((a)=>({part:r(a),color:String(a.color),m:a.m,steps:a.steps})),o=s.map((a)=>it(a.steps)),i=[...new Set(o)].sort(),l=new Map(i.map((a,c)=>[a,c]));return{all:s,stepOf:o.map((a)=>l.get(a)),nSteps:i.length}}function xe(e,t,n=!0){let r=_t(e,t,n);return Wt(r.all,t,r.nSteps>1?r.stepOf:void 0)}var Me="https://ldr-demo.vercel.app/cdn/v1/",Ae=new Map,we=new Map;function pt(e=Me,t=fetch){let n=Ae.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(()=>Ae.delete(e)),Ae.set(e,n);return n}var Yt=(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"),ve=(e,t)=>Yt(e)?[e[0]+t,e[1],e[2]]:Array.isArray(e)?e.map((n)=>ve(n,t)):e&&typeof e==="object"?Object.fromEntries(Object.entries(e).map(([n,r])=>[n,ve(r,t)])):e;function Jt(e,t={}){let n=[],r=0,s={},o={};for(let h of e){let d=h.buffer;if(!d)throw Error("ldr: mergePacks needs packs from decodePack/loadPack");let S=new DataView(d).getUint32(0,!0),u=new Uint8Array(d,4+S),b=r;n.push(u),r+=u.byteLength;let P=(4-r%4)%4;if(P)n.push(new Uint8Array(P)),r+=P;for(let[g,f]of Object.entries(h.header.parts??{}))if(!(g in s))s[g]=ve(f,b);for(let[g,f]of Object.entries(h.header.studKinds??{}))if(!(g in o))o[g]=ve(f,b)}let i=e[0]?.header??{version:1,weld:!0},l=new TextEncoder().encode(JSON.stringify({...i,parts:s,studKinds:o,...t})),a=(4-(4+l.length)%4)%4,c=4+l.length+a,p=new Uint8Array(c+r);new DataView(p.buffer).setUint32(0,l.length+a,!0),p.set(l,4),p.fill(32,4+l.length,c);let m=c;for(let h of n)p.set(h,m),m+=h.byteLength;return de(p.buffer)}async function Zt(e,t={}){e=[...e];try{return await ft(e,t)}catch(n){let r=t.cdn??Me,s=t.fetch??fetch;Ae.delete(r);let o=(i,l)=>s(i,{...l,cache:"reload"});try{return await ft(e,{...t,fetch:o})}catch{throw n}}}async function ft(e,t){let n=t.cdn??Me,r=t.fetch??fetch,s=t.gap??16384,o=await pt(n,r),i=[...new Set([...e].map(J))],l=[],a=[];for(let u of i){if(we.has(n+u))continue;let b=o.parts[u];if(b)a.push({name:u,off:b[0],len:b[1],file:b[2]??0});else l.push(u)}a.sort((u,b)=>u.file-b.file||u.off-b.off);let c=[];for(let u of a){let b=c[c.length-1];if(b&&b.file===u.file&&u.off-b.end<=s)b.end=Math.max(b.end,u.off+u.len),b.items.push(u);else c.push({file:u.file,start:u.off,end:u.off+u.len,items:[u]})}let p=0,m=0,h=async()=>{while(m<c.length){let u=c[m++],b=await r(new URL(o.archives[u.file],n).href,{headers:{Range:`bytes=${u.start}-${u.end-1}`}});if(!b.ok)throw Error(`ldr: parts CDN ${b.status}`);let P=new Uint8Array(await b.arrayBuffer());if(b.status===200)P=P.subarray(u.start,u.end);p+=P.byteLength;for(let g of u.items){let f=je(P.subarray(g.off-u.start,g.off-u.start+g.len)),A=f.buffer.slice(f.byteOffset,f.byteOffset+f.byteLength);we.set(n+g.name,de(A))}}};await Promise.all(Array.from({length:Math.min(t.concurrency??24,c.length)},h));let d=i.filter((u)=>we.has(n+u)).map((u)=>we.get(n+u));return{pack:d.length?Jt(d,{colors:o.colors}):de(qt(o.colors)),missing:l,requests:c.length,bytes:p}}function qt(e){let t=new TextEncoder().encode(JSON.stringify({version:1,weld:!0,parts:{},studKinds:{},colors: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}async function mt(e,t={}){let n=performance.now(),r=t.fetch??fetch,s=pt(t.cdn??Me,r);s.catch(()=>{});let o=t.text?e:await r(e).then((f)=>{if(!f.ok)throw Error(`ldr: ${f.status} fetching ${e}`);return f.text()}),i=performance.now(),l=t.name??(t.text?"main.ldr":decodeURIComponent(e.split(/[?#]/)[0].split("/").pop()||"main.ldr")),a=at(o,l,{looseGeometry:!1,callouts:t.callouts}),c=performance.now();t.onParsed?.(a),await s;let p=lt(o,new Set(a.filter((f)=>f.embedded).map((f)=>f.part)),l),{pack:m,missing:h,requests:d,bytes:S}=await Zt([...a.filter((f)=>!f.embedded).map((f)=>f.part),...p.values()],t),u=new Map([...p].map(([f,A])=>[A,f])),b=h.map((f)=>u.get(f)??f);for(let[f,A]of p){let O=m.header.parts[A];if(O)m.header.parts[f]=O}let P=performance.now(),g=t.cull?xe(a,m.header,t.textures!==!1):void 0;return{insts:a,pack:m,missing:b,requests:d,bytes:S,cull:g,timings:{fetchModel:i-n,parse:c-i,parts:P-c,...g?{cull:performance.now()-P}:{}}}}self.onmessage=async(e)=>{let{id:t,source:n,opts:r}=e.data;try{let s=await mt(n,{...r,cull:!1,onParsed:(p)=>self.postMessage({id:t,insts:p})}),o=s.pack.buffer;if(self.postMessage({id:t,buffer:o,missing:s.missing,requests:s.requests,bytes:s.bytes,timings:s.timings},[o]),!r.cull)return;let i=performance.now(),l=xe(s.insts,s.pack.header,r.textures!==!1),a=performance.now()-i,c=[];for(let p of[l.studHidden,l.studUp,l.underHidden,l.studHideStep,l.underHideStep])if(p)c.push(p.buffer);self.postMessage({id:t,cull:l,ms:a},c)}catch(s){self.postMessage({id:t,phase:"error",error:String(s?.message??s)})}};\n';
2997
3304
 
2998
- // ../../../../../../../tmp/ldr-build-eZnTdy/src/cdn.ts
3305
+ // ../../../../../../../tmp/ldr-build-sEUhaY/src/cdn.ts
2999
3306
  var worker;
3000
3307
  var seq = 0;
3001
3308
  var pending = new Map;