@adatechnology/game-weapons-three 0.11.1 → 0.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16241,6 +16241,94 @@ ${problems.map((problem) => ` - ${problem}`).join("\n")}`);
16241
16241
  return mesh3;
16242
16242
  });
16243
16243
  }
16244
+ var isTexture = (v) => !!v && typeof v === "object" && v.isTexture === true;
16245
+ function texturesOf(material, out) {
16246
+ for (const value of Object.values(material)) if (isTexture(value)) out.add(value);
16247
+ const uniforms = material.uniforms;
16248
+ if (uniforms) {
16249
+ for (const u of Object.values(uniforms)) if (isTexture(u?.value)) out.add(u.value);
16250
+ }
16251
+ }
16252
+ function collect(roots) {
16253
+ const geometries = /* @__PURE__ */ new Set();
16254
+ const materials = /* @__PURE__ */ new Set();
16255
+ const textures = /* @__PURE__ */ new Set();
16256
+ const skeletons = /* @__PURE__ */ new Set();
16257
+ for (const root of roots) {
16258
+ root.traverse((object2) => {
16259
+ const o = object2;
16260
+ if (o.geometry && typeof o.geometry.dispose === "function") geometries.add(o.geometry);
16261
+ if (o.skeleton && typeof o.skeleton.dispose === "function") skeletons.add(o.skeleton);
16262
+ const list2 = Array.isArray(o.material) ? o.material : o.material ? [o.material] : [];
16263
+ for (const m of list2) {
16264
+ if (!m || typeof m.dispose !== "function") continue;
16265
+ materials.add(m);
16266
+ texturesOf(m, textures);
16267
+ }
16268
+ });
16269
+ }
16270
+ return { geometries, materials, textures, skeletons };
16271
+ }
16272
+ var marked = /* @__PURE__ */ new WeakSet();
16273
+ function markShared(...resources) {
16274
+ for (const resource of resources) marked.add(resource);
16275
+ return resources;
16276
+ }
16277
+ var shared = (r) => r.userData?.shared === true || marked.has(r);
16278
+ function releaseObject3D(roots, options = {}) {
16279
+ const list2 = Array.isArray(roots) ? roots : [roots];
16280
+ const report = { geometries: 0, materials: 0, textures: 0 };
16281
+ if (list2.length === 0) return report;
16282
+ const found = collect(list2);
16283
+ const keepRoots = options.keep === void 0 ? [] : Array.isArray(options.keep) ? options.keep : [options.keep];
16284
+ const releasing = new Set(list2);
16285
+ for (const keep of keepRoots) {
16286
+ const walk = (o) => {
16287
+ if (releasing.has(o)) return;
16288
+ const owner = o;
16289
+ if (owner.geometry) found.geometries.delete(owner.geometry);
16290
+ if (owner.skeleton) found.skeletons.delete(owner.skeleton);
16291
+ const mats = Array.isArray(owner.material) ? owner.material : owner.material ? [owner.material] : [];
16292
+ for (const m of mats) {
16293
+ if (!m) continue;
16294
+ found.materials.delete(m);
16295
+ const t = /* @__PURE__ */ new Set();
16296
+ texturesOf(m, t);
16297
+ for (const x of t) found.textures.delete(x);
16298
+ }
16299
+ for (const c of o.children) walk(c);
16300
+ };
16301
+ walk(keep);
16302
+ }
16303
+ for (const g of found.geometries) {
16304
+ if (shared(g)) continue;
16305
+ g.dispose();
16306
+ report.geometries++;
16307
+ }
16308
+ for (const m of found.materials) {
16309
+ if (shared(m)) continue;
16310
+ m.dispose();
16311
+ report.materials++;
16312
+ }
16313
+ for (const t of found.textures) {
16314
+ if (shared(t)) continue;
16315
+ t.dispose();
16316
+ report.textures++;
16317
+ }
16318
+ for (const s of found.skeletons) s.dispose();
16319
+ return report;
16320
+ }
16321
+ function discardObject3D(objects, options = {}) {
16322
+ const list2 = Array.isArray(objects) ? objects : [objects];
16323
+ const keep = options.keep === void 0 ? [] : Array.isArray(options.keep) ? [...options.keep] : [options.keep];
16324
+ for (const object2 of list2) {
16325
+ let top = object2;
16326
+ while (top.parent) top = top.parent;
16327
+ object2.removeFromParent();
16328
+ if (top !== object2 && !keep.includes(top)) keep.push(top);
16329
+ }
16330
+ return releaseObject3D(list2, { keep });
16331
+ }
16244
16332
 
16245
16333
  // ../game-props3d/dist/index.js
16246
16334
  function rng(seed) {
@@ -19439,9 +19527,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
19439
19527
  const tz = 2 * (qx * v[1] - qy * v[0]);
19440
19528
  return [v[0] + qw * tx + (qy * tz - qz * ty), v[1] + qw * ty + (qz * tx - qx * tz), v[2] + qw * tz + (qx * ty - qy * tx)];
19441
19529
  };
19442
- var toLocal = (position, rotation, p) => rotateVec([-rotation[0], -rotation[1], -rotation[2], rotation[3]], [p[0] - position[0], p[1] - position[1], p[2] - position[2]]);
19443
- var toWorld = (position, rotation, p) => {
19444
- const r = rotateVec(rotation, p);
19530
+ var toLocal = (position, rotation2, p) => rotateVec([-rotation2[0], -rotation2[1], -rotation2[2], rotation2[3]], [p[0] - position[0], p[1] - position[1], p[2] - position[2]]);
19531
+ var toWorld = (position, rotation2, p) => {
19532
+ const r = rotateVec(rotation2, p);
19445
19533
  return [r[0] + position[0], r[1] + position[1], r[2] + position[2]];
19446
19534
  };
19447
19535
  var shapeDims = (s) => {
@@ -19846,8 +19934,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
19846
19934
  };
19847
19935
  var cellsOutside = (cells, thin, point, radius) => cells.filter((c) => planeDistance(c, thin, point) > radius);
19848
19936
  var MAX_MARKS_PER_FRAGMENT = 12;
19849
- var marksInBox = (center, size, rotation, holes) => {
19850
- const inverse = rotation ? quat.conjugate(rotation) : void 0;
19937
+ var marksInBox = (center, size, rotation2, holes) => {
19938
+ const inverse = rotation2 ? quat.conjugate(rotation2) : void 0;
19851
19939
  const marks = [];
19852
19940
  for (const hole of holes) {
19853
19941
  const offset = [hole.point[0] - center[0], hole.point[1] - center[1], hole.point[2] - center[2]];
@@ -21989,6 +22077,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
21989
22077
  var CHIP_ENERGY = 200;
21990
22078
  var CHIP_SPLASH = 0.5;
21991
22079
  var CRATER_SPENT = 0.6;
22080
+ var EDGE_REACH = 1.5;
21992
22081
  var BAR_BOW = 0.08;
21993
22082
  var BULLET_JOINT_SPAN = 0.3;
21994
22083
  var CUT_SLICE = 1;
@@ -22440,8 +22529,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
22440
22529
  }
22441
22530
  solveStructure(o);
22442
22531
  if (peak <= sec.steel) return;
22443
- const rotation = (elasticEnergy(peak, L, EI, flexure.loadFactor) - elasticEnergy(sec.steel, L, EI, flexure.loadFactor)) / (2 * sec.steel);
22444
- p.rt.hinge = (p.rt.hinge ?? 0) + rotation;
22532
+ const rotation2 = (elasticEnergy(peak, L, EI, flexure.loadFactor) - elasticEnergy(sec.steel, L, EI, flexure.loadFactor)) / (2 * sec.steel);
22533
+ p.rt.hinge = (p.rt.hinge ?? 0) + rotation2;
22445
22534
  markDamaged(p);
22446
22535
  if (p.rt.hinge >= flexure.failRotationDeg * Math.PI / 180) hingeDrop(o, p, src);
22447
22536
  };
@@ -23143,8 +23232,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23143
23232
  const detachEvents = (o, opened, by, src) => {
23144
23233
  for (const j of opened) emit2({ ...base(o, src), type: "detach", joint: j.spec.id, parts: [j.spec.a, j.spec.b], by, groups: o.st.groups.map((g) => [...g]) });
23145
23234
  };
23146
- const slideOffResting = (o, rotation) => {
23147
- const upY = 1 - 2 * (rotation[0] * rotation[0] + rotation[2] * rotation[2]);
23235
+ const slideOffResting = (o, rotation2) => {
23236
+ const upY = 1 - 2 * (rotation2[0] * rotation2[0] + rotation2[2] * rotation2[2]);
23148
23237
  if (upY >= RESTING_HOLD_COS) return;
23149
23238
  const opened = o.joints.filter((j) => j.spec.kind === "resting" && !j.st.open);
23150
23239
  if (opened.length === 0) return;
@@ -23362,6 +23451,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23362
23451
  const lo = cell.center[a] - cell.size[a] / 2 + w / 2, hi = cell.center[a] + cell.size[a] / 2 - w / 2;
23363
23452
  size[a] = w;
23364
23453
  center[a] = clamp2(lp[a], lo, hi);
23454
+ const [from, to] = tornToEdge({ p, cell, a, b: a === u ? v : u, at: lp[a], crater: [center[a] - w / 2, center[a] + w / 2], reach: w * EDGE_REACH, gone: (k) => worn[k] === -1 });
23455
+ size[a] = to - from;
23456
+ center[a] = (from + to) / 2;
23365
23457
  }
23366
23458
  const taken2 = (cut[i] ?? 0) + size[u] * size[v];
23367
23459
  if (taken2 >= cell.size[u] * cell.size[v] * CRATER_SPENT) {
@@ -23399,6 +23491,19 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
23399
23491
  collapseCheck(o, src);
23400
23492
  }
23401
23493
  };
23494
+ const tornToEdge = (o) => {
23495
+ const { p, cell, a, b, at: at3, crater: crater2, reach, gone } = o;
23496
+ const half = p.dims[a] / 2;
23497
+ const lo = cell.center[a] - cell.size[a] / 2, hi = cell.center[a] + cell.size[a] / 2;
23498
+ const free = (side, sign2) => {
23499
+ if (sign2 > 0 ? side >= half - 1e-6 : side <= -half + 1e-6) return sign2 > 0 || a !== planeAxes(p.thin)[1];
23500
+ const probe = side + sign2 * 1e-3;
23501
+ return gridOf(p).some((c, k) => gone(k) && Math.abs(probe - c.center[a]) <= c.size[a] / 2 && Math.abs(cell.center[b] - c.center[b]) <= c.size[b] / 2);
23502
+ };
23503
+ if (at3 - lo <= reach && free(lo, -1)) return [lo, Math.max(crater2[1], lo)];
23504
+ if (hi - at3 <= reach && free(hi, 1)) return [Math.min(crater2[0], hi), hi];
23505
+ return crater2;
23506
+ };
23402
23507
  const craterAcross = (energy) => clamp2(0.03 + 12e-4 * Math.sqrt(Math.max(0, energy)), 0.03, 0.14);
23403
23508
  const craterFragments = (o, p, cell, dir, speed, mass, tag) => {
23404
23509
  const { c, q } = partXf(o, p);
@@ -24551,11 +24656,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24551
24656
  impls.set(id, { impl, position: opts.position ?? [0, 0, 0], rotation: opts.rotation ?? [0, 0, 0, 1], poses: /* @__PURE__ */ new Map() });
24552
24657
  return id;
24553
24658
  },
24554
- setPartPose(objectId, partId, position, rotation) {
24555
- const q = quatFromEuler(...rotation ?? [0, 0, 0]);
24659
+ setPartPose(objectId, partId, position, rotation2) {
24660
+ const q = quatFromEuler(...rotation2 ?? [0, 0, 0]);
24556
24661
  const im = impls.get(objectId);
24557
24662
  if (im) {
24558
- im.impl.setPartPose?.(partId, position, rotation);
24663
+ im.impl.setPartPose?.(partId, position, rotation2);
24559
24664
  im.poses.set(partId, { pos: [position[0], position[1], position[2]], q });
24560
24665
  return;
24561
24666
  }
@@ -24572,17 +24677,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
24572
24677
  },
24573
24678
  has: (id) => taken(id),
24574
24679
  ids: () => [...objects.keys(), ...impls.keys()],
24575
- setTransform(id, position, rotation) {
24680
+ setTransform(id, position, rotation2) {
24576
24681
  const im = impls.get(id);
24577
24682
  if (im) {
24578
24683
  im.position = [position[0], position[1], position[2]];
24579
- im.rotation = [rotation[0], rotation[1], rotation[2], rotation[3]];
24684
+ im.rotation = [rotation2[0], rotation2[1], rotation2[2], rotation2[3]];
24580
24685
  return;
24581
24686
  }
24582
24687
  const o = getObj(id);
24583
- o.base = { pos: [position[0], position[1], position[2]], rot: [rotation[0], rotation[1], rotation[2], rotation[3]] };
24688
+ o.base = { pos: [position[0], position[1], position[2]], rot: [rotation2[0], rotation2[1], rotation2[2], rotation2[3]] };
24584
24689
  applySoilPose(o);
24585
- slideOffResting(o, rotation);
24690
+ slideOffResting(o, rotation2);
24586
24691
  },
24587
24692
  splitGroup(id, group, newId) {
24588
24693
  if (impls.has(id)) throw new Error(`object "${id}" is a registered DestructibleImpl and cannot be split; its module owns its pieces`);
@@ -28092,9 +28197,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28092
28197
  var SHARED_ROOMS = { west: { type: "laundry", label: "laundry_room" }, east: { type: "storage", label: "storage_room" } };
28093
28198
  var apartments = (plan) => (strip, { floor: floor2, plate, ceiling }) => {
28094
28199
  if (strip.length < plan.apartmentMin) {
28095
- const shared = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
28096
- const id = `${shared.label}_${floor2}_${strip.id}`;
28097
- return { rooms: [{ id, type: shared.type, label: shared.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor2, 0.9)], windows: exteriorWindows(id, strip.rect, plate, ceiling, { ...plan.window, width: 1.2 }) };
28200
+ const shared2 = SHARED_ROOMS[strip.id] ?? SHARED_ROOMS.east;
28201
+ const id = `${shared2.label}_${floor2}_${strip.id}`;
28202
+ return { rooms: [{ id, type: shared2.type, label: shared2.label, rect: [...strip.rect] }], doors: [stripDoor(id, strip, floor2, 0.9)], windows: exteriorWindows(id, strip.rect, plate, ceiling, { ...plan.window, width: 1.2 }) };
28098
28203
  }
28099
28204
  const count = Math.max(1, Math.round(strip.length / plan.apartment)), wide2 = strip.length / count;
28100
28205
  const parts = Array.from({ length: count }, (_, k) => apartment(strip, floor2, k, r22(k * wide2), r22((k + 1) * wide2), plate, ceiling, plan.window));
@@ -28208,7 +28313,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28208
28313
  var OPEN_ROOM_TYPES2 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
28209
28314
  var rectsOf = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
28210
28315
  var isOpenArea = (c) => OPEN_ROOM_TYPES2.has(c.type) || c.outdoor === true;
28211
- function installKernelGeometry(K, shared) {
28316
+ function installKernelGeometry(K, shared2) {
28212
28317
  const { THREE } = K;
28213
28318
  const GEO = {};
28214
28319
  {
@@ -28267,9 +28372,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28267
28372
  const cursor = { group: "lot", accs: /* @__PURE__ */ new Map(), rot: [], org: [0, 0, 0], ry: 0 };
28268
28373
  const PARTS = [];
28269
28374
  const MIRRORS = [];
28270
- shared.partCount = 0;
28375
+ shared2.partCount = 0;
28271
28376
  function part(type, pos, fn, meta = {}, parent, ry = 0) {
28272
- const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared.partCount++;
28377
+ const gA = cursor.group, oA = cursor.org, rA = cursor.ry, pieceA = cursor.pc, name = "part:" + (meta.id || type) + ":" + shared2.partCount++;
28273
28378
  PARTS.push({ name, parent: parent || gA, pos: pos.slice(), type, meta, ry });
28274
28379
  cursor.group = name;
28275
28380
  cursor.org = pos;
@@ -28304,7 +28409,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28304
28409
  }
28305
28410
  const _Y = new THREE.Vector3(0, 1, 0), _qa = new THREE.Quaternion(), _qb = new THREE.Quaternion();
28306
28411
  function pieceRecord(id, mat, role, extra) {
28307
- const M = shared.ctx.pieces;
28412
+ const M = shared2.ctx.pieces;
28308
28413
  let p = M.get(id);
28309
28414
  if (!p) {
28310
28415
  p = Object.assign({ id, mat, role: role || null }, extra);
@@ -28313,7 +28418,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28313
28418
  return p;
28314
28419
  }
28315
28420
  const structurePiece = (id) => {
28316
- const e = shared.ctx.structureIndex && shared.ctx.structureIndex[id];
28421
+ const e = shared2.ctx.structureIndex && shared2.ctx.structureIndex[id];
28317
28422
  return e ? pieceRecord(id, e.material, e.role, { floor: e.floor }) : null;
28318
28423
  };
28319
28424
  function accFor(mat) {
@@ -28762,7 +28867,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28762
28867
  const NO_SHADOW = /* @__PURE__ */ new Set(["dirt", "glass", "water", "screen", "building", "picture", "floor", "emissive"]);
28763
28868
  Object.assign(K, { createMaterials: createMaterials2, antiTile, dirtMaterial, CLOTHES_UNIFORMS, clothesMaterial, ORDER: ORDER2, NO_SHADOW });
28764
28869
  }
28765
- function installKernelCloseScene(K, shared) {
28870
+ function installKernelCloseScene(K, shared2) {
28766
28871
  const { THREE, NO_SHADOW, ORDER: ORDER2, PARTS, applyPart, cursor } = K;
28767
28872
  const assembleCars = (...a) => K.assembleCars(...a);
28768
28873
  const assembleMirrors = (...a) => K.assembleMirrors(...a);
@@ -28777,7 +28882,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28777
28882
  if (!fx.length) return;
28778
28883
  const u = m.userData, ids = [...new Set(fx.map((f) => f.id))], weight = {};
28779
28884
  for (const f of fx) {
28780
- const mt = shared.ctx.pieces.get(f.id).mat;
28885
+ const mt = shared2.ctx.pieces.get(f.id).mat;
28781
28886
  weight[mt] = (weight[mt] || 0) + f.v1 - f.v0;
28782
28887
  }
28783
28888
  u.ranges = fx;
@@ -28785,7 +28890,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28785
28890
  u.destructionMaterial = Object.keys(weight).sort((a, b) => weight[b] - weight[a])[0];
28786
28891
  if (ids.length === 1) {
28787
28892
  u.destructionPart = ids[0];
28788
- const pc = shared.ctx.pieces.get(ids[0]);
28893
+ const pc = shared2.ctx.pieces.get(ids[0]);
28789
28894
  if (pc.role) u.structuralRole = pc.role;
28790
28895
  }
28791
28896
  }
@@ -28828,7 +28933,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28828
28933
  if (P.meta.t0) applyPart(g, P.meta.t0);
28829
28934
  }
28830
28935
  (groups[P.parent] || (groups[P.parent] = new THREE.Group())).add(g);
28831
- if (P.meta.id) (shared.ctx.parts || (shared.ctx.parts = {}))[P.meta.id] = g;
28936
+ if (P.meta.id) (shared2.ctx.parts || (shared2.ctx.parts = {}))[P.meta.id] = g;
28832
28937
  }
28833
28938
  PARTS.length = 0;
28834
28939
  assembleMirrors(groups);
@@ -28838,20 +28943,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28838
28943
  }
28839
28944
  Object.assign(K, { markMesh, closeScene });
28840
28945
  }
28841
- function installHouseHelpers(K, shared) {
28842
- shared.ctx = {};
28946
+ function installHouseHelpers(K, shared2) {
28947
+ shared2.ctx = {};
28843
28948
  const OPEN_ROOM_TYPES22 = /* @__PURE__ */ new Set(["balcony", "terrace", "veranda", "balcony_gourmet"]);
28844
28949
  const NO_CEILING = OPEN_ROOM_TYPES22;
28845
28950
  const OPEN_AREA = (c) => OPEN_ROOM_TYPES22.has(c.type) || c.outdoor === true;
28846
28951
  const EPS6 = 1e-3;
28847
28952
  const Y0 = (f) => {
28848
- const A = shared.ctx.r.floors;
28953
+ const A = shared2.ctx.r.floors;
28849
28954
  return A[Math.max(0, Math.min(A.length - 1, f))].y0;
28850
28955
  };
28851
- const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared.ctx.colors[v] != null ? shared.ctx.colors[v] : null;
28956
+ const colorOf = (v) => typeof v === "number" ? v : typeof v === "string" && shared2.ctx.colors[v] != null ? shared2.ctx.colors[v] : null;
28852
28957
  const rectsOf2 = (c) => c.parts && c.parts.length ? c.parts : [[c.u0, c.v0, c.u1, c.v1]];
28853
28958
  function roomAt(f, u, v) {
28854
- for (const c of shared.ctx.r.rooms) if (c.floor === f) {
28959
+ for (const c of shared2.ctx.r.rooms) if (c.floor === f) {
28855
28960
  for (const [a, b, c2, d] of rectsOf2(c)) if (u > a + EPS6 && u < c2 - EPS6 && v > b + EPS6 && v < d - EPS6) return c;
28856
28961
  }
28857
28962
  return null;
@@ -28879,14 +28984,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28879
28984
  return [Math.min(...pts.map((p) => p[0])), Math.min(...pts.map((p) => p[1])), Math.max(...pts.map((p) => p[0])), Math.max(...pts.map((p) => p[1]))];
28880
28985
  }
28881
28986
  function effectiveHeight(f, h) {
28882
- const A = shared.ctx.r.floors;
28987
+ const A = shared2.ctx.r.floors;
28883
28988
  if (f + 1 >= A.length) return h;
28884
28989
  const pitch = A[f + 1].y0 - A[f].y0;
28885
28990
  return h > pitch && h - pitch <= 0.45 ? pitch : h;
28886
28991
  }
28887
28992
  Object.assign(K, { OPEN_ROOM_TYPES: OPEN_ROOM_TYPES22, NO_CEILING, OPEN_AREA, EPS: EPS6, Y0, colorOf, rectsOf: rectsOf2, roomAt, subRect, subRects, wallColor, floorColor, stairFootprint, effectiveHeight });
28888
28993
  }
28889
- function installHouseWalls(K, shared) {
28994
+ function installHouseWalls(K, shared2) {
28890
28995
  const { EPS: EPS6, Y0, boxC, bx, cursor, effectiveHeight, pieceRecord, structurePiece, wallColor } = K;
28891
28996
  function wallBox(alongU, L, a, b, ya, yb, th, cL, cH, mL, mH) {
28892
28997
  if (yb - ya < 1e-4 || b - a < 1e-4) return;
@@ -28899,10 +29004,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28899
29004
  }
28900
29005
  }
28901
29006
  function sideOf(id, frontLine) {
28902
- const R = shared.ctx.r, F = R.facade;
28903
- if (id === "outside" || !shared.ctx.roomById[id]) {
29007
+ const R = shared2.ctx.r, F = R.facade;
29008
+ if (id === "outside" || !shared2.ctx.roomById[id]) {
28904
29009
  const ac = F.finish;
28905
- let mat = "plaster", color2 = shared.ctx.colors.facade;
29010
+ let mat = "plaster", color2 = shared2.ctx.colors.facade;
28906
29011
  if (ac === "roughcast") mat = "roughcast";
28907
29012
  else if (ac === "exposed_block") {
28908
29013
  mat = "block";
@@ -28913,12 +29018,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28913
29018
  }
28914
29019
  return { color: color2, mat, exterior: true };
28915
29020
  }
28916
- return { color: wallColor(shared.ctx.roomById[id]), mat: "plaster", exterior: false };
29021
+ return { color: wallColor(shared2.ctx.roomById[id]), mat: "plaster", exterior: false };
28917
29022
  }
28918
29023
  const pieceOf = (w) => !w.id ? null : structurePiece(w.id) || pieceRecord(w.id, w.material || "brick", w.role || "partition", { floor: w.floor });
28919
29024
  function nearestWall(f, axis2, L, c) {
28920
29025
  let m = null, md = 1e9;
28921
- for (const w of shared.ctx.r.walls) {
29026
+ for (const w of shared2.ctx.r.walls) {
28922
29027
  if (w.floor !== f || w.axis !== axis2 || w.type !== "wall" || Math.abs((axis2 === "u" ? w.v0 : w.u0) - L) > EPS6) continue;
28923
29028
  const a = Math.min(axis2 === "u" ? w.u0 : w.v0, axis2 === "u" ? w.u1 : w.v1), b = Math.max(axis2 === "u" ? w.u0 : w.v0, axis2 === "u" ? w.u1 : w.v1), d = c < a ? a - c : c > b ? c - b : 0;
28924
29029
  if (d < md) {
@@ -28929,7 +29034,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28929
29034
  return m;
28930
29035
  }
28931
29036
  function walls() {
28932
- const R = shared.ctx.r, cut = shared.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
29037
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, nA = R.floors.length, vMin = Math.min(...R.walls.map((w) => w.axis === "u" ? w.v0 : Math.min(w.v0, w.v1)));
28933
29038
  const corners = /* @__PURE__ */ new Map();
28934
29039
  for (const w of R.walls) {
28935
29040
  const f = w.floor;
@@ -28940,9 +29045,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28940
29045
  const hh = cut ? Math.min(h, 1.2) : h, L = alongU ? w.v0 : w.u0, s0 = Math.min(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1), s1 = Math.max(alongU ? w.u0 : w.v0, alongU ? w.u1 : w.v1);
28941
29046
  const front = alongU && Math.abs(L - vMin) < 0.05;
28942
29047
  const sideL = sideOf(w.sides[0], front), sideH = sideOf(w.sides[1], front);
28943
- shared.ctx.colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
29048
+ shared2.ctx.colliders.push({ type: "wall", piece: w.id, f, x0: alongU ? s0 : L - th / 2, z0: alongU ? L - th / 2 : s0, x1: alongU ? s1 : L + th / 2, z1: alongU ? L + th / 2 : s1 });
28944
29049
  if (w.type === "railing") {
28945
- const c0 = shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9080466;
29050
+ const c0 = shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9080466;
28946
29051
  const sx = alongU ? 1 : 0, sz = alongU ? 0 : 1, len = s1 - s0, n = Math.max(1, Math.round(len / 1.4));
28947
29052
  const cx_ = alongU ? (s0 + s1) / 2 : L, cz_ = alongU ? L : (s0 + s1) / 2;
28948
29053
  boxC("glass", cx_, y0 + 0.55, cz_, alongU ? len : 0.02, 0.85, alongU ? 0.02 : len, 16777215);
@@ -28989,7 +29094,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28989
29094
  }
28990
29095
  Object.assign(K, { wallBox, sideOf, pieceOf, nearestWall, walls });
28991
29096
  }
28992
- function installHouseDoors(K, shared) {
29097
+ function installHouseDoors(K, shared2) {
28993
29098
  const seedKey = (id) => K.seedKey(id);
28994
29099
  const { EPS: EPS6, Y0, boxC, bx, cursor, effectiveHeight, nearestWall, part, pieceOf, pieceRecord, roomAt, sideOf, wallBox } = K;
28995
29100
  const SEED = (...a) => K.SEED(...a);
@@ -28997,15 +29102,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
28997
29102
  const rngString = (...a) => K.rngString(...a);
28998
29103
  const sh = (...a) => K.sh(...a);
28999
29104
  function doorLineSides(p) {
29000
- const R = shared.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
29105
+ const R = shared2.ctx.r, alongU = p.axis === "u", a = p.at - p.width / 2, b = p.at + p.width / 2;
29001
29106
  const w = R.walls.find((w2) => w2.floor === p.floor && w2.axis === p.axis && Math.abs((alongU ? w2.v0 : w2.u0) - p.pos) < EPS6 && w2.type === "wall" && (Math.abs((alongU ? w2.u1 : w2.v1) - a) < 0.02 || Math.abs((alongU ? w2.u0 : w2.v0) - b) < 0.02));
29002
29107
  const sides = w ? w.sides : [p.a, p.b];
29003
29108
  return [sideOf(sides[0], false), sideOf(sides[1], false)];
29004
29109
  }
29005
- shared.doorState = /* @__PURE__ */ new Map();
29110
+ shared2.doorState = /* @__PURE__ */ new Map();
29006
29111
  function doors() {
29007
- shared.ctx.leaves = [];
29008
- const R = shared.ctx.r, cut = shared.ctx.cut, C = shared.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
29112
+ shared2.ctx.leaves = [];
29113
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, wood = C.wood != null ? C.wood : 8016948, frame2 = sh(wood, 0.55);
29009
29114
  for (const p of R.doors) {
29010
29115
  const f = p.floor;
29011
29116
  cursor.group = "f" + f;
@@ -29035,12 +29140,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29035
29140
  }
29036
29141
  const leaf = (u0, u1, y_0, y_1, tt, color2, mat = "wood") => alongU ? bx(mat, u0, y0 + y_0, L - tt / 2, u1, y0 + y_1, L + tt / 2, color2) : bx(mat, L - tt / 2, y0 + y_0, u0, L + tt / 2, y0 + y_1, u1, color2);
29037
29142
  const extC = wood;
29038
- const open0 = p.blocked ? false : shared.doorState.has(p.id) ? shared.doorState.get(p.id) : !!p.open;
29039
- shared.doorState.set(p.id, open0);
29143
+ const open0 = p.blocked ? false : shared2.doorState.has(p.id) ? shared2.doorState.get(p.id) : !!p.open;
29144
+ shared2.doorState.set(p.id, open0);
29040
29145
  const dc = alongU ? [p.at, L] : [L, p.at];
29041
29146
  const fo = { id: p.id, floor: f, type: p.model === "steel" ? "steel" : "swing", open: open0, t: open0 ? 1 : 0, blockedFlag: !!p.blocked, locked: R.state === "fortified" && !!p.exterior, handleNames: [], hT: 0, cx: dc[0], cz: dc[1], visH, groups: [], col: null };
29042
29147
  const colR = { type: "door", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b, off: open0 };
29043
- shared.ctx.colliders.push(colR);
29148
+ shared2.ctx.colliders.push(colR);
29044
29149
  fo.col = colR;
29045
29150
  const leafBox = (hu, d0, d1, y_0, y_1, tt, color2, mat) => alongU ? bx(mat, d0, y_0, -tt / 2, d1, y_1, tt / 2, color2) : bx(mat, -tt / 2, y_0, d0, tt / 2, y_1, d1, color2);
29046
29151
  const newGroup = (k, hu, topY) => {
@@ -29100,7 +29205,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29100
29205
  fo.rot = Math.atan2(n[0] * A[1] - n[1] * A[0], A[0] * n[0] + A[1] * n[1]);
29101
29206
  }
29102
29207
  }
29103
- shared.ctx.leaves.push(fo);
29208
+ shared2.ctx.leaves.push(fo);
29104
29209
  cursor.group = "f" + f;
29105
29210
  if (p.blocked) {
29106
29211
  part("window_boards", [0, 0, 0], () => {
@@ -29128,18 +29233,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29128
29233
  }
29129
29234
  }
29130
29235
  }, { id: "boards:" + p.id }, "f" + f);
29131
- shared.ctx.colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
29236
+ shared2.ctx.colliders.push({ type: "board", f, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b });
29132
29237
  }
29133
29238
  }
29134
29239
  }
29135
29240
  Object.assign(K, { doorLineSides, doors });
29136
29241
  }
29137
- function installHouseWindows(K, shared) {
29242
+ function installHouseWindows(K, shared2) {
29138
29243
  const { EPS: EPS6, Y0, boxC, bx, cursor, pieceRecord, roomAt } = K;
29139
29244
  const FRAME_COLORS = { budget: 15856110, mid: 12830924, high: 2829875, commercial: 11844287 };
29140
29245
  const SILL_COLORS = { budget: 15131870, mid: 14277076, high: 3816770, commercial: 13225166 };
29141
29246
  function windows() {
29142
- const R = shared.ctx.r, cut = shared.ctx.cut, C = shared.ctx.colors, structure = R.style, fr = FRAME_COLORS[structure] || FRAME_COLORS.budget, pe_ = SILL_COLORS[structure] || SILL_COLORS.budget;
29247
+ const R = shared2.ctx.r, cut = shared2.ctx.cut, C = shared2.ctx.colors, structure = R.style, fr = FRAME_COLORS[structure] || FRAME_COLORS.budget, pe_ = SILL_COLORS[structure] || SILL_COLORS.budget;
29143
29248
  const boardItems = new Set(R.stateItems.filter((e) => e.type === "window_boards" && e.window).map((e) => e.window));
29144
29249
  for (const j of R.windows) {
29145
29250
  const f = j.floor;
@@ -29192,11 +29297,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29192
29297
  }
29193
29298
  Object.assign(K, { FRAME_COLORS, SILL_COLORS, windows });
29194
29299
  }
29195
- function installHouseFloors(K, shared) {
29300
+ function installHouseFloors(K, shared2) {
29196
29301
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor, floorColor, stairFootprint, structurePiece, subRects } = K;
29197
29302
  function flights() {
29198
- if (shared.ctx._flights && shared.ctx._flights.r === shared.ctx.r) return shared.ctx._flights.l;
29199
- const R = shared.ctx.r, mp = /* @__PURE__ */ new Map();
29303
+ if (shared2.ctx._flights && shared2.ctx._flights.r === shared2.ctx.r) return shared2.ctx._flights.l;
29304
+ const R = shared2.ctx.r, mp = /* @__PURE__ */ new Map();
29200
29305
  for (const m of R.items) {
29201
29306
  if (m.type !== "stairs" || !m.link) continue;
29202
29307
  const k = [m.link.from, m.link.to, m.x.toFixed(2), m.z.toFixed(2), (m.ry || 0).toFixed(2)].join("|");
@@ -29212,12 +29317,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29212
29317
  v.LP = LP;
29213
29318
  v.top = stairFootprint({ x: m.x + lz * Math.sin(m.ry), z: m.z + lz * Math.cos(m.ry), ry: m.ry, w: m.w, d: LP });
29214
29319
  }
29215
- shared.ctx._flights = { r: R, l };
29320
+ shared2.ctx._flights = { r: R, l };
29216
29321
  return l;
29217
29322
  }
29218
29323
  const panelRects = (p) => p.footprint && p.footprint.length ? p.footprint : [p.aabb];
29219
29324
  function tilesOf(parent, rc) {
29220
- const ps = parent && shared.ctx.panelsOf && shared.ctx.panelsOf.get(parent);
29325
+ const ps = parent && shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
29221
29326
  if (!ps) return [[parent ? structurePiece(parent) : null, rc]];
29222
29327
  const out = [], taken = [];
29223
29328
  for (const p of ps) for (const q of panelRects(p)) {
@@ -29231,14 +29336,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29231
29336
  return out;
29232
29337
  }
29233
29338
  function panelAt(parent, x, z) {
29234
- const ps = shared.ctx.panelsOf && shared.ctx.panelsOf.get(parent);
29339
+ const ps = shared2.ctx.panelsOf && shared2.ctx.panelsOf.get(parent);
29235
29340
  if (!ps) return structurePiece(parent);
29236
29341
  for (const p of ps) for (const q of panelRects(p)) if (x >= q[0] - EPS6 && x <= q[2] + EPS6 && z >= q[1] - EPS6 && z <= q[3] + EPS6) return structurePiece(p.id);
29237
29342
  return null;
29238
29343
  }
29239
- const hasSlab = (id) => !!(shared.ctx.structureIndex[id] || shared.ctx.panelsOf && shared.ctx.panelsOf.has(id));
29344
+ const hasSlab = (id) => !!(shared2.ctx.structureIndex[id] || shared2.ctx.panelsOf && shared2.ctx.panelsOf.has(id));
29240
29345
  function floorsAndSlabs() {
29241
- const R = shared.ctx.r, nA = R.floors.length, C = shared.ctx.colors;
29346
+ const R = shared2.ctx.r, nA = R.floors.length, C = shared2.ctx.colors;
29242
29347
  const V3 = flights(), holes = (f) => V3.filter((v) => v.to === f).flatMap((v) => {
29243
29348
  let rs = [v.rect];
29244
29349
  if (v.top) rs = subRects(rs, [v.top]);
@@ -29275,18 +29380,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29275
29380
  }
29276
29381
  Object.assign(K, { flights, floorsAndSlabs, tilesOf, panelAt });
29277
29382
  }
29278
- function installHouseStairs(K, shared) {
29383
+ function installHouseStairs(K, shared2) {
29279
29384
  const { rectsOf: rectsOf2, Y0, boxC, bx, cursor, flights, stairFootprint, structurePiece } = K;
29280
29385
  const sh = (...a) => K.sh(...a);
29281
29386
  function buildStairs() {
29282
- const R = shared.ctx.r;
29283
- shared.ctx.stairs = [];
29387
+ const R = shared2.ctx.r;
29388
+ shared2.ctx.stairs = [];
29284
29389
  for (const vo of flights()) {
29285
29390
  const m = vo.m, f = vo.from, Dr = m.d - (vo.LP || 0);
29286
29391
  cursor.group = "f" + f;
29287
29392
  cursor.pc = structurePiece("stairs_" + vo.from + "_" + vo.to);
29288
29393
  const y0 = Y0(f), H = Y0(m.link.to) - y0, n = Math.max(8, Math.round(H / 0.18)), c = Math.cos(m.ry), s = Math.sin(m.ry);
29289
- const wood = shared.ctx.colors.wood != null ? shared.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
29394
+ const wood = shared2.ctx.colors.wood != null ? shared2.ctx.colors.wood : 9071176, under = sh(wood, 0.7);
29290
29395
  const P = (lx, lz) => [m.x + lx * c + lz * s, m.z - lx * s + lz * c];
29291
29396
  const boxL = (mat, lx, y, lz, w, h, d, color2, rx = 0) => {
29292
29397
  const [px, pz] = P(lx, lz);
@@ -29308,16 +29413,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29308
29413
  }
29309
29414
  }
29310
29415
  cursor.pc = null;
29311
- shared.ctx.stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
29416
+ shared2.ctx.stairs.push({ m, f, to: vo.to, y0, H, rect: stairFootprint(m), landingPoint: (vo.LP || 0) / m.d });
29312
29417
  }
29313
29418
  }
29314
29419
  function elevator() {
29315
- const R = shared.ctx.r;
29420
+ const R = shared2.ctx.r;
29316
29421
  for (const c of R.rooms.filter((c2) => c2.type === "elevator" && c2.floor === 0)) {
29317
29422
  cursor.group = "f0";
29318
29423
  const [u0, v0, u1, v1] = rectsOf2(c)[0], y0 = Y0(0);
29319
29424
  bx("metal", u0 + 0.15, y0 + 0.05, v0 + 0.15, u1 - 0.15, y0 + 2.3, v1 - 0.15, 10133670);
29320
- bx("emissive", u0 + 0.3, y0 + 2.28, v0 + 0.3, u1 - 0.3, y0 + 2.3, v1 - 0.3, shared.ctx.night ? 16773320 : 13619924);
29425
+ bx("emissive", u0 + 0.3, y0 + 2.28, v0 + 0.3, u1 - 0.3, y0 + 2.3, v1 - 0.3, shared2.ctx.night ? 16773320 : 13619924);
29321
29426
  for (const f of R.floors) {
29322
29427
  const yy = Y0(f.index);
29323
29428
  cursor.group = "f" + f.index;
@@ -29327,7 +29432,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29327
29432
  }
29328
29433
  Object.assign(K, { buildStairs, elevator });
29329
29434
  }
29330
- function installLightsFixtures(K, shared) {
29435
+ function installLightsFixtures(K, shared2) {
29331
29436
  const seedKey = (id) => K.seedKey(id);
29332
29437
  const { cursor, part, polyFace } = K;
29333
29438
  const makeApi = (...a) => K.makeApi(...a);
@@ -29345,9 +29450,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29345
29450
  return ((t ^ t >>> 14) >>> 0) / 4294967296;
29346
29451
  };
29347
29452
  }
29348
- const SEED = () => shared.ctx.r && shared.ctx.r.seed || 0;
29349
- const STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
29350
- shared.api0 = null;
29453
+ const SEED = () => shared2.ctx.r && shared2.ctx.r.seed || 0;
29454
+ const STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
29455
+ shared2.api0 = null;
29351
29456
  function kit2(M, A, y0 = M.y || 0) {
29352
29457
  const c = Math.cos(M.ry), s = Math.sin(M.ry);
29353
29458
  let api = A;
@@ -29379,7 +29484,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29379
29484
  return null;
29380
29485
  }
29381
29486
  const a0 = api;
29382
- api = shared.api0 || (shared.api0 = makeApi());
29487
+ api = shared2.api0 || (shared2.api0 = makeApi());
29383
29488
  try {
29384
29489
  return part(type, W(lx, ly, lz), fn, meta || {}, void 0, M.ry);
29385
29490
  } finally {
@@ -29473,7 +29578,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29473
29578
  yLight = yc - 0.3;
29474
29579
  range2 = 6.5;
29475
29580
  } else if (type === "chandelier") {
29476
- const yc = t - 0.5, gold = shared.ctx.colors && shared.ctx.colors.metal != null ? shared.ctx.colors.metal : 9075290, N = 6;
29581
+ const yc = t - 0.5, gold = shared2.ctx.colors && shared2.ctx.colors.metal != null ? shared2.ctx.colors.metal : 9075290, N = 6;
29477
29582
  K2.c("metal", 0, yc, 0, 0.012, 0.5, gold);
29478
29583
  K2.e("metal", 0, yc - 0.03, 0, 0.055, 0.08, gold);
29479
29584
  K2.c("metal", 0, yc - 0.06, 0, 0.14, 0.015, gold);
@@ -29551,24 +29656,24 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29551
29656
  }
29552
29657
  Object.assign(K, { hashString, rngString, SEED, STYLE, kit2, arcPoints, TEMP_WARM, TEMP_NEUTRAL, TEMP_COOL, colorTemperature, lightStyle, ceilingLamp, tableLamp, floorLamp, sconce, outdoorLamp, lightSwitch });
29553
29658
  }
29554
- function installLightsDecor(K, shared) {
29659
+ function installLightsDecor(K, shared2) {
29555
29660
  const { EPS: EPS6, OPEN_AREA, SEED, Y0, cursor, rngString, roomAt, stairFootprint } = K;
29556
29661
  const lightItem = (...a) => K.lightItem(...a);
29557
29662
  function decorLights(api) {
29558
- const R = shared.ctx.r, T2 = shared.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd2 = rngString(SEED() + "|decorluz");
29663
+ const R = shared2.ctx.r, T2 = shared2.ctx.types, structure = R.style, chance = structure === "budget" ? 0.35 : structure === "mid" ? 0.75 : 1, rnd2 = rngString(SEED() + "|decorluz");
29559
29664
  const itemsF = (f) => R.items.filter((m) => (m.outdoor ? -1 : m.floor) === f && m.type !== "stairs");
29560
29665
  const rectsF = (f) => itemsF(f).filter((m) => (m.h || 0) > 0.3 && !/rug|floor|concrete|dirt|lawn|ceiling_light|curtain|blinds|picture|mirror|pendant|chandelier|spot/.test(m.type)).map((m) => stairFootprint(m));
29561
29666
  const free = (f, x, z, margin) => {
29562
29667
  if (!roomAt(f, x, z)) return false;
29563
- for (const c of shared.ctx.colliders) if (c.f === f && x > c.x0 - margin && x < c.x1 + margin && z > c.z0 - margin && z < c.z1 + margin) return false;
29668
+ for (const c of shared2.ctx.colliders) if (c.f === f && x > c.x0 - margin && x < c.x1 + margin && z > c.z0 - margin && z < c.z1 + margin) return false;
29564
29669
  for (const r of rectsF(f)) if (x > r[0] - margin && x < r[2] + margin && z > r[1] - margin && z < r[3] + margin) return false;
29565
29670
  return true;
29566
29671
  };
29567
29672
  const puts = (f, type, m0, extra) => {
29568
29673
  const ent = T2[type];
29569
29674
  if (!ent) return;
29570
- const com = shared.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
29571
- const M = Object.assign({ x: m0.x, z: m0.z, ry: m0.ry || 0, w: m0.w || 0.3, d: m0.d || 0.3, h: m0.h || 0.3, y: 0, base, floor: f, colors: shared.ctx.colors, seed: m0.id, room: m0.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.8, on: shared.ctx.night, light: shared.ctx.night, lit: shared.ctx.night }, extra || {});
29675
+ const com = shared2.ctx.roomById[m0.room], g = "f" + f, base = Y0(f);
29676
+ const M = Object.assign({ x: m0.x, z: m0.z, ry: m0.ry || 0, w: m0.w || 0.3, d: m0.d || 0.3, h: m0.h || 0.3, y: 0, base, floor: f, colors: shared2.ctx.colors, seed: m0.id, room: m0.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.8, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night }, extra || {});
29572
29677
  cursor.group = g;
29573
29678
  lightItem({ id: m0.id, room: m0.room }, M, ent, api, g);
29574
29679
  };
@@ -29616,18 +29721,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29616
29721
  }
29617
29722
  Object.assign(K, { decorLights });
29618
29723
  }
29619
- function installLotTerrain(K, shared) {
29724
+ function installLotTerrain(K, shared2) {
29620
29725
  const { rectsOf: rectsOf2, MIRRORS, PARTS, bx, cursor } = K;
29621
29726
  function terrain() {
29622
29727
  PARTS.length = 0;
29623
29728
  MIRRORS.length = 0;
29624
29729
  K.CARS.length = 0;
29625
- shared.partCount = 0;
29626
- shared.ctx.parts = {};
29627
- shared.tapCount = 0;
29628
- shared.ctx.clotheslines = [];
29629
- if (shared.ctx.noTerrain) return;
29630
- const R = shared.ctx.r, lt2 = R.lot, C = shared.ctx.colors;
29730
+ shared2.partCount = 0;
29731
+ shared2.ctx.parts = {};
29732
+ shared2.tapCount = 0;
29733
+ shared2.ctx.clotheslines = [];
29734
+ if (shared2.ctx.noTerrain) return;
29735
+ const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
29631
29736
  cursor.group = "floor";
29632
29737
  const light = (c, f) => {
29633
29738
  const m = (k) => Math.round((c >> k & 255) * (1 - f) + 255 * f);
@@ -29641,13 +29746,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29641
29746
  bx("sidewalk", u0 - 40, -0.06, v0 - 1.8, u1 + 40, 0.02, v0, 14999766);
29642
29747
  for (let x = u0 - 38; x < u1 + 40; x += 6) bx("plaster", x, 0, v0 - 5.6, x + 2.6, 5e-3, v0 - 5.4, 15262904);
29643
29748
  } else {
29644
- const b = shared.ctx.limits;
29749
+ const b = shared2.ctx.limits;
29645
29750
  bx("sidewalk", b.x0 - 6, -0.09, b.z0 - 6, b.x1 + 6, -0.03, b.z1 + 6, 14605010);
29646
29751
  }
29647
29752
  }
29648
29753
  function freeSpans(alongU, L, a, b) {
29649
29754
  const blocks = [];
29650
- for (const c of shared.ctx.r.rooms) {
29755
+ for (const c of shared2.ctx.r.rooms) {
29651
29756
  if (c.type === "void" || c.floor < 0) continue;
29652
29757
  for (const [u0, v0, u1, v1] of rectsOf2(c)) {
29653
29758
  const c0 = alongU ? v0 : u0, c1 = alongU ? v1 : u1, lo = alongU ? u0 : v0, hi = alongU ? u1 : v1;
@@ -29667,12 +29772,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29667
29772
  }
29668
29773
  Object.assign(K, { terrain, freeSpans });
29669
29774
  }
29670
- function installLotPerimeter(K, shared) {
29775
+ function installLotPerimeter(K, shared2) {
29671
29776
  const { EPS: EPS6, boxC, bx, colorOf, cursor, freeSpans, pieceRecord } = K;
29672
29777
  const makeApi = (...a) => K.makeApi(...a);
29673
29778
  const sh = (...a) => K.sh(...a);
29674
29779
  function perimeter() {
29675
- const R = shared.ctx.r, lt2 = R.lot, C = shared.ctx.colors;
29780
+ const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
29676
29781
  if (!lt2) return;
29677
29782
  cursor.group = "lot";
29678
29783
  const rnd2 = /* @__PURE__ */ (() => {
@@ -29686,7 +29791,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29686
29791
  const th = s.thickness || 0.15, h = s.height, color2 = colorOf(s.color) != null ? colorOf(s.color) : C.wall || 12104874, len = b - a;
29687
29792
  const B = (mat, u0, y0, u1, y1, t, c, off = 0) => alongU ? bx(mat, u0, y0, L + off - t / 2, u1, y1, L + off + t / 2, c) : bx(mat, L + off - t / 2, y0, u0, L + off + t / 2, y1, u1, c);
29688
29793
  const col = { type: "lot_wall", f: -1, x0: alongU ? a : L - th / 2, z0: alongU ? L - th / 2 : a, x1: alongU ? b : L + th / 2, z1: alongU ? L + th / 2 : b };
29689
- shared.ctx.colliders.push(col);
29794
+ shared2.ctx.colliders.push(col);
29690
29795
  if (s.type === "wall") {
29691
29796
  B("plaster", a, 0, b, h, th, color2);
29692
29797
  B("plaster", a, h, b, h + 0.05, th + 0.06, sh(color2, 1.15));
@@ -29725,7 +29830,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29725
29830
  const w2 = x1 - x0, cm = (x0 + x1) / 2;
29726
29831
  const M = top === "razor_wire" ? { x: alongU ? cm : L, z: alongU ? L : cm, ry: alongU ? 0 : K.PE, w: w2, d: 0.4, h: 0.4, y: ym, base: 0, floor: -1, colors: C, seed: s.id } : { x: alongU ? cm : L, z: alongU ? L : cm, ry: alongU ? 0 : K.PE, w: w2, d: 0.1, h: 0.3, y: 0, base: ym, floor: -1, colors: C, seed: s.id };
29727
29832
  try {
29728
- shared.ctx.mv.builders[top](M, api);
29833
+ shared2.ctx.mv.builders[top](M, api);
29729
29834
  } catch (e) {
29730
29835
  console.warn(e);
29731
29836
  }
@@ -29746,7 +29851,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29746
29851
  }
29747
29852
  }
29748
29853
  function paths() {
29749
- const lt2 = shared.ctx.r.lot;
29854
+ const lt2 = shared2.ctx.r.lot;
29750
29855
  if (!lt2 || !lt2.paths) return;
29751
29856
  cursor.group = "lot";
29752
29857
  for (const c of lt2.paths) {
@@ -29759,14 +29864,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29759
29864
  }
29760
29865
  Object.assign(K, { perimeter, paths });
29761
29866
  }
29762
- function installLotGates(K, shared) {
29867
+ function installLotGates(K, shared2) {
29763
29868
  const { bx, colorOf, cursor, cylBase } = K;
29764
29869
  const sh = (...a) => K.sh(...a);
29765
29870
  function slideDirection(g, lt2) {
29766
29871
  return g.u + g.width / 2 + g.width + 1.2 <= lt2.rect[2] ? 1 : -1;
29767
29872
  }
29768
29873
  function gates() {
29769
- const R = shared.ctx.r, lt2 = R.lot, C = shared.ctx.colors;
29874
+ const R = shared2.ctx.r, lt2 = R.lot, C = shared2.ctx.colors;
29770
29875
  if (!lt2) return;
29771
29876
  cursor.group = "lot";
29772
29877
  const structure = R.style, auto = structure !== "budget", wall = colorOf("wall") || 12104874, cu = (lt2.rect[0] + lt2.rect[2]) / 2, cz = (lt2.rect[1] + lt2.rect[3]) / 2;
@@ -29840,12 +29945,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29840
29945
  bx("emissive", mx + 0.1, 0.28, zc + sd * 0.452, mx + 0.14, 0.31, zc + sd * 0.455, 6479994);
29841
29946
  }
29842
29947
  }
29843
- if (!g.open || ped) shared.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
29948
+ if (!g.open || ped) shared2.ctx.colliders.push({ type: "gate", f: -1, x0: a, z0: v - 0.1, x1: b, z1: v + 0.1 });
29844
29949
  }
29845
29950
  }
29846
29951
  Object.assign(K, { slideDirection, gates });
29847
29952
  }
29848
- function installRoofRoofs(K, shared) {
29953
+ function installRoofRoofs(K, shared2) {
29849
29954
  const { rectsOf: rectsOf2, EPS: EPS6, OPEN_AREA, Y0, bx, cursor } = K;
29850
29955
  const gutter = (...a) => K.gutter(...a);
29851
29956
  const gutterConfig = (...a) => K.gutterConfig(...a);
@@ -29853,14 +29958,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29853
29958
  const sh = (...a) => K.sh(...a);
29854
29959
  const slabs = (...a) => K.slabs(...a);
29855
29960
  function roofs() {
29856
- const R = shared.ctx.r, F = R.facade, C = shared.ctx.colors, nA = R.floors.length, type = F.roof;
29961
+ const R = shared2.ctx.r, F = R.facade, C = shared2.ctx.colors, nA = R.floors.length, type = F.roof;
29857
29962
  cursor.group = "roof";
29858
- shared.ctx.roofRects = [];
29859
- shared.ctx.gutter = gutterConfig();
29860
- shared.ctx.gutter.ncond = 0;
29861
- shared.ctx.gutter.nbuz = 0;
29862
- shared.ctx.gutter.bz = /* @__PURE__ */ new Set();
29863
- shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
29963
+ shared2.ctx.roofRects = [];
29964
+ shared2.ctx.gutter = gutterConfig();
29965
+ shared2.ctx.gutter.ncond = 0;
29966
+ shared2.ctx.gutter.nbuz = 0;
29967
+ shared2.ctx.gutter.bz = /* @__PURE__ */ new Set();
29968
+ shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] };
29864
29969
  const roofColor = C.roof != null ? C.roof : 11031610, gable = (R.seed | 0) % 2 === 0;
29865
29970
  for (let f = 0; f < nA; f++) {
29866
29971
  const rs = R.rooms.filter((c) => c.floor === f && c.type !== "void" && !c.outbuilding && !OPEN_AREA(c)).flatMap(rectsOf2), up = R.rooms.filter((c) => c.floor === f + 1 && c.type !== "void").flatMap(rectsOf2);
@@ -29883,7 +29988,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29883
29988
  return Y0(f) + Math.max(...cs.map((c) => c.ceiling)) + 0.2;
29884
29989
  };
29885
29990
  if (type === "slab") {
29886
- for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) shared.ctx.roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
29991
+ for (let j = 0; j < nz; j++) for (let i = 0; i < nx; i++) if (O(j, i)) shared2.ctx.roofRects.push({ f, r: [xs[i], zs[j], xs[i + 1], zs[j + 1]], slab: true, yb: pe(xs[i], zs[j], xs[i + 1], zs[j + 1]) + 0.03 });
29887
29992
  slabs(f, xs, zs, O, U, nx, nz, full, pe, C);
29888
29993
  cursor.pc = null;
29889
29994
  continue;
@@ -29906,36 +30011,36 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29906
30011
  if (U(q.j0 - 1, i)) touchesU[1] = 1;
29907
30012
  if (U(q.j1 + 1, i)) touchesU[3] = 1;
29908
30013
  }
29909
- shared.ctx.roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
30014
+ shared2.ctx.roofRects.push({ f, r: [x0, z0, x1, z1], touchesU });
29910
30015
  const ybq = pe(x0, z0, x1, z1);
29911
30016
  roofRect(type, x0, z0, x1, z1, ybq, roofColor, gable && single, F, touchesU);
29912
30017
  cursor.pc = null;
29913
- if (shared.ctx.gutter.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
30018
+ if (shared2.ctx.gutter.on) gutter(type, f, x0, z0, x1, z1, ybq, touchesU);
29914
30019
  }
29915
30020
  }
29916
- for (const e of shared.ctx.outbuildingList || []) {
30021
+ for (const e of shared2.ctx.outbuildingList || []) {
29917
30022
  const [x0, z0, x1, z1] = e.aabb, yb = Y0(0) + (e.ceiling || 2.6) + 0.2;
29918
- shared.ctx.roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
30023
+ shared2.ctx.roofRects.push({ f: 0, r: [x0, z0, x1, z1], outbuilding: e.id });
29919
30024
  if (type === "slab") {
29920
30025
  const c = C.facade != null ? C.facade : 14209216;
29921
30026
  bx("plaster", x0 - 0.08, yb, z0 - 0.08, x1 + 0.08, yb + 0.03, z1 + 0.08, sh(C.ceiling != null ? C.ceiling : 12104876, 0.85));
29922
30027
  for (const [a, b, c2, d] of [[x0 - 0.08, z0 - 0.08, x1 + 0.08, z0 - 0.04], [x0 - 0.08, z1 + 0.04, x1 + 0.08, z1 + 0.08], [x0 - 0.08, z0 - 0.08, x0 - 0.04, z1 + 0.08], [x1 + 0.04, z0 - 0.08, x1 + 0.08, z1 + 0.08]]) bx("plaster", a, yb, b, c2, yb + 0.4, d, c);
29923
30028
  continue;
29924
30029
  }
29925
- shared.ctx.noPiece = true;
30030
+ shared2.ctx.noPiece = true;
29926
30031
  roofRect(type, x0, z0, x1, z1, yb, roofColor, true, F, [0, 0, 0, 0]);
29927
30032
  cursor.pc = null;
29928
- shared.ctx.noPiece = false;
29929
- if (shared.ctx.gutter.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
30033
+ shared2.ctx.noPiece = false;
30034
+ if (shared2.ctx.gutter.on) gutter(type, 0, x0, z0, x1, z1, yb, [0, 0, 0, 0]);
29930
30035
  }
29931
30036
  }
29932
30037
  Object.assign(K, { roofs });
29933
30038
  }
29934
- function installRoofGutters(K, shared) {
30039
+ function installRoofGutters(K, shared2) {
29935
30040
  const { boxC, bx, cursor, roomAt } = K;
29936
30041
  const sh = (...a) => K.sh(...a);
29937
30042
  function gutterConfig() {
29938
- const R = shared.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
30043
+ const R = shared2.ctx.r, structure = R.style, high = structure === "high" || structure === "luxury", p = high || structure === "mid" ? 0.6 : 0.3;
29939
30044
  let h = 2166136261;
29940
30045
  for (const ch of String(R.seed) + "|" + K.seedKey(R.template) + "|calha") h = Math.imul(h ^ ch.charCodeAt(0), 16777619);
29941
30046
  const rnd2 = () => {
@@ -29947,10 +30052,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29947
30052
  const draw2 = rnd2() < p, light = rnd2() < 0.6;
29948
30053
  void draw2;
29949
30054
  const on = true;
29950
- return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared.ctx.colors.meta && shared.ctx.colors.meta.state) === "abandoned" || R.state === "abandoned", fallback: false };
30055
+ return { on, rnd: rnd2, color: high ? 3816770 : light ? 15527921 : 10857392, bad: (shared2.ctx.colors.meta && shared2.ctx.colors.meta.state) === "abandoned" || R.state === "abandoned", fallback: false };
29951
30056
  }
29952
30057
  function gutter(type, f, X0, Z0, X1, Z1, yb, touchesU) {
29953
- const G = shared.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
30058
+ const G = shared2.ctx.gutter, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), c = G.color, y = yb - 0.05;
29954
30059
  const run = (ax, a, b, p, outside, breaks) => {
29955
30060
  const seg2 = (u0, u1, tilt) => {
29956
30061
  const L = u1 - u0, m = (u0 + u1) / 2, dy = tilt ? -Math.abs(tilt) * L * 0.5 : 0;
@@ -29974,7 +30079,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
29974
30079
  sides.forEach((l, i) => {
29975
30080
  if (l[0]) run(l[1], l[2], l[3], l[4], l[5], G.bad && !G.fallback && i === larger && (G.fallback = true));
29976
30081
  });
29977
- const INF = shared.ctx.gutterInfo || (shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
30082
+ const INF = shared2.ctx.gutterInfo || (shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] });
29978
30083
  sides.forEach((l, i) => {
29979
30084
  if (l[0]) INF.gutters.push({ f, side: ["z0", "z1", "x0", "x1"][i], axis: l[1], a: l[2], b: l[3], p: l[4], y });
29980
30085
  });
@@ -30036,7 +30141,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30036
30141
  }
30037
30142
  Object.assign(K, { gutterConfig, gutter, drain });
30038
30143
  }
30039
- function installRoofSlabs(K, shared) {
30144
+ function installRoofSlabs(K, shared2) {
30040
30145
  const { boxC, bx, cursor, drain, roomAt, structurePiece } = K;
30041
30146
  const sh = (...a) => K.sh(...a);
30042
30147
  function slabs(f, xs, zs, O, U, nx, nz, full, pe, C) {
@@ -30066,15 +30171,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30066
30171
  side(free(j, i + 1), x1 + o - t, z0 - ez0, x1 + o, z1 + ez1);
30067
30172
  side(free(j - 1, i), x0 - ex0, z0 - o, x1 + ex1, z0 - o + t);
30068
30173
  side(free(j + 1, i), x0 - ex0, z1 + o - t, x1 + ex1, z1 + o);
30069
- if (shared.ctx.gutter && shared.ctx.gutter.on) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
30174
+ if (shared2.ctx.gutter && shared2.ctx.gutter.on) for (const [ok, dx, dz] of [[free(j - 1, i), 0, -1], [free(j + 1, i), 0, 1], [free(j, i - 1), -1, 0], [free(j, i + 1), 1, 0]]) {
30070
30175
  const kd = f + ":" + dx + ":" + dz;
30071
- if (!ok || shared.ctx.gutter.bz.has(kd)) continue;
30072
- shared.ctx.gutter.bz.add(kd);
30073
- shared.ctx.gutter.nbuz++;
30074
- const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = shared.ctx.gutter.color;
30176
+ if (!ok || shared2.ctx.gutter.bz.has(kd)) continue;
30177
+ shared2.ctx.gutter.bz.add(kd);
30178
+ shared2.ctx.gutter.nbuz++;
30179
+ const mx = (x0 + x1) / 2, mz = (z0 + z1) / 2, ex = dx ? dx < 0 ? x0 - o : x1 + o : mx, ez = dz ? dz < 0 ? z0 - o : z1 + o : mz, cc = shared2.ctx.gutter.color;
30075
30180
  boxC("plain", ex + dx * 0.15, yb + 0.1, ez + dz * 0.15, dx ? 0.42 : 0.14, 0.1, dz ? 0.42 : 0.14, cc);
30076
30181
  boxC("plain", ex + dx * 0.36, yb + 0.1, ez + dz * 0.36, dx ? 0.04 : 0.18, 0.14, dz ? 0.04 : 0.18, sh(cc, 0.8));
30077
- if (shared.ctx.gutter.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
30182
+ if (shared2.ctx.gutter.bad) boxC("plain", ex + dx * 0.05, yb + 0.5 * 0, ez + dz * 0.05, dx ? 0.06 : 0.3, 0.02, dz ? 0.06 : 0.3, 4868674);
30078
30183
  {
30079
30184
  const tx = ex + dx * 0.38, tz = ez + dz * 0.38;
30080
30185
  let lv = true;
@@ -30087,8 +30192,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30087
30192
  boxC("plain", tx, 0.9, tz, 0.12, 0.04, 0.12, sh(cc, 0.8));
30088
30193
  const rx = tx + dx * 0.24, rz = tz + dz * 0.24;
30089
30194
  drain(rx, rz, tx, tz, cc);
30090
- (shared.ctx.gutterInfo || (shared.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] })).downpipes.push({ f, x: tx, z: tz, y0: 0.045, y1: yb + 0.04, drain: [rx, rz], hornBox: true });
30091
- shared.ctx.gutterInfo.drains.push({ x: rx, z: rz });
30195
+ (shared2.ctx.gutterInfo || (shared2.ctx.gutterInfo = { gutters: [], downpipes: [], drains: [] })).downpipes.push({ f, x: tx, z: tz, y0: 0.045, y1: yb + 0.04, drain: [rx, rz], hornBox: true });
30196
+ shared2.ctx.gutterInfo.drains.push({ x: rx, z: rz });
30092
30197
  }
30093
30198
  }
30094
30199
  }
@@ -30096,10 +30201,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30096
30201
  }
30097
30202
  Object.assign(K, { slabs });
30098
30203
  }
30099
- function installRoofTiles(K, shared) {
30204
+ function installRoofTiles(K, shared2) {
30100
30205
  const { UV_SCALE, _Y, _h2, _q, accFor, cursor, put, rgbOf, structurePiece } = K;
30101
30206
  const sh = (...a) => K.sh(...a);
30102
- const R_STYLE = () => shared.ctx.r && shared.ctx.r.style || "budget";
30207
+ const R_STYLE = () => shared2.ctx.r && shared2.ctx.r.style || "budget";
30103
30208
  function tileRelief(mat, pts, color2, type) {
30104
30209
  const n = pts.length;
30105
30210
  if (n < 3) return;
@@ -30140,7 +30245,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30140
30245
  S.push(rx * ex + ry * ey + rz * ez);
30141
30246
  T2.push(rx * dx + ry * dy + rz * dz);
30142
30247
  }
30143
- const colonial = type !== "fiber_cement", P = colonial ? 0.2 : 0.177, A = colonial ? 0.032 : 0.0255, seg2 = shared.quality === "game" ? colonial ? 4 : 4 : colonial ? 8 : 6, h = P / seg2;
30248
+ const colonial = type !== "fiber_cement", P = colonial ? 0.2 : 0.177, A = colonial ? 0.032 : 0.0255, seg2 = shared2.quality === "game" ? colonial ? 4 : 4 : colonial ? 8 : 6, h = P / seg2;
30144
30249
  const smin = Math.min(...S), smax = Math.max(...S);
30145
30250
  if (smax - smin < 1e-4) return;
30146
30251
  const xs = new Set(S.map((v) => +v.toFixed(5)));
@@ -30212,9 +30317,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30212
30317
  }
30213
30318
  }
30214
30319
  function pieceOfPane(x, z) {
30215
- if (shared.ctx.noPiece || !shared.ctx.panes.length) return null;
30320
+ if (shared2.ctx.noPiece || !shared2.ctx.panes.length) return null;
30216
30321
  let m = null, md = 1e9;
30217
- for (const a of shared.ctx.panes) {
30322
+ for (const a of shared2.ctx.panes) {
30218
30323
  const b = a.aabb;
30219
30324
  if (!b) continue;
30220
30325
  const dx = x < b[0] ? b[0] - x : x > b[2] ? x - b[2] : 0, dz = z < b[1] ? b[1] - z : z > b[3] ? z - b[3] : 0, d = Math.hypot(dx, dz) * 1e3 + (b[2] - b[0]) * (b[3] - b[1]) * 1e-3;
@@ -30227,11 +30332,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30227
30332
  }
30228
30333
  Object.assign(K, { R_STYLE, tileRelief, ridge, pieceOfPane });
30229
30334
  }
30230
- function installRoofRect(K, shared) {
30335
+ function installRoofRect(K, shared2) {
30231
30336
  const { R_STYLE, bx, cursor, pieceOfPane, polyFace, ridge, tileRelief } = K;
30232
30337
  const sh = (...a) => K.sh(...a);
30233
30338
  function roofRect(type, X0, Z0, X1, Z1, yb, roofColor, gable, F, touchesU = [0, 0, 0, 0]) {
30234
- const C = shared.ctx.colors, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), dx = x1 - x0, dz = z1 - z0, xm = (x0 + x1) / 2, zm = (z0 + z1) / 2;
30339
+ const C = shared2.ctx.colors, o = type === "fiber_cement" ? 0.3 : 0.45, x0 = X0 - (touchesU[0] ? 0 : o), x1 = X1 + (touchesU[2] ? 0 : o), z0 = Z0 - (touchesU[1] ? 0 : o), z1 = Z1 + (touchesU[3] ? 0 : o), dx = x1 - x0, dz = z1 - z0, xm = (x0 + x1) / 2, zm = (z0 + z1) / 2;
30235
30340
  const mat = type === "fiber_cement" ? "fiber_cement" : "tile", tp = type === "fiber_cement" ? 0.2 : 0.5, alongX = dx >= dz, up = [0, 1, 0];
30236
30341
  const Q = (pts) => {
30237
30342
  let cx = 0, cz = 0;
@@ -30269,7 +30374,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30269
30374
  }
30270
30375
  const rm = alongX ? dz / 2 : dx / 2;
30271
30376
  {
30272
- const rr = shared.ctx.roofRects[shared.ctx.roofRects.length - 1];
30377
+ const rr = shared2.ctx.roofRects[shared2.ctx.roofRects.length - 1];
30273
30378
  if (rr && !rr.yb) Object.assign(rr, { yb, tp, gable: !!gable, alongX, exterior: [x0, z0, x1, z1], rm });
30274
30379
  }
30275
30380
  if (gable) {
@@ -30308,12 +30413,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30308
30413
  }
30309
30414
  Object.assign(K, { roofRect });
30310
30415
  }
30311
- function installMirrors(K, shared) {
30416
+ function installMirrors(K, shared2) {
30312
30417
  const { DOC, THREE, Reflector, MIRRORS, Y0, _Y, roomAt } = K;
30313
- shared.mirrorEnv = null;
30314
- shared.mirrorMat = null;
30418
+ shared2.mirrorEnv = null;
30419
+ shared2.mirrorMat = null;
30315
30420
  function mirrorEnv() {
30316
- if (shared.mirrorEnv) return shared.mirrorEnv;
30421
+ if (shared2.mirrorEnv) return shared2.mirrorEnv;
30317
30422
  const mk = (f) => {
30318
30423
  const c = DOC.createElement("canvas");
30319
30424
  c.width = c.height = 64;
@@ -30349,18 +30454,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30349
30454
  const t = new THREE.CubeTexture(faces);
30350
30455
  t.colorSpace = THREE.SRGBColorSpace;
30351
30456
  t.needsUpdate = true;
30352
- shared.mirrorEnv = t;
30353
- shared.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
30457
+ shared2.mirrorEnv = t;
30458
+ shared2.mirrorMat = new THREE.MeshStandardMaterial({ color: 16054008, metalness: 1, roughness: 0.06, envMap: t, envMapIntensity: 1 });
30354
30459
  return t;
30355
30460
  }
30356
30461
  const newMirrorState = () => ({ list: [], active: null, tmp: new THREE.Vector3(), house: null });
30357
- shared.mirrors = newMirrorState();
30462
+ shared2.mirrors = newMirrorState();
30358
30463
  function assembleMirrors(groups) {
30359
- shared.mirrors.list.length = 0;
30360
- shared.mirrors.active = null;
30464
+ shared2.mirrors.list.length = 0;
30465
+ shared2.mirrors.active = null;
30361
30466
  if (!MIRRORS.length) return;
30362
30467
  mirrorEnv();
30363
- if (shared.quality === "game" || !Reflector) {
30468
+ if (shared2.quality === "game" || !Reflector) {
30364
30469
  const by = /* @__PURE__ */ new Map(), m4 = new THREE.Matrix4(), qy = new THREE.Quaternion(), um = new THREE.Vector3(1, 1, 1), ps = new THREE.Vector3(), nm = new THREE.Matrix3(), v = new THREE.Vector3();
30365
30470
  for (const E of MIRRORS) {
30366
30471
  const geo = new THREE.PlaneGeometry(E.w, E.h);
@@ -30387,7 +30492,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30387
30492
  g.setAttribute("uv", new THREE.Float32BufferAttribute(B.U, 2));
30388
30493
  g.setIndex(B.I);
30389
30494
  g.computeBoundingSphere();
30390
- const m = new THREE.Mesh(g, shared.mirrorMat);
30495
+ const m = new THREE.Mesh(g, shared2.mirrorMat);
30391
30496
  m.name = "mirror/environment";
30392
30497
  m.userData.part = "mirror";
30393
30498
  (groups[parent] || (groups[parent] = new THREE.Group())).add(m);
@@ -30402,7 +30507,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30402
30507
  g.userData.part = "mirror";
30403
30508
  g.userData.room = E.room;
30404
30509
  const geo = new THREE.PlaneGeometry(E.w, E.h);
30405
- const fake = new THREE.Mesh(geo, shared.mirrorMat);
30510
+ const fake = new THREE.Mesh(geo, shared2.mirrorMat);
30406
30511
  fake.userData.part = "mirror";
30407
30512
  fake.name = "mirror/environment";
30408
30513
  g.add(fake);
@@ -30418,27 +30523,27 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30418
30523
  console.warn("mirror real", e);
30419
30524
  }
30420
30525
  (groups[E.parent] || (groups[E.parent] = new THREE.Group())).add(g);
30421
- shared.mirrors.list.push({ E, g, fake, real });
30526
+ shared2.mirrors.list.push({ E, g, fake, real });
30422
30527
  }
30423
30528
  }
30424
30529
  function floorAtY(y) {
30425
- const A = shared.ctx.r.floors;
30530
+ const A = shared2.ctx.r.floors;
30426
30531
  let f = 0;
30427
30532
  for (let i = 0; i < A.length; i++) if (y >= A[i].y0 - 0.2) f = i;
30428
30533
  return f;
30429
30534
  }
30430
30535
  function chooseMirror(camera2) {
30431
- if (!shared.mirrors.list.length) return;
30536
+ if (!shared2.mirrors.list.length) return;
30432
30537
  let target = null;
30433
- if (shared.mirrors.house && shared.ctx.r) {
30434
- shared.mirrors.tmp.copy(camera2.position);
30435
- shared.mirrors.house.worldToLocal(shared.mirrors.tmp);
30436
- const f = floorAtY(shared.mirrors.tmp.y), c = roomAt(f, shared.mirrors.tmp.x, shared.mirrors.tmp.z);
30437
- if (c && shared.mirrors.tmp.y > Y0(f) && shared.mirrors.tmp.y < Y0(f) + 4) {
30538
+ if (shared2.mirrors.house && shared2.ctx.r) {
30539
+ shared2.mirrors.tmp.copy(camera2.position);
30540
+ shared2.mirrors.house.worldToLocal(shared2.mirrors.tmp);
30541
+ const f = floorAtY(shared2.mirrors.tmp.y), c = roomAt(f, shared2.mirrors.tmp.x, shared2.mirrors.tmp.z);
30542
+ if (c && shared2.mirrors.tmp.y > Y0(f) && shared2.mirrors.tmp.y < Y0(f) + 4) {
30438
30543
  let best = 1e9;
30439
- for (const m of shared.mirrors.list) {
30544
+ for (const m of shared2.mirrors.list) {
30440
30545
  if (m.E.room !== c.id || m.E.floor !== f || !m.g.parent || !m.g.parent.visible) continue;
30441
- const d = Math.hypot(m.E.x - shared.mirrors.tmp.x, m.E.z - shared.mirrors.tmp.z);
30546
+ const d = Math.hypot(m.E.x - shared2.mirrors.tmp.x, m.E.z - shared2.mirrors.tmp.z);
30442
30547
  if (d < best) {
30443
30548
  best = d;
30444
30549
  target = m;
@@ -30446,9 +30551,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30446
30551
  }
30447
30552
  }
30448
30553
  }
30449
- if (target === shared.mirrors.active) return;
30450
- shared.mirrors.active = target;
30451
- for (const m of shared.mirrors.list) {
30554
+ if (target === shared2.mirrors.active) return;
30555
+ shared2.mirrors.active = target;
30556
+ for (const m of shared2.mirrors.list) {
30452
30557
  const on = m === target && !!m.real;
30453
30558
  if (m.real) m.real.visible = on;
30454
30559
  m.fake.visible = !on;
@@ -30456,7 +30561,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30456
30561
  }
30457
30562
  Object.assign(K, { mirrorEnv, newMirrorState, assembleMirrors, floorAtY, chooseMirror });
30458
30563
  }
30459
- function installCars(K, shared) {
30564
+ function installCars(K, shared2) {
30460
30565
  const { THREE, FLEET, _Y } = K;
30461
30566
  const CARS = [];
30462
30567
  const CAR_BY_STYLE = Object.assign({
@@ -30482,12 +30587,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30482
30587
  return b;
30483
30588
  }
30484
30589
  function carModel(k, seed) {
30485
- const kc = k + "|" + shared.quality + "|" + (seed || 0);
30590
+ const kc = k + "|" + shared2.quality + "|" + (seed || 0);
30486
30591
  if (CAR_CACHE.has(kc)) return CAR_CACHE.get(kc);
30487
30592
  if (!FLEET) return null;
30488
30593
  let res = null;
30489
30594
  try {
30490
- const v0 = FLEET.build(k, { quality: shared.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
30595
+ const v0 = FLEET.build(k, { quality: shared2.quality, seed: seed || 0 }), c = { root: v0.group, g: v0.group };
30491
30596
  c.root.updateMatrixWorld(true);
30492
30597
  const inv = new THREE.Matrix4();
30493
30598
  const byMaterial = /* @__PURE__ */ new Map(), tmp = new THREE.Matrix4(), v = new THREE.Vector3(), nm = new THREE.Matrix3(), bb = new THREE.Box3();
@@ -30607,7 +30712,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30607
30712
  return g;
30608
30713
  }
30609
30714
  function assembleCars(groups) {
30610
- if (shared.quality === "game") return assembleMergedCars(groups);
30715
+ if (shared2.quality === "game") return assembleMergedCars(groups);
30611
30716
  for (const C of CARS) {
30612
30717
  const g = carGroup(C.k, C.w, C.d, C.seed);
30613
30718
  if (!g) continue;
@@ -30660,10 +30765,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30660
30765
  }
30661
30766
  Object.assign(K, { CARS, CAR_BY_STYLE, CAR_CACHE, materialSignature, BUCKETS, bucketMaterial, carModel, carGroup, assembleCars, assembleMergedCars });
30662
30767
  }
30663
- function installHouseBuilding(K, shared) {
30768
+ function installHouseBuilding(K, shared2) {
30664
30769
  const { bx, cursor } = K;
30665
30770
  function building() {
30666
- const R = shared.ctx.r, P = R.building, C = shared.ctx.colors, N = shared.ctx.pa, uf = shared.ctx.pf, pe = P.ceilingHeight, fa = C.facade != null ? C.facade : 14209216;
30771
+ const R = shared2.ctx.r, P = R.building, C = shared2.ctx.colors, N = shared2.ctx.pa, uf = shared2.ctx.pf, pe = P.ceilingHeight, fa = C.facade != null ? C.facade : 14209216;
30667
30772
  cursor.group = "building";
30668
30773
  const uw = P.unit.w, ud = P.unit.d, un = P.units;
30669
30774
  const unitBox = (u) => {
@@ -30671,7 +30776,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30671
30776
  return [x[0], z[0], x[1], z[1]];
30672
30777
  };
30673
30778
  const un0 = unitBox(un[0]), color2 = P.corridor, hall = P.hall, el = P.elevator.rect, es = P.stairs.rect;
30674
- const sel = un[shared.ctx.pu] || un[0], selR = unitBox(sel);
30779
+ const sel = un[shared2.ctx.pu] || un[0], selR = unitBox(sel);
30675
30780
  const shell = (rc, y0, y1, thickness = 0.15) => {
30676
30781
  const [a, b, c, d] = rc;
30677
30782
  bx("building", a, y0, b, c, y1, b + thickness, fa);
@@ -30710,11 +30815,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30710
30815
  }
30711
30816
  const ytop = N * pe - 0.2;
30712
30817
  bx("plaster", Math.min(hall[0] - 3, color2[0]), ytop, Math.min(un[1] ? unitBox(un[1])[1] : 0, el[1]), Math.max(color2[2], un0[2]), ytop + 0.2, Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0), 11841704);
30713
- shared.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
30818
+ shared2.ctx.limits = { x0: Math.min(hall[0] - 3, color2[0]), z0: Math.min(el[1], un[1] ? unitBox(un[1])[1] : 0), x1: Math.max(color2[2], un0[2]), z1: Math.max(un0[3], un[1] ? unitBox(un[1])[3] : 0) };
30714
30819
  }
30715
30820
  Object.assign(K, { building });
30716
30821
  }
30717
- function installUtilitiesWater(K, shared) {
30822
+ function installUtilitiesWater(K, shared2) {
30718
30823
  const { THREE, _Y, _q, cursor, cylBase, part, pieceRecord, put } = K;
30719
30824
  function createWater(r, state) {
30720
30825
  const H = r.utilities.plumbing, cap = H ? +H.capacityL || 0 : 0, ls = { dry: [], full: [] }, points = {}, itemPoint = {};
@@ -30806,14 +30911,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30806
30911
  }
30807
30912
  const _v3 = new THREE.Vector3();
30808
30913
  function waterPipes() {
30809
- const H = shared.ctx.r.utilities.plumbing;
30914
+ const H = shared2.ctx.r.utilities.plumbing;
30810
30915
  if (!H || !H.visibleRuns) return;
30811
- const nA = shared.ctx.r.floors.length;
30916
+ const nA = shared2.ctx.r.floors.length;
30812
30917
  const groupOf = (c) => c && c.floor >= 0 ? "f" + Math.min(c.floor, nA - 1) : "lot", xyz = (p) => [p[0], p[2], p[1]];
30813
30918
  for (const tr of H.visibleRuns) {
30814
30919
  const pts = tr.points.map(xyz), d = tr.diameter || 0.025;
30815
30920
  if (tr.exposed === "wall") {
30816
- const pt = H.points.find((p) => p.run === tr.id), com = shared.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
30921
+ const pt = H.points.find((p) => p.run === tr.id), com = shared2.ctx.roomById[tr.to], g2 = groupOf(com || pt && { floor: pt.floor });
30817
30922
  part("wall_pipe", [0, 0, 0], () => {
30818
30923
  for (let i = 0; i + 1 < pts.length; i++) pipe(pts[i], pts[i + 1], d, PIPE_COLOR);
30819
30924
  for (const p of pts) cylBase("plain", p[0], p[1] - d, p[2], d * 0.7, d * 2, PIPE_COLOR);
@@ -30821,7 +30926,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30821
30926
  continue;
30822
30927
  }
30823
30928
  let g;
30824
- if (tr.exposed === "tank_outlet") g = shared.ctx.waterTankPos && shared.ctx.waterTankPos.group || "f0";
30929
+ if (tr.exposed === "tank_outlet") g = shared2.ctx.waterTankPos && shared2.ctx.waterTankPos.group || "f0";
30825
30930
  else {
30826
30931
  const pt = H.points.find((p) => p.id === tr.to);
30827
30932
  g = groupOf(pt);
@@ -30837,15 +30942,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30837
30942
  }
30838
30943
  Object.assign(K, { createWater, PIPE_COLOR, pipe, _v3, waterPipes });
30839
30944
  }
30840
- function installUtilitiesElectrical(K, shared) {
30945
+ function installUtilitiesElectrical(K, shared2) {
30841
30946
  const { _Y, _q, _v3, bx, cursor, cylBase, pieceRecord, put } = K;
30842
30947
  const sh = (...a) => K.sh(...a);
30843
30948
  function electricalStructure() {
30844
- const E = shared.ctx.r.utilities.electrical;
30845
- shared.ctx.electricalInfo = null;
30949
+ const E = shared2.ctx.r.utilities.electrical;
30950
+ shared2.ctx.electricalInfo = null;
30846
30951
  if (!E) return;
30847
- const R = shared.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
30848
- const en22 = E.serviceEntrance, KV = shared.ctx.iv ? shared.ctx.iv.plane : null;
30952
+ const R = shared2.ctx.r, nA = R.floors.length, lotGroup = R.lot ? "lot" : "f0", concreteColor = 11973547, iron = 4869200, wireRun = 1842206, info = { pole: null, meter: null, panel: null, conduits: [], outlets: [], switches: [], circuits: E.circuits || [], exposed: !!E.exposed };
30953
+ const en22 = E.serviceEntrance, KV = shared2.ctx.iv ? shared2.ctx.iv.plane : null;
30849
30954
  const wireL = (a, b, r_ = 8e-3) => {
30850
30955
  const L = Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
30851
30956
  if (L < 1e-3) return;
@@ -30923,7 +31028,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30923
31028
  info.conduits.push(t.id);
30924
31029
  continue;
30925
31030
  }
30926
- const c = circ[t.circuit], com = c && shared.ctx.roomById[c.room];
31031
+ const c = circ[t.circuit], com = c && shared2.ctx.roomById[c.room];
30927
31032
  cursor.group = "f" + Math.max(0, Math.min(nA - 1, com ? com.floor : 0));
30928
31033
  const d = t.diameter || 0.02, P = t.points.map((p) => [p[0], p[2], p[1]]), seg2 = [];
30929
31034
  for (let i = 0; i + 1 < P.length; i++) {
@@ -30941,7 +31046,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30941
31046
  }
30942
31047
  for (const t of E.outlets || []) info.outlets.push({ id: t.id, pos: [t.u, t.y, t.v], normal: [t.frontU || 0, 0, t.frontV || 0], room: t.room, floor: t.floor, type: t.type, voltage: t.voltage });
30943
31048
  for (const t of E.switches || []) info.switches.push({ id: t.id, pos: [t.u, t.y, t.v], normal: [t.frontU || 0, 0, t.frontV || 0], room: t.room, floor: t.floor, controls: t.controls });
30944
- shared.ctx.electricalInfo = info;
31049
+ shared2.ctx.electricalInfo = info;
30945
31050
  }
30946
31051
  function pipe2(a, b, diameter, color2) {
30947
31052
  const dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2], L = Math.hypot(dx, dy, dz);
@@ -30951,11 +31056,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30951
31056
  }
30952
31057
  Object.assign(K, { electricalStructure, pipe2 });
30953
31058
  }
30954
- function installHouseBaseboard(K, shared) {
31059
+ function installHouseBaseboard(K, shared2) {
30955
31060
  const { Y0, bx, cursor, sideOf } = K;
30956
31061
  const sh = (...a) => K.sh(...a);
30957
31062
  function baseboardAndSidewalk() {
30958
- const R = shared.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared.ctx.colors.facade != null ? shared.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
31063
+ const R = shared2.ctx.r, W = 0.6, t = 0.012, ht = 0.35, color2 = sh(shared2.ctx.colors.facade != null ? shared2.ctx.colors.facade : 14209216, 0.62), y0 = Y0(0), cal = 13947078;
30959
31064
  const ws = R.walls.filter((w) => w.floor === 0 && w.type === "wall").map((w) => {
30960
31065
  const au = w.axis === "u";
30961
31066
  return { w, au, L: au ? w.v0 : w.u0, a: Math.min(au ? w.u0 : w.v0, au ? w.u1 : w.v1), b: Math.max(au ? w.u0 : w.v0, au ? w.u1 : w.v1), th: w.thickness || 0.15 };
@@ -30987,11 +31092,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
30987
31092
  }
30988
31093
  Object.assign(K, { baseboardAndSidewalk });
30989
31094
  }
30990
- function installUtilitiesSolar(K, shared) {
31095
+ function installUtilitiesSolar(K, shared2) {
30991
31096
  const { Y0, boxC, bx, cursor, cylBase } = K;
30992
31097
  function roofHeightAt(u, v, f) {
30993
31098
  let y = null;
30994
- for (const rr of shared.ctx.roofRects || []) {
31099
+ for (const rr of shared2.ctx.roofRects || []) {
30995
31100
  if (rr.yb == null || f != null && rr.f !== f) continue;
30996
31101
  if (rr.slab) {
30997
31102
  const [a, b, c, d] = rr.r;
@@ -31006,8 +31111,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31006
31111
  return y;
31007
31112
  }
31008
31113
  function solar() {
31009
- const R = shared.ctx.r, S = R.utilities.solar;
31010
- shared.ctx.solarInfo = null;
31114
+ const R = shared2.ctx.r, S = R.utilities.solar;
31115
+ shared2.ctx.solarInfo = null;
31011
31116
  if (!S || !S.panels || !S.panels.length) return;
31012
31117
  cursor.group = "roof";
31013
31118
  const silver = 13225426, blue = 1780302, line = 9279142, sv = S.north === "front" ? -1 : 1, info = { type: S.type, panels: [], inverter: null }, onRack = S.type === "slab_rack";
@@ -31049,15 +31154,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31049
31154
  bx("plain", iv.u - W * 0.6, y0 + 0.05, iv.v + fa0, iv.u + W * 0.6, y0 + 0.17, iv.v + fa1, 2106924);
31050
31155
  bx("emissive", iv.u - 0.03, y0 - 0.12, iv.v + fa0, iv.u + 0.03, y0 - 0.09, iv.v + fa1, 6479994);
31051
31156
  }
31052
- const top = Math.max(...(shared.ctx.roofRects || []).filter((t2) => t2.yb != null).map((t2) => t2.yb), Y0(fa) + 2.8);
31157
+ const top = Math.max(...(shared2.ctx.roofRects || []).filter((t2) => t2.yb != null).map((t2) => t2.yb), Y0(fa) + 2.8);
31053
31158
  cylBase("plain", iv.u, y0 + h / 2, iv.v, 0.016, Math.max(0.2, top - 0.2 - (y0 + h / 2)), 15262936);
31054
31159
  info.inverter = { id: iv.id, pos: [iv.u, y0, iv.v], side: iv.side, link: iv.link };
31055
31160
  }
31056
- shared.ctx.solarInfo = info;
31161
+ shared2.ctx.solarInfo = info;
31057
31162
  }
31058
31163
  Object.assign(K, { roofHeightAt, solar });
31059
31164
  }
31060
- function installHouseOutbuildings(K, shared) {
31165
+ function installHouseOutbuildings(K, shared2) {
31061
31166
  const { t, bx, cursor, floorColor } = K;
31062
31167
  const sh = (...a) => K.sh(...a);
31063
31168
  const OUTBUILDING_USE = { guest_room: ["bedroom", "bedroom", t("outbuilding.guest_room")], office: ["office", "office", t("outbuilding.office")], storage: ["stockroom", "stockroom", t("outbuilding.storage")], gourmet: ["living", "gourmet", t("outbuilding.gourmet")] };
@@ -31089,17 +31194,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31089
31194
  return Object.assign({}, r, { rooms, walls, doors, windows, items });
31090
31195
  }
31091
31196
  function outbuildings() {
31092
- const E = (shared.ctx.r.outbuildings || []).filter((e) => shared.ctx.roomById[e.id] && shared.ctx.roomById[e.id].outbuilding);
31093
- shared.ctx.outbuildingList = E;
31197
+ const E = (shared2.ctx.r.outbuildings || []).filter((e) => shared2.ctx.roomById[e.id] && shared2.ctx.roomById[e.id].outbuilding);
31198
+ shared2.ctx.outbuildingList = E;
31094
31199
  if (!E.length) return;
31095
31200
  cursor.group = "f0";
31096
31201
  for (const e of E) {
31097
- const c = shared.ctx.roomById[e.id], col = floorColor(c);
31202
+ const c = shared2.ctx.roomById[e.id], col = floorColor(c);
31098
31203
  for (const [a, b, c2, d] of e.interior) bx("plaster", a - 0.075, 0, b - 0.075, c2 + 0.075, 0.04, d + 0.075, col);
31099
31204
  for (const p of e.doors || []) {
31100
31205
  const alongU = p.axis === "u", th = e.thickness || 0.15;
31101
- if (alongU) bx("plaster", p.at - p.width / 2, 0, p.pos - th / 2 - 0.12, p.at + p.width / 2, 0.03, p.pos + th / 2 + 0.12, sh(shared.ctx.colors.facade || 14209216, 0.8));
31102
- else bx("plaster", p.pos - th / 2 - 0.12, 0, p.at - p.width / 2, p.pos + th / 2 + 0.12, 0.03, p.at + p.width / 2, sh(shared.ctx.colors.facade || 14209216, 0.8));
31206
+ if (alongU) bx("plaster", p.at - p.width / 2, 0, p.pos - th / 2 - 0.12, p.at + p.width / 2, 0.03, p.pos + th / 2 + 0.12, sh(shared2.ctx.colors.facade || 14209216, 0.8));
31207
+ else bx("plaster", p.pos - th / 2 - 0.12, 0, p.at - p.width / 2, p.pos + th / 2 + 0.12, 0.03, p.at + p.width / 2, sh(shared2.ctx.colors.facade || 14209216, 0.8));
31103
31208
  }
31104
31209
  }
31105
31210
  }
@@ -31833,10 +31938,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31833
31938
  }
31834
31939
  Object.assign(K, { typeTable });
31835
31940
  }
31836
- function installFurnitureTaps(K, shared) {
31837
- shared.tapCount = 0;
31941
+ function installFurnitureTaps(K, shared2) {
31942
+ shared2.tapCount = 0;
31838
31943
  function counterTap(K2, x, y, z, reach, back, meta = {}) {
31839
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared.tapCount++;
31944
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++;
31840
31945
  K2.c("metal", x, y, z, 0.028, 0.012, cr);
31841
31946
  K2.c("metal", x, y + 0.012, z, 0.014, 0.12, cr);
31842
31947
  const pts = [];
@@ -31867,7 +31972,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
31867
31972
  return id;
31868
31973
  }
31869
31974
  function wallTap(K2, x, y, zw, direction, back, meta = {}) {
31870
- const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared.tapCount++, s = direction || 1;
31975
+ const cr = 12896460, id = "tap_" + (K2.M.seed || "") + "_" + shared2.tapCount++, s = direction || 1;
31871
31976
  K2.t("metal", [x, y, zw], [x, y, zw + s * 0.025], 0.03, cr);
31872
31977
  K2.t("metal", [x, y, zw + s * 0.02], [x, y, zw + s * 0.1], 0.016, cr);
31873
31978
  K2.e("metal", x, y, zw + s * 0.105, 0.019, 0.04, cr);
@@ -32117,7 +32222,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32117
32222
  }
32118
32223
  Object.assign(K, { GREENS: GREENS2, FLOWERS, blobs, potModel, arcLeaf, tuft, palm_tree, treeModel, shrubModel, potPlant, tablePot, planterModel });
32119
32224
  }
32120
- function installFurnitureYard(K, shared) {
32225
+ function installFurnitureYard(K, shared2) {
32121
32226
  const seedKey = (id) => K.seedKey(id);
32122
32227
  const { FURNITURE, SEED, STYLE, kit2, rngString, sh, wallTap } = K;
32123
32228
  FURNITURE.laundry_tub = function(M, A) {
@@ -32207,7 +32312,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32207
32312
  }
32208
32313
  }
32209
32314
  }, { id: "laundry_" + M.seed, swing: true, room: "yard" });
32210
- (shared.ctx.clotheslines || (shared.ctx.clotheslines = [])).push(M.seed);
32315
+ (shared2.ctx.clotheslines || (shared2.ctx.clotheslines = [])).push(M.seed);
32211
32316
  };
32212
32317
  FURNITURE.water_tank = function(M, A) {
32213
32318
  const K2 = kit2(M, A), w = M.w || 1, d = M.d || 1, onGround = !M.onSlab && (M.y || 0) < 0.5, color2 = M.palette && M.palette.tank_water != null ? M.palette.tank_water : 3107496, r = Math.min(w, d) * 0.46, rc = 11841700;
@@ -32349,13 +32454,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32349
32454
  }
32350
32455
  Object.assign(K, { extraTypes });
32351
32456
  }
32352
- function installFurniturePlaceItems(K, shared) {
32457
+ function installFurniturePlaceItems(K, shared2) {
32353
32458
  const { THREE, Y0, _col, boxC, colorOf, cursor, decorLights, makeApi, structurePiece } = K;
32354
32459
  const buildItem2 = (...a) => K.buildItem(...a);
32355
32460
  const registerCollision = (...a) => K.registerCollision(...a);
32356
32461
  const vegItem = (...a) => K.vegItem(...a);
32357
32462
  function houseItems() {
32358
- const R = shared.ctx.r, T2 = shared.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
32463
+ const R = shared2.ctx.r, T2 = shared2.ctx.types, api = makeApi(), noModel = /* @__PURE__ */ new Map();
32359
32464
  const list2 = R.items.concat(R.stateItems.filter((e) => e.w != null && e.d != null && e.type !== "razor_wire" && e.type !== "barbed_wire"));
32360
32465
  const rect = (poly) => {
32361
32466
  let a = 0;
@@ -32367,8 +32472,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32367
32472
  if (m.type === "stairs") continue;
32368
32473
  const exterior = m.outdoor || m.floor < 0, f = exterior ? -1 : Math.min(m.floor, R.floors.length - 1);
32369
32474
  cursor.group = exterior ? "lot" : "f" + f;
32370
- const com = shared.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
32371
- const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) != null ? colorOf(m.color) : void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared.ctx.night, light: shared.ctx.night, lit: shared.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
32475
+ const com = shared2.ctx.roomById[m.room], base = exterior ? 0 : Y0(f);
32476
+ const M = { x: m.x, z: m.z, ry: m.ry || 0, w: m.w, d: m.d, h: m.h, y: m.y || 0, base, floor: exterior ? -1 : f, palette: shared2.ctx.colors, color: m.category === "ground_cover" ? void 0 : colorOf(m.color) != null ? colorOf(m.color) : void 0, seed: m.id, room: m.room, typeWith: com ? com.type : null, ceiling: com ? com.ceiling : 2.9, on: shared2.ctx.night, light: shared2.ctx.night, lit: shared2.ctx.night, open: !!m.doorOpen, overhead: m.overhead, assembly: m.assembly, hose: m.hose };
32372
32477
  if (m.category === "ground_cover" && m.polygon) {
32373
32478
  const xs = m.polygon.map((p) => p[0]), zs = m.polygon.map((p) => p[1]);
32374
32479
  M.x = (Math.min(...xs) + Math.max(...xs)) / 2;
@@ -32378,8 +32483,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32378
32483
  M.ry = 0;
32379
32484
  if (!rect(m.polygon)) M.poly = m.polygon.map((p) => [p[0] - M.x, p[1] - M.z]);
32380
32485
  }
32381
- if (shared.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
32382
- if (shared.ctx.iv && shared.ctx.iv.replace.has(m.id)) {
32486
+ if (shared2.ctx.veg && vegItem(m, M, exterior ? "lot" : "f" + f)) continue;
32487
+ if (shared2.ctx.iv && shared2.ctx.iv.replace.has(m.id)) {
32383
32488
  registerCollision(m, M);
32384
32489
  continue;
32385
32490
  }
@@ -32411,13 +32516,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32411
32516
  return noModel;
32412
32517
  }
32413
32518
  function waterTankOfHouse(api) {
32414
- const cd = shared.ctx.r.waterTank;
32415
- if (!cd || !shared.ctx.types.water_tank) return;
32416
- const lc = cd.place === "raised_slab" && cd.platform, slab = cd.place === "slab" || !!lc, nA = shared.ctx.r.floors.length, f = Math.max(0, Math.min(nA - 1, cd.floor));
32417
- const base = lc ? cd.platform.topY : cd.y + (shared.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
32519
+ const cd = shared2.ctx.r.waterTank;
32520
+ if (!cd || !shared2.ctx.types.water_tank) return;
32521
+ const lc = cd.place === "raised_slab" && cd.platform, slab = cd.place === "slab" || !!lc, nA = shared2.ctx.r.floors.length, f = Math.max(0, Math.min(nA - 1, cd.floor));
32522
+ const base = lc ? cd.platform.topY : cd.y + (shared2.ctx.r.rooms.some((c) => c.id === cd.room && c.type === "terrace") ? 0 : 0.2 + (slab ? 0.03 : 0));
32418
32523
  cursor.group = slab ? "f" + f : "attic_tank";
32419
32524
  if (lc) {
32420
- const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668;
32525
+ const P = cd.platform, [x0, z0, x1, z1] = P.aabb, e = P.thickness, color2 = shared2.ctx.colors.slab != null ? shared2.ctx.colors.slab : 12170668;
32421
32526
  cursor.pc = structurePiece("tank_slab");
32422
32527
  boxC("plain", (x0 + x1) / 2, P.topY - e / 2, (z0 + z1) / 2, x1 - x0, e, z1 - z0, color2, 0, 0, 0);
32423
32528
  P.pillars.forEach((p, k) => {
@@ -32427,13 +32532,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32427
32532
  cursor.pc = null;
32428
32533
  }
32429
32534
  if (!slab) {
32430
- const color2 = shared.ctx.colors.slab != null ? shared.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
32535
+ const color2 = shared2.ctx.colors.slab != null ? shared2.ctx.colors.slab : 12170668, yp = Y0(f), hw = cd.w / 2 + 0.1, hd = cd.d / 2 + 0.1;
32431
32536
  boxC("plain", cd.u, base - 0.06, cd.v, hw * 2, 0.12, hd * 2, color2);
32432
32537
  for (const sx of [-1, 1]) for (const sz of [-1, 1]) boxC("plain", cd.u + sx * (hw - 0.07), (yp + base - 0.12) / 2, cd.v + sz * (hd - 0.07), 0.1, base - 0.12 - yp, 0.1, color2);
32433
32538
  }
32434
- const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
32435
- shared.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
32436
- shared.ctx.types.water_tank.f(M, api);
32539
+ const M = { x: cd.u, z: cd.v, ry: 0, w: cd.w, d: cd.d, h: cd.h + 0.12, y: 0, base, floor: f, colors: shared2.ctx.colors, seed: "water_tank", room: cd.room, onSlab: true, ceiling: 2.9 };
32540
+ shared2.ctx.waterTankPos = { x: cd.u, z: cd.v, y: base, group: cursor.group };
32541
+ shared2.ctx.types.water_tank.f(M, api);
32437
32542
  }
32438
32543
  function hashColor(s) {
32439
32544
  let h = 7;
@@ -32443,11 +32548,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32443
32548
  function labeledBox(m, M, group) {
32444
32549
  const color2 = M.color != null ? M.color : hashColor(m.category || m.type), h = Math.max(0.05, m.h || 0.5);
32445
32550
  boxC("plain", m.x, M.base + (m.y || 0) + h / 2, m.z, m.w, h, m.d, color2, 0, m.ry || 0, 0);
32446
- shared.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
32551
+ shared2.ctx.labels.push({ pos: new THREE.Vector3(m.x, M.base + (m.y || 0) + h + 0.15, m.z), text: m.type, group, type: "no_model" });
32447
32552
  }
32448
32553
  Object.assign(K, { houseItems, waterTankOfHouse, hashColor, labeledBox });
32449
32554
  }
32450
- function installVegetationBridge(K, shared) {
32555
+ function installVegetationBridge(K, shared2) {
32451
32556
  const seedKey = (id) => K.seedKey(id);
32452
32557
  const { THREE, SEED, rngString } = K;
32453
32558
  const VEG_POT = ["potted_areca", "potted_snake_plant", "potted_fern"], VEG_CACTUS = { cactus_mandacaru: "mandacaru", cactus_palm: "prickly_pear", cactus_crown: "crown_cactus", cactus_xique: "xique_xique", cactus_pot: "potted_cactus" };
@@ -32473,7 +32578,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32473
32578
  for (const k of Object.keys(VEG_CACTUS)) VEG_MAP[k] = [VEG_CACTUS[k]];
32474
32579
  const VEG_PLANTER = { planter_bed: ["rose_bush_red", "rose_bush_pink", "rose_bush_white", "marigold", "periwinkle_pink", "periwinkle_white", "daisy"], planter_bed_small: ["rose_bush_red", "marigold", "periwinkle_pink", "daisy"], garden_bed: ["lawn_tuft", "wild_flowers"] };
32475
32580
  function vegItem(m, M, group) {
32476
- const V3 = shared.ctx.veg;
32581
+ const V3 = shared2.ctx.veg;
32477
32582
  if (!V3) return false;
32478
32583
  const ids = VEG_MAP[m.type], can2 = VEG_PLANTER[m.type];
32479
32584
  if (!ids && !can2) return false;
@@ -32514,7 +32619,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32514
32619
  return true;
32515
32620
  }
32516
32621
  function assembleVegetation(groups) {
32517
- const V3 = shared.ctx.veg;
32622
+ const V3 = shared2.ctx.veg;
32518
32623
  if (!V3) return;
32519
32624
  let pl = 0, tri = 0;
32520
32625
  const col = [], lod = [0, 0, 0], mats = V3.mats();
@@ -32537,17 +32642,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32537
32642
  for (const c of lot.colliders) col.push(Object.assign({ y: G.y, group: G.group }, c));
32538
32643
  for (let i = 0; i < 3; i++) lod[i] += lot.lodCounts[i];
32539
32644
  }
32540
- shared.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
32645
+ shared2.ctx.vegInfo = { plants: pl, triangles: tri, colliders: col, lodCounts: lod, materials: mats };
32541
32646
  }
32542
32647
  Object.assign(K, { VEG_POT, VEG_CACTUS, VEG_MAP, VEG_PLANTER, vegItem, assembleVegetation });
32543
32648
  }
32544
- function installInteractionState(K, shared) {
32649
+ function installInteractionState(K, shared2) {
32545
32650
  const { THREE, cfg, colliderChanged, invalidateShadow, invalidate, UV_SCALE, applyPart, texture } = K;
32546
32651
  const ivRoomEffective = (...a) => K.ivRoomEffective(...a);
32547
32652
  const ivRoomLight = (...a) => K.ivRoomLight(...a);
32548
- shared.partState = /* @__PURE__ */ new Map();
32653
+ shared2.partState = /* @__PURE__ */ new Map();
32549
32654
  const newInteractiveState = () => ({ defs: /* @__PURE__ */ new Map(), items: [], pieces: [], lights: /* @__PURE__ */ new Map(), litRooms: /* @__PURE__ */ new Set(), objs: [], anim: /* @__PURE__ */ new Set(), msg: null, target: null });
32550
- shared.inter = newInteractiveState();
32655
+ shared2.inter = newInteractiveState();
32551
32656
  const MESSAGE_MS = 2200;
32552
32657
  UV_SCALE.doorWood = 1;
32553
32658
  UV_SCALE.doorPaint = 1;
@@ -32602,15 +32707,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32602
32707
  }
32603
32708
  const _EY = new THREE.Vector3(0, 1, 0), _UM3 = new THREE.Vector3(1, 1, 1);
32604
32709
  const hudMessage = (text) => {
32605
- shared.inter.msg = { text, until: performance.now() + MESSAGE_MS };
32710
+ shared2.inter.msg = { text, until: performance.now() + MESSAGE_MS };
32606
32711
  if (cfg.onMessage) cfg.onMessage(text);
32607
32712
  };
32608
32713
  function definePiece(name, def) {
32609
32714
  def.name = name;
32610
32715
  def.meshes = [];
32611
- def.t = def.target = shared.partState.has(name) ? shared.partState.get(name) : def.t0 || 0;
32612
- shared.inter.defs.set(name, def);
32613
- shared.inter.pieces.push(def);
32716
+ def.t = def.target = shared2.partState.has(name) ? shared2.partState.get(name) : def.t0 || 0;
32717
+ shared2.inter.defs.set(name, def);
32718
+ shared2.inter.pieces.push(def);
32614
32719
  return def;
32615
32720
  }
32616
32721
  const localOf = (M, lx, lz) => {
@@ -32622,7 +32727,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32622
32727
  return true;
32623
32728
  }
32624
32729
  function assembleInteractive(gs) {
32625
- for (const [name, def] of shared.inter.defs) {
32730
+ for (const [name, def] of shared2.inter.defs) {
32626
32731
  const g = gs[name];
32627
32732
  if (!g) continue;
32628
32733
  delete gs[name];
@@ -32644,13 +32749,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32644
32749
  const parent = def.leaf ? def.leaf.gs[def.k] : gs[def.parent] || (gs[def.parent] = new THREE.Group());
32645
32750
  if (parent) parent.add(outer);
32646
32751
  if (def.roomId) {
32647
- if (!shared.inter.lights.has(def.roomId)) shared.inter.lights.set(def.roomId, []);
32648
- shared.inter.lights.get(def.roomId).push(def);
32752
+ if (!shared2.inter.lights.has(def.roomId)) shared2.inter.lights.set(def.roomId, []);
32753
+ shared2.inter.lights.get(def.roomId).push(def);
32649
32754
  }
32650
32755
  applyPiece(def);
32651
32756
  }
32652
- for (const roomId of shared.inter.litRooms) applyLight(roomId);
32653
- shared.inter.defs.forEach((d) => {
32757
+ for (const roomId of shared2.inter.litRooms) applyLight(roomId);
32758
+ shared2.inter.defs.forEach((d) => {
32654
32759
  if (d.col) d.col.off = d.t > 0.5;
32655
32760
  });
32656
32761
  }
@@ -32690,8 +32795,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32690
32795
  }
32691
32796
  const DURATION = { swing: 0.55, drawer: 0.4, curtain: 0.9, gate_swing: 0.9, gate_tilt: 1.4, gate_slide: 1.6, lightSwitch: 0.12, part: 0.4 };
32692
32797
  function animateInteractive(dt) {
32693
- if (!shared.inter.anim.size) return;
32694
- for (const p of shared.inter.anim) {
32798
+ if (!shared2.inter.anim.size) return;
32799
+ for (const p of shared2.inter.anim) {
32695
32800
  const step = dt / (DURATION[p.kind] || 0.5), d = p.target - p.t;
32696
32801
  p.t = Math.abs(d) <= step ? p.target : p.t + Math.sign(d) * step;
32697
32802
  applyPiece(p);
@@ -32699,39 +32804,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32699
32804
  p.col.off = p.target > 0.5;
32700
32805
  colliderChanged(p.col);
32701
32806
  }
32702
- if (p.t === p.target) shared.inter.anim.delete(p);
32807
+ if (p.t === p.target) shared2.inter.anim.delete(p);
32703
32808
  }
32704
32809
  invalidateShadow();
32705
32810
  }
32706
32811
  function togglePiece(p) {
32707
32812
  p.target = p.target > 0.5 ? 0 : 1;
32708
- shared.partState.set(p.name, p.target);
32813
+ shared2.partState.set(p.name, p.target);
32709
32814
  if (p.col && p.col.off !== p.target > 0.5) {
32710
32815
  p.col.off = p.target > 0.5;
32711
32816
  colliderChanged(p.col);
32712
32817
  }
32713
- shared.inter.anim.add(p);
32818
+ shared2.inter.anim.add(p);
32714
32819
  }
32715
- const lightBase = (roomId) => roomId == null ? true : shared.partState.has("light:" + roomId) ? !!shared.partState.get("light:" + roomId) : !!shared.ctx.night;
32820
+ const lightBase = (roomId) => roomId == null ? true : shared2.partState.has("light:" + roomId) ? !!shared2.partState.get("light:" + roomId) : !!shared2.ctx.night;
32716
32821
  const lightOn = (roomId) => {
32717
- const S = roomId != null && shared.ctx.iv && shared.ctx.iv.roomStates.get(roomId);
32822
+ const S = roomId != null && shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
32718
32823
  return S ? S.ef : lightBase(roomId);
32719
32824
  };
32720
32825
  function applyLight(roomId) {
32721
32826
  const on = lightOn(roomId);
32722
- for (const d of shared.inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? shared.mats.emissive : shared.mats.off;
32723
- const sw = shared.inter.defs.get("ix:int:" + roomId);
32827
+ for (const d of shared2.inter.lights.get(roomId) || []) for (const m of d.meshes) if (m.name.endsWith("/emissive")) m.material = on ? shared2.mats.emissive : shared2.mats.off;
32828
+ const sw = shared2.inter.defs.get("ix:int:" + roomId);
32724
32829
  if (sw) {
32725
32830
  sw.target = on ? 1 : 0;
32726
- if (sw.t !== sw.target) shared.inter.anim.add(sw);
32831
+ if (sw.t !== sw.target) shared2.inter.anim.add(sw);
32727
32832
  }
32728
32833
  invalidate();
32729
32834
  }
32730
32835
  function toggleLight(roomId) {
32731
- const S = shared.ctx.iv && shared.ctx.iv.roomStates.get(roomId);
32836
+ const S = shared2.ctx.iv && shared2.ctx.iv.roomStates.get(roomId);
32732
32837
  if (S) {
32733
- ivRoomLight(shared.ctx.iv, roomId, !S.ef);
32734
- const ef = ivRoomEffective(shared.ctx.iv, S);
32838
+ ivRoomLight(shared2.ctx.iv, roomId, !S.ef);
32839
+ const ef = ivRoomEffective(shared2.ctx.iv, S);
32735
32840
  if (ef !== S.ef) {
32736
32841
  S.ef = ef;
32737
32842
  applyLight(roomId);
@@ -32739,13 +32844,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32739
32844
  }
32740
32845
  return;
32741
32846
  }
32742
- shared.partState.set("light:" + roomId, !lightOn(roomId));
32847
+ shared2.partState.set("light:" + roomId, !lightOn(roomId));
32743
32848
  applyLight(roomId);
32744
32849
  if (cfg.onLight) cfg.onLight(roomId, lightOn(roomId));
32745
32850
  }
32746
32851
  Object.assign(K, { newInteractiveState, MESSAGE_MS, createInteractiveMaterials, _EY, _UM3, hudMessage, definePiece, localOf, visibleChain, assembleInteractive, applyPiece, DURATION, animateInteractive, togglePiece, lightBase, lightOn, applyLight, toggleLight });
32747
32852
  }
32748
- function installInteractionCollision(K, shared) {
32853
+ function installInteractionCollision(K, shared2) {
32749
32854
  const NO_COLLIDE = /(^|_)(rug|floor|concrete|dirt|lawn|deck|ceiling_light|pendant|chandelier|spot|picture|curtain|blinds|wall_shelving|plank_shelf|wall_ac|ac_condenser|pool|soaking_tub|pergola|stairs|mirror)/;
32750
32855
  function registerCollision(m, M) {
32751
32856
  const h = m.h || 0, y = M.y || 0;
@@ -32755,7 +32860,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32755
32860
  w = Math.min(w, 0.5);
32756
32861
  d = Math.min(d, 0.5);
32757
32862
  }
32758
- shared.inter.objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
32863
+ shared2.inter.objs.push({ f: M.floor, cx: m.x, cz: m.z, c: Math.cos(M.ry), s: Math.sin(M.ry), hw: w / 2, hd: d / 2, type: m.type });
32759
32864
  }
32760
32865
  function objectDistance(o, x, z) {
32761
32866
  const dx = x - o.cx, dz = z - o.cz, lx = dx * o.c - dz * o.s, lz = dx * o.s + dz * o.c, ex = Math.abs(lx) - o.hw, ez = Math.abs(lz) - o.hd;
@@ -32763,7 +32868,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32763
32868
  }
32764
32869
  function collideObject(x, z, fx, fz, floor2) {
32765
32870
  const R = 0.2;
32766
- for (const o of shared.inter.objs) {
32871
+ for (const o of shared2.inter.objs) {
32767
32872
  if (o.f !== -1 ? o.f !== floor2 : floor2 !== 0) continue;
32768
32873
  const d1 = objectDistance(o, x, z);
32769
32874
  if (d1 < R && d1 < objectDistance(o, fx, fz) - 1e-6) return true;
@@ -32773,7 +32878,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32773
32878
  function collideAt(x, z, floor2, opt) {
32774
32879
  opt = opt || {};
32775
32880
  const R = opt.radius != null ? opt.radius : 0.24;
32776
- for (const c of shared.ctx.colliders) {
32881
+ for (const c of shared2.ctx.colliders) {
32777
32882
  if (c.off) continue;
32778
32883
  if (c.f !== -1 && c.f !== floor2) continue;
32779
32884
  if (c.f === -1 && floor2 !== 0) continue;
@@ -32785,7 +32890,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32785
32890
  }
32786
32891
  Object.assign(K, { NO_COLLIDE, registerCollision, objectDistance, collideObject, collideAt });
32787
32892
  }
32788
- function installInteractionItems(K, shared) {
32893
+ function installInteractionItems(K, shared2) {
32789
32894
  const { t, LIGHTS, cursor, definePiece, localOf, registerCollision, togglePiece } = K;
32790
32895
  const DOOR_ITEM = /^(tv_unit|tv_unit_small|tv_unit_large|sideboard|china_cabinet|filing_cabinet|pantry|laundry_cabinet|wardrobe|wardrobe_small|wardrobe_large|closet_wardrobe|kitchen_cabinet|kitchen_cabinet_large|kitchen_cabinet_small|fridge|fridge_large|display_fridge_medium|display_fridge)$/;
32791
32896
  const DRAWER_ITEM = /^(console_table|dresser|nightstand|vanity_table)$/;
@@ -32810,7 +32915,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32810
32915
  }
32811
32916
  function lightItem(m, M, ent, api, parent) {
32812
32917
  M.on = M.light = M.lit = true;
32813
- const n0 = LIGHTS.length, name = shared.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
32918
+ const n0 = LIGHTS.length, name = shared2.quality === "game" ? "ix:light:" + m.room + "@" + parent : "ix:light:" + m.id;
32814
32919
  cursor.group = name;
32815
32920
  try {
32816
32921
  ent.f(M, api);
@@ -32818,8 +32923,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32818
32923
  cursor.group = parent;
32819
32924
  }
32820
32925
  for (let i = n0; i < LIGHTS.length; i++) LIGHTS[i].roomId = m.room;
32821
- if (!shared.inter.defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
32822
- shared.inter.litRooms.add(m.room);
32926
+ if (!shared2.inter.defs.has(name)) definePiece(name, { kind: "light", pivot: [0, 0, 0], ry: 0, parent, roomId: m.room });
32927
+ shared2.inter.litRooms.add(m.room);
32823
32928
  }
32824
32929
  function curtainItem(m, M, ent, api, parent) {
32825
32930
  M.open = false;
@@ -32847,12 +32952,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32847
32952
  for (const c of body) api[c[0]](M, ...c[1]);
32848
32953
  if (!parts.length) return;
32849
32954
  const [ax, az] = localOf(M, 0, 0.2);
32850
- shared.inter.items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(parts[0].target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
32955
+ shared2.inter.items.push({ type: "curtain", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (m.h || 2) * 0.5, az], range: 2.4, angle: 1, pieces: parts, text: () => t(parts[0].target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.curtain") }), action: () => {
32851
32956
  const al = parts[0].target > 0.5 ? 0 : 1;
32852
32957
  for (const p of parts) {
32853
32958
  p.target = al;
32854
- shared.partState.set(p.name, al);
32855
- shared.inter.anim.add(p);
32959
+ shared2.partState.set(p.name, al);
32960
+ shared2.inter.anim.add(p);
32856
32961
  }
32857
32962
  } });
32858
32963
  }
@@ -32922,8 +33027,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32922
33027
  p.def = def;
32923
33028
  parts.push(def);
32924
33029
  const [ax, az] = localOf(M, cx, front + 0.08);
32925
- shared.inter.items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
32926
- def.item = shared.inter.items[shared.inter.items.length - 1];
33030
+ shared2.inter.items.push({ type: drawer ? "drawer" : "cabinet", id: m.id, floor: M.floor, anchor: [ax, M.base + (M.y || 0) + (p.y0 + p.y1) / 2, az], range: 1.6, angle: 0.4, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what." + name) }), action: () => togglePiece(def) });
33031
+ def.item = shared2.inter.items[shared2.inter.items.length - 1];
32927
33032
  });
32928
33033
  calls.forEach((c, i) => {
32929
33034
  const p = owner.get(i);
@@ -32939,10 +33044,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32939
33044
  }
32940
33045
  Object.assign(K, { DOOR_ITEM, DRAWER_ITEM, LIGHT_TYPES, objectName, recordApi, buildItem: buildItem2, lightItem, curtainItem, furnitureItem });
32941
33046
  }
32942
- function installInteractionFittings(K, shared) {
33047
+ function installInteractionFittings(K, shared2) {
32943
33048
  const { t, EPS: EPS6, OPEN_AREA, Y0, applyPiece, bx, cursor, definePiece, gates, lightOn, roomAt, slideDirection, toggleLight, togglePiece } = K;
32944
33049
  function gatesInteractive() {
32945
- const lt2 = shared.ctx.r.lot;
33050
+ const lt2 = shared2.ctx.r.lot;
32946
33051
  if (!lt2) return;
32947
33052
  const cz0 = (lt2.rect[1] + lt2.rect[3]) / 2;
32948
33053
  const orig = K.getBx(), gs = lt2.gates, opening = gs.map((g) => g.open), reg = gs.map((g) => {
@@ -32964,7 +33069,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32964
33069
  }
32965
33070
  return orig(mat, x0, y0, z0, x1, y1, z1, color2);
32966
33071
  });
32967
- const n0 = shared.ctx.colliders.length;
33072
+ const n0 = shared2.ctx.colliders.length;
32968
33073
  try {
32969
33074
  gs.forEach((g) => {
32970
33075
  g.open = false;
@@ -32976,7 +33081,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32976
33081
  g.open = opening[i];
32977
33082
  });
32978
33083
  }
32979
- const cols = shared.ctx.colliders.slice(n0), cz = (lt2.rect[1] + lt2.rect[3]) / 2, cu = (lt2.rect[0] + lt2.rect[2]) / 2;
33084
+ const cols = shared2.ctx.colliders.slice(n0), cz = (lt2.rect[1] + lt2.rect[3]) / 2, cu = (lt2.rect[0] + lt2.rect[2]) / 2;
32980
33085
  reg.forEach((r, i) => {
32981
33086
  const g = r.g;
32982
33087
  if (!isFinite(r.x0)) return;
@@ -32985,25 +33090,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
32985
33090
  const p = ped ? definePiece(name, Object.assign(base, { kind: "gate_swing", pivot: [r.x0, 0, g.v], angle: -sd * 1.65 })) : tilt ? definePiece(name, Object.assign(base, { kind: "gate_tilting", pivot: [(r.x0 + r.x1) / 2, r.y1, g.v], angle: -sd * 1.45 })) : definePiece(name, Object.assign(base, { kind: "gate_sliding", pivot: [r.x0, 0, r.zm], travel: r.dx * g.width }));
32986
33091
  if (p.col) p.col.off = p.target > 0.5;
32987
33092
  const text = () => t(p.target > 0.5 ? "prompt.close" : "prompt.open", { what: t(ped ? "what.pedestrianGate" : "what.garageGate") });
32988
- shared.inter.items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
33093
+ shared2.inter.items.push({ type: "gate", id: g.id, floor: -1, anchor: [g.u, 1, g.v + sd * 0.4], range: 2.8, angle: 0.9, pieces: [p], text, action: () => togglePiece(p), noWall: true });
32989
33094
  });
32990
33095
  }
32991
33096
  function mailboxInteractive() {
32992
- for (const m of shared.ctx.r.items) {
33097
+ for (const m of shared2.ctx.r.items) {
32993
33098
  if (m.type !== "mailbox") continue;
32994
- const g = shared.ctx.parts && shared.ctx.parts["mailbox_" + m.id];
33099
+ const g = shared2.ctx.parts && shared2.ctx.parts["mailbox_" + m.id];
32995
33100
  if (!g) continue;
32996
33101
  const name = "ix:correio:" + m.id, def = definePiece(name, { kind: "part", pivot: [0, 0, 0], ry: 0, parent: "lot" });
32997
33102
  def.inner = g;
32998
33103
  const fx = Math.sin(m.ry || 0), fz = Math.cos(m.ry || 0), ay = (m.y || 1) + (m.h || 0.3) * 0.4;
32999
- shared.inter.items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
33104
+ shared2.inter.items.push({ type: "mailbox", id: m.id, floor: -1, anchor: [m.x + fx * 0.2, ay, m.z + fz * 0.2], range: 2.2, angle: 0.7, pieces: [def], text: () => t(def.target > 0.5 ? "prompt.close" : "prompt.open", { what: t("what.mailbox") }), action: () => togglePiece(def), noWall: true });
33000
33105
  applyPiece(def);
33001
33106
  }
33002
33107
  }
33003
33108
  function placeSwitches() {
33004
- const R = shared.ctx.r, used = /* @__PURE__ */ new Set();
33109
+ const R = shared2.ctx.r, used = /* @__PURE__ */ new Set();
33005
33110
  for (const c of R.rooms) {
33006
- if (c.type === "void" || OPEN_AREA(c) || !shared.inter.litRooms.has(c.id) || used.has(c.id) || shared.ctx.iv && shared.ctx.iv.switchRooms.has(c.id)) continue;
33111
+ if (c.type === "void" || OPEN_AREA(c) || !shared2.inter.litRooms.has(c.id) || used.has(c.id) || shared2.ctx.iv && shared2.ctx.iv.switchRooms.has(c.id)) continue;
33007
33112
  const doors = R.doors.filter((p) => p.floor === c.floor && (p.a === c.id || p.b === c.id));
33008
33113
  doors.sort((p, q) => ((q.exterior ? 1 : 0) - (p.exterior ? 1 : 0)) * (c.type === "living" ? 1 : -1));
33009
33114
  for (const p of doors) if (putSwitch(c, p)) {
@@ -33013,7 +33118,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33013
33118
  }
33014
33119
  }
33015
33120
  function putSwitch(c, p) {
33016
- const R = shared.ctx.r, f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
33121
+ const R = shared2.ctx.r, f = p.floor, alongU = p.axis === "u", L = p.pos, a = p.at - p.width / 2, b = p.at + p.width / 2;
33017
33122
  const wref = R.walls.find((w) => w.floor === f && w.axis === p.axis && Math.abs((alongU ? w.v0 : w.u0) - L) < EPS6), th = wref ? wref.thickness || 0.15 : 0.15;
33018
33123
  const inside2 = (sd2) => {
33019
33124
  const cc = roomAt(f, alongU ? p.at : L + sd2 * 0.4, alongU ? L + sd2 * 0.4 : p.at);
@@ -33040,17 +33145,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33040
33145
  const piece2 = definePiece("ix:int:" + roomId, { kind: "light_switch", pivot: pv, ry: 0, parent: "f" + f, axis: alongU ? "x" : "z", sgn: alongU ? sd : -sd, t0: lightOn(roomId) ? 1 : 0 });
33041
33146
  piece2.t = piece2.target = lightOn(roomId) ? 1 : 0;
33042
33147
  const an = alongU ? [u, yc, face + sd * 0.12] : [face + sd * 0.12, yc, u];
33043
- shared.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
33148
+ shared2.inter.items.push({ type: "light_switch", id: roomId, floor: f, anchor: an, range: 1.5, angle: 0.45, pieces: [piece2], text: () => t(lightOn(roomId) ? "prompt.lightOff" : "prompt.lightOn"), action: () => toggleLight(roomId) });
33044
33149
  return true;
33045
33150
  }
33046
33151
  return false;
33047
33152
  }
33048
33153
  Object.assign(K, { gatesInteractive, mailboxInteractive, placeSwitches, putSwitch });
33049
33154
  }
33050
- function installInteractionDoors(K, shared) {
33155
+ function installInteractionDoors(K, shared2) {
33051
33156
  const { t, colliderChanged, invalidateShadow, applyPiece, hudMessage } = K;
33052
33157
  function linkDoorLeaves() {
33053
- for (const fo of shared.ctx.leaves) fo.handles = (fo.handleNames || []).map((n) => shared.inter.defs.get(n)).filter(Boolean);
33158
+ for (const fo of shared2.ctx.leaves) fo.handles = (fo.handleNames || []).map((n) => shared2.inter.defs.get(n)).filter(Boolean);
33054
33159
  }
33055
33160
  function handleApply(fo) {
33056
33161
  for (const mc of fo.handles || []) {
@@ -33062,7 +33167,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33062
33167
  if (fo.phase === "rattle") return;
33063
33168
  if (fo.phase === "handle" || fo.phase === "swing") {
33064
33169
  fo.open = !fo.open;
33065
- shared.doorState.set(fo.id, fo.open);
33170
+ shared2.doorState.set(fo.id, fo.open);
33066
33171
  fo.col.off = fo.open;
33067
33172
  colliderChanged(fo.col);
33068
33173
  fo.anim = true;
@@ -33072,25 +33177,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33072
33177
  if (fo.blockedFlag || fo.locked) {
33073
33178
  fo.phase = "rattle";
33074
33179
  fo.jig = 0.7;
33075
- shared.ctx.animateDoorsOn = true;
33180
+ shared2.ctx.animateDoorsOn = true;
33076
33181
  hudMessage(t(fo.blockedFlag ? "message.boarded" : "message.locked"));
33077
33182
  return;
33078
33183
  }
33079
33184
  fo.open = !fo.open;
33080
- shared.doorState.set(fo.id, fo.open);
33185
+ shared2.doorState.set(fo.id, fo.open);
33081
33186
  fo.col.off = fo.open;
33082
33187
  colliderChanged(fo.col);
33083
33188
  fo.anim = true;
33084
- shared.ctx.animateDoorsOn = true;
33189
+ shared2.ctx.animateDoorsOn = true;
33085
33190
  if (fo.handles && fo.handles.length) {
33086
33191
  fo.phase = "handle";
33087
33192
  fo.hT = fo.hT || 0;
33088
33193
  } else fo.phase = "swing";
33089
33194
  }
33090
33195
  function animateDoors(dt) {
33091
- if (!shared.ctx.animateDoorsOn) return;
33196
+ if (!shared2.ctx.animateDoorsOn) return;
33092
33197
  let active = false;
33093
- for (const fo of shared.ctx.leaves) {
33198
+ for (const fo of shared2.ctx.leaves) {
33094
33199
  if (!fo.phase) continue;
33095
33200
  active = true;
33096
33201
  if (fo.phase === "handle") {
@@ -33120,13 +33225,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33120
33225
  }
33121
33226
  }
33122
33227
  }
33123
- shared.ctx.animateDoorsOn = active;
33228
+ shared2.ctx.animateDoorsOn = active;
33124
33229
  invalidateShadow();
33125
33230
  }
33126
33231
  function wallBlocks(ex, ez, ax, az, floor2) {
33127
- const n = shared.ctx.wallColliders != null ? shared.ctx.wallColliders : 0;
33232
+ const n = shared2.ctx.wallColliders != null ? shared2.ctx.wallColliders : 0;
33128
33233
  for (let i = 0; i < n; i++) {
33129
- const c = shared.ctx.colliders[i];
33234
+ const c = shared2.ctx.colliders[i];
33130
33235
  if (c.f !== floor2 && !(c.f === -1 && floor2 === 0)) continue;
33131
33236
  let t0 = 0, t1 = 1;
33132
33237
  const dx = ax - ex, dz = az - ez;
@@ -33158,7 +33263,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33158
33263
  }
33159
33264
  Object.assign(K, { linkDoorLeaves, handleApply, toggleDoor, animateDoors, wallBlocks, doorText, applyLeaf });
33160
33265
  }
33161
- function installInteractionTarget(K, shared) {
33266
+ function installInteractionTarget(K, shared2) {
33162
33267
  const { doorText, toggleDoor, visibleChain, wallBlocks } = K;
33163
33268
  const ivTarget = (...a) => K.ivTarget(...a);
33164
33269
  function targetOf(o, opt) {
@@ -33169,7 +33274,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33169
33274
  const tries = (score, text, action, target) => {
33170
33275
  if (!best || score < best.score) best = { score, text, action, target };
33171
33276
  };
33172
- for (const fo of shared.ctx.leaves) {
33277
+ for (const fo of shared2.ctx.leaves) {
33173
33278
  if (fo.floor !== floor2) continue;
33174
33279
  const d = Math.hypot(fo.cx - ex, fo.cz - ez);
33175
33280
  if (d > 1.7) continue;
@@ -33177,11 +33282,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33177
33282
  if (angle > 1.35 && d > 0.9) continue;
33178
33283
  tries(angle * 1.6 + d * 0.5 + (angle < 0.25 ? 0 : 0.6), doorText(fo), () => toggleDoor(fo), fo);
33179
33284
  }
33180
- const vis = shared.inter.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
33181
- const kitA = shared.ctx.iv ? ivTarget(shared.ctx.iv, o, opt && opt.interactives) : null;
33285
+ const vis = shared2.inter.pieces.flatMap((p) => p.meshes).filter(visibleChain), hit = vis.length && opt.strike ? opt.strike(vis) : null;
33286
+ const kitA = shared2.ctx.iv ? ivTarget(shared2.ctx.iv, o, opt && opt.interactives) : null;
33182
33287
  const nearKit = kitA && hit && Math.hypot(kitA.target.pos[0] - ex, kitA.target.pos[1] - ey, kitA.target.pos[2] - ez) < hit.distance + 0.1;
33183
33288
  const pieceHit = hit && !nearKit && hit.object.userData.piece;
33184
- for (const it of shared.inter.items) {
33289
+ for (const it of shared2.inter.items) {
33185
33290
  if (it.floor !== floor2 && !(it.floor === -1 && floor2 === 0)) continue;
33186
33291
  const [ax, ay, az] = it.anchor, dx = ax - ex, dy = ay - ey, dz = az - ez, d = Math.hypot(dx, dy, dz), dh = Math.hypot(dx, dz);
33187
33292
  if (dh > it.range + 0.4) continue;
@@ -33196,14 +33301,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33196
33301
  }
33197
33302
  Object.assign(K, { targetOf });
33198
33303
  }
33199
- function installInteractablesBridge(K, shared) {
33304
+ function installInteractablesBridge(K, shared2) {
33200
33305
  const { t, THREE, invalidate, invalidateShadow, cfg, DOC, LIGHT_TYPES, _Y, _q, _v3, accFor, applyLight, cursor, hashString, hudMessage, lightBase, pieceRecord, put, rgbOf, sh, wallBlocks } = K;
33201
33306
  const enter = (...a) => K.enter(...a);
33202
33307
  const roomLightMask = (...a) => K.roomLightMask(...a);
33203
33308
  const IV_MATERIAL = { plain: "plain", metal: "metal", wood: "wood", glass: "glass", fabric: "fabric", plant: "plant", water: "water", emissive: "emissive", atlas_picture: "picture", atlas_floor: "floor" };
33204
33309
  const IV_WIRE = { conduit: 13618628, cable: 2762532, drop: 1381653, cord: 1776413, earth: 3111482, hose: 11556124 };
33205
33310
  const IV_DOOR = /^(door|drawer)/;
33206
- const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared.ctx.r.floors.length - 1);
33311
+ const ivGroup = (e) => e.floor < 0 ? "lot" : "f" + Math.min(e.floor, shared2.ctx.r.floors.length - 1);
33207
33312
  function ivAccumulate(mat, g, ox, oy, oz, ry, color2) {
33208
33313
  const P = g.attributes.position, N = g.attributes.normal, C = color2 == null ? g.attributes.color : null, U = g.attributes.uv, I = g.index, nv = P.count, ni = I ? I.count : nv;
33209
33314
  const A = accFor(mat);
@@ -33247,7 +33352,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33247
33352
  A.ni += ni;
33248
33353
  }
33249
33354
  function ivBuild(h, water) {
33250
- const ik = K.IVK, r = shared.ctx.r, A = ik.A, world0 = null;
33355
+ const ik = K.IVK, r = shared2.ctx.r, A = ik.A, world0 = null;
33251
33356
  void world0;
33252
33357
  const plane2 = A.plan(r, { seed: r.seed });
33253
33358
  const IV = { k: ik, plane: plane2, world: null, water, entries: /* @__PURE__ */ new Map(), roots: [], replace: /* @__PURE__ */ new Set(), roomStates: /* @__PURE__ */ new Map(), lampRoom: /* @__PURE__ */ new Map(), anim: /* @__PURE__ */ new Map(), screens: /* @__PURE__ */ new Map(), efx: null, items: null, itemsDirty: true, itemsT: 0, dirty: true, list: null, listT: 0, t: 0, circuits: [], switchRooms: /* @__PURE__ */ new Set(), warnings: [], tBuild: 0 };
@@ -33268,7 +33373,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33268
33373
  const wants = (roomId) => lightBase(roomId);
33269
33374
  const entById = new Map(plane2.items.map((e) => [e.id, e]));
33270
33375
  const entByItem = new Map(plane2.items.map((e) => [e.item, e]));
33271
- IV.mats = { plain: shared.mats.plain, metal: shared.mats.metal, wood: shared.mats.wood, glass: shared.mats.glass, fabric: shared.mats.fabric, plant: shared.mats.plant, water: shared.mats.water, emissive: shared.mats.emissive, atlas_picture: shared.mats.picture, atlas_floor: shared.mats.floor };
33376
+ IV.mats = { plain: shared2.mats.plain, metal: shared2.mats.metal, wood: shared2.mats.wood, glass: shared2.mats.glass, fabric: shared2.mats.fabric, plant: shared2.mats.plant, water: shared2.mats.water, emissive: shared2.mats.emissive, atlas_picture: shared2.mats.picture, atlas_floor: shared2.mats.floor };
33272
33377
  const ev = (e) => ivEvent(h, e);
33273
33378
  const world = IV.world = A.createWorld(r, { water, seed: r.seed, onEvent: ev });
33274
33379
  const add0 = world.add;
@@ -33276,7 +33381,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33276
33381
  const e = entById.get(id);
33277
33382
  if (e && e.type === "lamp") {
33278
33383
  const roomId = IV.lampRoom.get(id);
33279
- spec.devices[0].on = roomId ? wants(roomId) : !!shared.ctx.night;
33384
+ spec.devices[0].on = roomId ? wants(roomId) : !!shared2.ctx.night;
33280
33385
  spec.parts = (spec.parts || []).concat([{ id: "_x", pivot: [0, 0, 0], motion: { kind: "slide", axis: [0, 1, 0], distance: 1e-3 }, label: "" }]);
33281
33386
  spec.interactions = [{ id: "device.lamp", pos: [0, 0, 0], action: { do: "toggle_device", device: "lamp" }, label: "", requires: { object: id, part: "_x" } }];
33282
33387
  } else if (e && e.type === "wall_switch") {
@@ -33302,7 +33407,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33302
33407
  }
33303
33408
  if (e.type === "lamp" && o.devices && o.devices.lamp) {
33304
33409
  const roomId = IV.lampRoom.get(id);
33305
- o.devices.lamp.on = roomId ? wants(roomId) : !!shared.ctx.night;
33410
+ o.devices.lamp.on = roomId ? wants(roomId) : !!shared2.ctx.night;
33306
33411
  } else if (e.type === "wall_switch" && o.parts && o.parts.rocker !== void 0) {
33307
33412
  const l = (e.connections.controls || [])[0], roomId = l && IV.lampRoom.get(l);
33308
33413
  if (roomId) o.parts.rocker = wants(roomId) ? 1 : 0;
@@ -33394,7 +33499,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33394
33499
  const ik = IV.k, w = IV.world, wl = (o, p) => ik.GI.localToWorld(o.transform, p), g0 = cursor.group;
33395
33500
  const tube2 = (pts, radius, color2, ox, oy, oz, ry) => {
33396
33501
  try {
33397
- const m = ik.gfx.createCord(pts, radius, shared.mats.plain);
33502
+ const m = ik.gfx.createCord(pts, radius, shared2.mats.plain);
33398
33503
  ivAccumulate("plain", m.geometry, ox, oy, oz, ry, color2);
33399
33504
  m.geometry.dispose();
33400
33505
  } catch (e) {
@@ -33437,7 +33542,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33437
33542
  for (const E of IV.roots) {
33438
33543
  (gs[E.group] || (gs[E.group] = new THREE.Group())).add(E.root);
33439
33544
  }
33440
- for (const [roomId] of IV.roomStates) if (!shared.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
33545
+ for (const [roomId] of IV.roomStates) if (!shared2.inter.litRooms.has(roomId)) IV.roomStates.delete(roomId);
33441
33546
  for (const E of IV.entries.values()) if (E.parts && Object.keys(E.parts).length) IV.k.gfx.syncObject(IV.world, E.id, E.parts, { time: 0 });
33442
33547
  for (const E of IV.entries.values()) if (E.screen) ivScreen(IV, E);
33443
33548
  }
@@ -33468,7 +33573,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33468
33573
  break;
33469
33574
  case "device": {
33470
33575
  const roomId = IV.lampRoom.get(e.object);
33471
- if (roomId) shared.partState.set("light:" + roomId, !!e.on);
33576
+ if (roomId) shared2.partState.set("light:" + roomId, !!e.on);
33472
33577
  invalidate();
33473
33578
  break;
33474
33579
  }
@@ -33621,7 +33726,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33621
33726
  gm.setIndex(new THREE.BufferAttribute(A.i.slice(0, A.ni), 1));
33622
33727
  gm.computeBoundingSphere();
33623
33728
  if (!IV.items) {
33624
- IV.items = new THREE.Mesh(gm, shared.mats.plain);
33729
+ IV.items = new THREE.Mesh(gm, shared2.mats.plain);
33625
33730
  IV.items.name = "iv-items";
33626
33731
  IV.items.castShadow = false;
33627
33732
  IV.items.receiveShadow = true;
@@ -33762,17 +33867,17 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33762
33867
  }
33763
33868
  Object.assign(K, { IV_MATERIAL, IV_WIRE, IV_DOOR, ivGroup, ivAccumulate, ivBuild, ivRoomEffective, ivDraw, ivCords, ivAssemble, ivScreen, ivEvent, ivSeat, ivUpdate, IV_SHAPE, ivItems, ivTarget, ivRoomLight, ivParts, ivDispose, ivPublish });
33764
33869
  }
33765
- function installAnimationClotheslines(K, shared) {
33870
+ function installAnimationClotheslines(K, shared2) {
33766
33871
  const { invalidate, CLOTHES_UNIFORMS } = K;
33767
33872
  const WIND = { t0: performance.now(), last: 0, base: 0.55 };
33768
33873
  function animateClotheslines(now) {
33769
- if (!shared.ctx.clotheslines || !shared.ctx.clotheslines.length) return;
33874
+ if (!shared2.ctx.clotheslines || !shared2.ctx.clotheslines.length) return;
33770
33875
  if (now - WIND.last < 33) return;
33771
33876
  WIND.last = now;
33772
33877
  const t = (now - WIND.t0) / 1e3;
33773
33878
  CLOTHES_UNIFORMS.uTime.value = t;
33774
33879
  CLOTHES_UNIFORMS.uVento.value = WIND.base + 0.45 * Math.sin(t * 0.23) * Math.sin(t * 0.11 + 1.3) + 0.25 * Math.max(0, Math.sin(t * 0.57));
33775
- const g = shared.ctx.parts && shared.ctx.parts["laundry_" + shared.ctx.clotheslines[0]];
33880
+ const g = shared2.ctx.parts && shared2.ctx.parts["laundry_" + shared2.ctx.clotheslines[0]];
33776
33881
  if (g) {
33777
33882
  let vis = true;
33778
33883
  for (let n = g; n; n = n.parent) if (!n.visible) {
@@ -33785,30 +33890,30 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33785
33890
  }
33786
33891
  Object.assign(K, { WIND, animateClotheslines });
33787
33892
  }
33788
- function installBuildInstance(K, shared) {
33893
+ function installBuildInstance(K, shared2) {
33789
33894
  const { PROPS, THREE, DOC, cfg, HP, createInteractiveMaterials, createMaterials: createMaterials2, typeTable } = K;
33790
33895
  const props = PROPS.create(THREE, { document: DOC, emit: () => {
33791
33896
  } });
33792
33897
  const TYPES = typeTable(props);
33793
- shared.mats = createMaterials2(props);
33794
- createInteractiveMaterials(shared.mats);
33898
+ shared2.mats = createMaterials2(props);
33899
+ createInteractiveMaterials(shared2.mats);
33795
33900
  if (cfg.materials) for (const k of Object.keys(cfg.materials)) {
33796
33901
  const v = cfg.materials[k];
33797
- shared.mats[k] = typeof v === "function" ? v(shared.mats[k], k) || shared.mats[k] : v;
33902
+ shared2.mats[k] = typeof v === "function" ? v(shared2.mats[k], k) || shared2.mats[k] : v;
33798
33903
  }
33799
33904
  const newState = () => ({ doors: /* @__PURE__ */ new Map(), inter: /* @__PURE__ */ new Map(), water: null, iv: null });
33800
33905
  function enter(h) {
33801
- shared.ctx = h.ctx;
33802
- shared.inter = h.inter;
33803
- shared.doorState = h.state.doors;
33804
- shared.partState = h.state.inter;
33805
- shared.mirrors = h.mirrors;
33806
- shared.quality = h.quality;
33906
+ shared2.ctx = h.ctx;
33907
+ shared2.inter = h.inter;
33908
+ shared2.doorState = h.state.doors;
33909
+ shared2.partState = h.state.inter;
33910
+ shared2.mirrors = h.mirrors;
33911
+ shared2.quality = h.quality;
33807
33912
  }
33808
33913
  const tagDamage = (type) => ({ type, hp: HP[type], hpMax: HP[type] });
33809
33914
  Object.assign(K, { props, TYPES, newState, enter, tagDamage });
33810
33915
  }
33811
- function installInteractablesKit(K, shared) {
33916
+ function installInteractablesKit(K, shared2) {
33812
33917
  const { t, THREE, DOC, cfg, Reflector } = K;
33813
33918
  const roomLightMask = (...a) => K.roomLightMask(...a);
33814
33919
  const IVK = (() => {
@@ -33826,15 +33931,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33826
33931
  const l = cfg.vegetation || null, G = l && (l.GameVegetation || (l.buildLot ? l : null)), S = l && (l.GameVegetationSpecies || (l.toSpec ? l : null));
33827
33932
  return G && S && G.buildLot && S.toSpec ? { G, S } : null;
33828
33933
  })();
33829
- shared.vegMaterials = null;
33830
- const vegMaterials = () => shared.vegMaterials || (shared.vegMaterials = (() => {
33934
+ shared2.vegMaterials = null;
33935
+ const vegMaterials = () => shared2.vegMaterials || (shared2.vegMaterials = (() => {
33831
33936
  const m = VEG.G.createVegetationMaterials(THREE);
33832
33937
  for (const k of ["wood", "foliage", "flowers", "fruit", "spines"]) roomLightMask(m[k]);
33833
33938
  return m;
33834
33939
  })());
33835
33940
  Object.assign(K, { IVK, VEG, vegMaterials });
33836
33941
  }
33837
- function installLightsRoomLight(K, shared) {
33942
+ function installLightsRoomLight(K, shared2) {
33838
33943
  const { THREE, rectsOf: rectsOf2 } = K;
33839
33944
  const MAX_LIGHTS = 12, EMPTY = [1e9, 1e9, -1e9, -1e9];
33840
33945
  const LZU = { uRB0: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB1: { value: new Float32Array(MAX_LIGHTS * 4) }, uRB2: { value: new Float32Array(MAX_LIGHTS * 4) }, uRBY: { value: new Float32Array(MAX_LIGHTS * 2) }, uREx: { value: new Float32Array(MAX_LIGHTS * 4) }, uIndK: { value: 0.06 } };
@@ -33873,7 +33978,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
33873
33978
  function lighting(o) {
33874
33979
  o = o || {};
33875
33980
  const scene = o.scene, N = Math.max(1, Math.min(MAX_LIGHTS, o.n || 6)), NS = Math.max(0, Math.min(N, o.shadows != null ? o.shadows : 2)), size = o.shadowSize || 512, MAX_EXTERNAL = o.external != null ? o.external : 2;
33876
- for (const k of Object.keys(shared.mats)) roomLightMask(shared.mats[k]);
33981
+ for (const k of Object.keys(shared2.mats)) roomLightMask(shared2.mats[k]);
33877
33982
  const PL = [], sig = new Array(N).fill(""), seg2 = { n: 0 };
33878
33983
  for (let i = 0; i < N; i++) {
33879
33984
  const l = new THREE.PointLight(16763008, 0, 8, 1.6);
@@ -34066,9 +34171,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34066
34171
  }
34067
34172
  return view;
34068
34173
  }
34069
- function installDestructionPieces(K, shared) {
34174
+ function installDestructionPieces(K, shared2) {
34070
34175
  const { THREE, floorAtY, pieceRecord } = K;
34071
- shared.destructionSeq = 0;
34176
+ shared2.destructionSeq = 0;
34072
34177
  const FRAGMENT_COLOR = { brick: 11031866, concrete: 10132118, plaster: 14210248, ceramic: 11821630, glass: 11456472, tempered_glass: 11456472, wood_soft: 11569752, wood_hard: 8016948, plywood: 12098154, mdf: 12098154, steel: 9080466, aluminium: 12106944, plastic: 3107496, copper: 12088115, stone: 9079428, fabric: 13616296 };
34073
34178
  const FRAGMENT_GEO = new THREE.BoxGeometry(1, 1, 1), FRAGMENT_MAT = {};
34074
34179
  const fragmentMaterial = (m) => FRAGMENT_MAT[m] || (FRAGMENT_MAT[m] = new THREE.MeshLambertMaterial({ color: FRAGMENT_COLOR[m] != null ? FRAGMENT_COLOR[m] : 9079428 }));
@@ -34077,7 +34182,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34077
34182
  objs = objs.filter(Boolean);
34078
34183
  if (!objs.length) return;
34079
34184
  const pc = pieceRecord(id, mat, role, extra);
34080
- shared.ctx.pieceObjects.set(id, objs);
34185
+ shared2.ctx.pieceObjects.set(id, objs);
34081
34186
  for (const o of objs) o.traverse((m) => {
34082
34187
  if (!m.isMesh) return;
34083
34188
  const u = m.userData;
@@ -34088,22 +34193,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34088
34193
  if (pc.explodes) u.destructionExplodes = pc.explodes;
34089
34194
  });
34090
34195
  };
34091
- for (const fo of shared.ctx.leaves) {
34196
+ for (const fo of shared2.ctx.leaves) {
34092
34197
  const pr = r.doors.find((p) => p.id === fo.id);
34093
34198
  tagObject("door:" + fo.id, fo.gs, fo.type === "steel" ? "steel" : pr && pr.exterior ? "wood_hard" : "mdf", null, { floor: fo.floor, mass: fo.type === "steel" ? 60 : 18, tags: ["door"] });
34094
34199
  }
34095
34200
  const cap = r.utilities.plumbing ? +r.utilities.plumbing.capacityL || 0 : 0;
34096
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) {
34201
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
34097
34202
  const tp = g.userData.part;
34098
34203
  if (tp === "water_tank") {
34099
- const e = shared.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
34204
+ const e = shared2.ctx.structureIndex.water_tank, L = cap || (g.userData.volume ? Math.round(g.userData.volume * 1e3) : 0);
34100
34205
  tagObject("water_tank", [g], "plastic", e ? e.role : null, { floor: e ? e.floor : 0, contains: L ? { fluid: "water", liters: L } : void 0, mass: e ? e.mass : 25, thickness: 4e-3, fill: 0.05, tags: ["tank"] });
34101
34206
  } else if (tp === "gas_cylinder") tagObject(id, [g], "steel", null, { mass: 11, form: "cylinder", thickness: 3e-3, fill: 0.03, contains: { fluid: "gas", liters: 13, pressurized: true }, explodes: { energy: 12e4, radius: 5, atC: 300 }, tags: ["gas_bottle"] });
34102
34207
  else if (tp === "wall_pipe") tagObject(id, [g], "plastic", null, { mass: 3, tags: ["pipe"] });
34103
34208
  else if (tp === "shower_door") tagObject(id, [g], "tempered_glass", null, { mass: 25 });
34104
34209
  else if (tp === "gate_leaf" || tp === "mailbox_door") tagObject(id, [g], "steel", null, { mass: 30 });
34105
34210
  }
34106
- for (const def of shared.inter.defs.values()) {
34211
+ for (const def of shared2.inter.defs.values()) {
34107
34212
  if (!def.outer) continue;
34108
34213
  if (/^gate/.test(def.kind)) tagObject(def.name, [def.outer], "steel", null, { mass: 80, tags: ["gate"] });
34109
34214
  else if (def.kind === "swing" || def.kind === "drawer") tagObject(def.name, [def.outer], "mdf", null, { mass: 6 });
@@ -34122,13 +34227,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34122
34227
  for (const f of o.userData.ranges) add2(f.id, { mesh: o, v0: f.v0, v1: f.v1, i0: f.i0, i1: f.i1, whole: f.v0 === 0 && f.v1 === nv });
34123
34228
  }
34124
34229
  });
34125
- for (const [id, objs] of shared.ctx.pieceObjects) for (const o of objs) add2(id, { obj: o });
34230
+ for (const [id, objs] of shared2.ctx.pieceObjects) for (const o of objs) add2(id, { obj: o });
34126
34231
  const box32 = (id) => {
34127
34232
  const b = new THREE.Box3(), v = new THREE.Vector3();
34128
34233
  for (const it of meshes.get(id) || []) {
34129
34234
  if (it.obj) {
34130
34235
  const bb = new THREE.Box3().setFromObject(it.obj);
34131
- if (!bb.isEmpty()) for (const x of [bb.min.x, bb.max.x]) for (const y of [bb.min.y, bb.max.y]) for (const z of [bb.min.z, bb.max.z]) b.expandByPoint(v.set(x, y, z).applyMatrix4(shared.ctx.unitInverse));
34236
+ if (!bb.isEmpty()) for (const x of [bb.min.x, bb.max.x]) for (const y of [bb.min.y, bb.max.y]) for (const z of [bb.min.z, bb.max.z]) b.expandByPoint(v.set(x, y, z).applyMatrix4(shared2.ctx.unitInverse));
34132
34237
  } else {
34133
34238
  const P = it.mesh.geometry.attributes.position.array;
34134
34239
  for (let k = it.v0; k < it.v1; k++) b.expandByPoint(v.set(P[k * 3], P[k * 3 + 1], P[k * 3 + 2]));
@@ -34138,15 +34243,15 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34138
34243
  };
34139
34244
  const parts = [], byId = /* @__PURE__ */ new Map(), supports = E0.supports.map((a) => Object.assign({}, a));
34140
34245
  for (const e of E0.parts) {
34141
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared.ctx.pieces.get(e.id);
34246
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
34142
34247
  if (pc) {
34143
34248
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
34144
34249
  }
34145
34250
  parts.push(p);
34146
34251
  byId.set(p.id, p);
34147
34252
  }
34148
- const base = parts.length, view = shared.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
34149
- for (const [id, pc] of shared.ctx.pieces) {
34253
+ const base = parts.length, view = shared2.ctx.panelView || panelViewOf(null, false), panelIds = new Set(view.panels.map((e) => e.id));
34254
+ for (const [id, pc] of shared2.ctx.pieces) {
34150
34255
  if (byId.has(id) || panelIds.has(id) || !meshes.has(id)) continue;
34151
34256
  const b = box32(id);
34152
34257
  if (!b) continue;
@@ -34180,7 +34285,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34180
34285
  parts.splice(0, parts.length, ...parts.filter((p) => !gone.has(p.id)));
34181
34286
  for (const id of gone) byId.delete(id);
34182
34287
  for (const e of view.panels) {
34183
- const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared.ctx.pieces.get(e.id);
34288
+ const p = Object.assign({}, e, { meshes: (meshes.get(e.id) || []).length, extra: false }), pc = shared2.ctx.pieces.get(e.id);
34184
34289
  if (pc) {
34185
34290
  for (const k of ["contains", "explodes", "tags", "form", "thickness", "fill"]) if (pc[k] != null && p[k] == null) p[k] = pc[k];
34186
34291
  }
@@ -34287,6 +34392,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34287
34392
  var SPALL_RAGGED = 0.045;
34288
34393
  var COVER2 = 0.015;
34289
34394
  var MAX_FLAKES = 64;
34395
+ function clipToBox(unit, box5) {
34396
+ const lo = [Math.max(unit.x - unit.sx / 2, box5[0]), Math.max(unit.y - unit.sy / 2, box5[1]), Math.max(unit.z - unit.sz / 2, box5[2])];
34397
+ const hi = [Math.min(unit.x + unit.sx / 2, box5[3]), Math.min(unit.y + unit.sy / 2, box5[4]), Math.min(unit.z + unit.sz / 2, box5[5])];
34398
+ if (hi[0] - lo[0] <= 1e-4 || hi[1] - lo[1] <= 1e-4 || hi[2] - lo[2] <= 1e-4) return null;
34399
+ return { x: (lo[0] + hi[0]) / 2, y: (lo[1] + hi[1]) / 2, z: (lo[2] + hi[2]) / 2, sx: hi[0] - lo[0], sy: hi[1] - lo[1], sz: hi[2] - lo[2], colour: unit.colour };
34400
+ }
34290
34401
  function installDestructionBreach(K, _shared) {
34291
34402
  const { THREE, fragmentMaterial, invalidate, invalidateShadow } = K;
34292
34403
  function createBreachView(opts) {
@@ -34397,6 +34508,16 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34397
34508
  material.userData.breachCore = core;
34398
34509
  return material;
34399
34510
  }
34511
+ function drawnBounds(items) {
34512
+ house.updateMatrixWorld(true);
34513
+ const box5 = new THREE.Box3(), toHouse = new THREE.Matrix4().copy(house.matrixWorld).invert();
34514
+ for (const it of items) {
34515
+ const a = it.mesh.userData._p0 || it.mesh.geometry.attributes.position.array;
34516
+ tmp.m.multiplyMatrices(toHouse, it.mesh.matrixWorld);
34517
+ for (let k = it.v0; k < it.v1; k++) box5.expandByPoint(tmp.p.set(a[k * 3], a[k * 3 + 1], a[k * 3 + 2]).applyMatrix4(tmp.m));
34518
+ }
34519
+ return [box5.min.x, box5.min.y, box5.min.z, box5.max.x, box5.max.y, box5.max.z];
34520
+ }
34400
34521
  function maskOf(hostId, parts) {
34401
34522
  const host = structure.byId.get(hostId);
34402
34523
  const [u0, v0, u1, v1] = host.aabb;
@@ -34484,7 +34605,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34484
34605
  for (const { c, part, units: units2, thick, mid } of shown) {
34485
34606
  if (!near(c)) continue;
34486
34607
  const centre = mask.start + (c.a + c.b) / 2, y = (c.y0 + c.y1) / 2, len = c.b - c.a, h = c.y1 - c.y0;
34487
- const at3 = (s, dy, d, colour) => list2.push({ x: mask.alongU ? centre : mid, y, z: mask.alongU ? mid : centre, sx: mask.alongU ? s : d, sy: dy, sz: mask.alongU ? d : s, colour });
34608
+ const at3 = (s, dy, d, colour) => {
34609
+ const unit = clipToBox({ x: mask.alongU ? centre : mid, y, z: mask.alongU ? mid : centre, sx: mask.alongU ? s : d, sy: dy, sz: mask.alongU ? d : s, colour }, view.bounds);
34610
+ if (unit) list2.push(unit);
34611
+ };
34488
34612
  const base = fragmentMaterial(part.material).color.getHex();
34489
34613
  const n = noise2(centre * 3.1, y * 2.7, 0.07);
34490
34614
  if (units2.mortar === "concrete") {
@@ -34551,6 +34675,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34551
34675
  units: null,
34552
34676
  gone: 0,
34553
34677
  pits: 0,
34678
+ bounds: drawnBounds(items),
34554
34679
  chips: new Map(parts.map((id) => [id, []])),
34555
34680
  spalls: new Map(parts.map((id) => [id, []])),
34556
34681
  openings: /* @__PURE__ */ new Map(),
@@ -34704,7 +34829,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34704
34829
  Object.assign(K, { createBreachView });
34705
34830
  }
34706
34831
  var FOLLOW_FLUSH_FALLBACK_MS = 100;
34707
- function installDestructionWorld(K, shared) {
34832
+ function installDestructionWorld(K, shared2) {
34708
34833
  const { THREE, cfg, invalidateShadow, invalidate, rngString, FRAGMENT_GEO, fragmentMaterial, createBreachView } = K;
34709
34834
  function createHouseDestruction(root, house, structure, parts, colliders, water) {
34710
34835
  const D = { world: cfg.destruction || null, id: null, active: false }, hiddenPieces = /* @__PURE__ */ new Set(), bodies = /* @__PURE__ */ new Map(), frags = [], facets = /* @__PURE__ */ new Map();
@@ -34940,7 +35065,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
34940
35065
  house.matrixWorld.decompose(p, q, sc);
34941
35066
  D.specOptions = specOptions || null;
34942
35067
  D.spec = structure.spec(specOptions);
34943
- D.id = D.world.add(D.spec, { id: "house3d:" + ++shared.destructionSeq, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] });
35068
+ D.id = D.world.add(D.spec, { id: "house3d:" + ++shared2.destructionSeq, position: [p.x, p.y, p.z], rotation: [q.x, q.y, q.z, q.w] });
34944
35069
  breach.claim();
34945
35070
  if (R) R.bind(D.id, house, { parts: rangesOf(), onFrame: () => breach.flush() });
34946
35071
  off = D.world.on("*", handleEvent);
@@ -35086,7 +35211,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35086
35211
  }
35087
35212
  Object.assign(K, { createHouseDestruction });
35088
35213
  }
35089
- function installBuildBuild(K, shared) {
35214
+ function installBuildBuild(K, shared2) {
35090
35215
  const { THREE, cfg, rectsOf: rectsOf2, invalidateShadow, colliderChanged, VERSION: VERSION2, CARS, EPS: EPS6, LIGHTS, MIRRORS, Y0, animateClotheslines, animateDoors, animateInteractive, applyLeaf, applyOutbuildings, applyPart, applyPiece, assembleInteractive, baseboardAndSidewalk, buildStairs, building, carModel, chooseMirror, closeScene, collideAt, createWater, cursor, doorText, doors, electricalStructure, elevator, floorsAndSlabs, gatesInteractive, houseItems, ivAssemble, ivBuild, ivDispose, ivParts, ivPublish, ivUpdate, lightOn, linkDoorLeaves, mailboxInteractive, newInteractiveState, newMirrorState, outbuildings, paths, perimeter, placeSwitches, roofs, roomAt, solar, targetOf, terrain, toggleDoor, toggleLight, walls, waterPipes, windows, props, TYPES, IVK, VEG, vegMaterials, markGroups, assembleStructure, createHouseDestruction, newState, enter, tagDamage } = K;
35091
35216
  function build(r0, opts) {
35092
35217
  opts = opts || {};
@@ -35097,43 +35222,43 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35097
35222
  cursor.accs.clear();
35098
35223
  LIGHTS.length = 0;
35099
35224
  const pr = opts.building || {};
35100
- shared.ctx.r = r;
35101
- shared.ctx.colors = r.colors;
35102
- shared.ctx.cut = !!opts.cut;
35103
- shared.ctx.night = !!opts.night;
35104
- shared.ctx.labels = [];
35105
- shared.ctx.colliders = [];
35106
- shared.ctx.stairs = [];
35107
- shared.ctx.noTerrain = opts.terrain === false;
35108
- shared.ctx.roomById = {};
35109
- for (const c of r.rooms) shared.ctx.roomById[c.id] = c;
35110
- shared.ctx.pieces = /* @__PURE__ */ new Map();
35111
- shared.ctx.pieceObjects = /* @__PURE__ */ new Map();
35112
- shared.ctx.structureIndex = {};
35113
- for (const e of r0.structure && r0.structure.parts || []) shared.ctx.structureIndex[e.id] = e;
35225
+ shared2.ctx.r = r;
35226
+ shared2.ctx.colors = r.colors;
35227
+ shared2.ctx.cut = !!opts.cut;
35228
+ shared2.ctx.night = !!opts.night;
35229
+ shared2.ctx.labels = [];
35230
+ shared2.ctx.colliders = [];
35231
+ shared2.ctx.stairs = [];
35232
+ shared2.ctx.noTerrain = opts.terrain === false;
35233
+ shared2.ctx.roomById = {};
35234
+ for (const c of r.rooms) shared2.ctx.roomById[c.id] = c;
35235
+ shared2.ctx.pieces = /* @__PURE__ */ new Map();
35236
+ shared2.ctx.pieceObjects = /* @__PURE__ */ new Map();
35237
+ shared2.ctx.structureIndex = {};
35238
+ for (const e of r0.structure && r0.structure.parts || []) shared2.ctx.structureIndex[e.id] = e;
35114
35239
  {
35115
- const view = shared.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
35116
- shared.ctx.panelsOf = /* @__PURE__ */ new Map();
35117
- for (const id of view.replaced) delete shared.ctx.structureIndex[id];
35240
+ const view = shared2.ctx.panelView = panelViewOf(r0.structure, !!cfg.destruction);
35241
+ shared2.ctx.panelsOf = /* @__PURE__ */ new Map();
35242
+ for (const id of view.replaced) delete shared2.ctx.structureIndex[id];
35118
35243
  for (const e of view.panels) {
35119
- shared.ctx.structureIndex[e.id] = e;
35120
- const l = shared.ctx.panelsOf.get(e.slab);
35244
+ shared2.ctx.structureIndex[e.id] = e;
35245
+ const l = shared2.ctx.panelsOf.get(e.slab);
35121
35246
  if (l) l.push(e);
35122
- else shared.ctx.panelsOf.set(e.slab, [e]);
35247
+ else shared2.ctx.panelsOf.set(e.slab, [e]);
35123
35248
  }
35124
35249
  }
35125
- shared.ctx.panes = r0.roof && r0.roof.panes || [];
35126
- shared.ctx.noPiece = false;
35250
+ shared2.ctx.panes = r0.roof && r0.roof.panes || [];
35251
+ shared2.ctx.noPiece = false;
35127
35252
  cursor.separate = opts.pieces === "meshes";
35128
35253
  cursor.pc = null;
35129
- shared.ctx.apartment = r.template === "apartment_modern";
35130
- shared.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
35131
- shared.ctx.pf = Math.max(1, Math.min(shared.ctx.pa, pr.floor != null ? pr.floor : 3));
35132
- shared.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
35133
- shared.ctx.showBuilding = shared.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
35134
- shared.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
35135
- shared.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
35136
- shared.ctx.vegInfo = null;
35254
+ shared2.ctx.apartment = r.template === "apartment_modern";
35255
+ shared2.ctx.pa = Math.max(3, Math.min(20, pr.floors != null ? pr.floors : 5));
35256
+ shared2.ctx.pf = Math.max(1, Math.min(shared2.ctx.pa, pr.floor != null ? pr.floor : 3));
35257
+ shared2.ctx.pu = Math.max(0, pr.unit != null ? pr.unit : 0);
35258
+ shared2.ctx.showBuilding = shared2.ctx.apartment && (pr.showIt == null ? true : !!pr.showIt);
35259
+ shared2.ctx.limits = { x0: -2, z0: -2, x1: r.w + 2, z1: r.d + 2 };
35260
+ shared2.ctx.veg = VEG ? { G: VEG.G, S: VEG.S, mats: vegMaterials, groups: /* @__PURE__ */ new Map(), ok: /* @__PURE__ */ new Map(), opts: shared2.quality === "game" ? { quality: "game" } : { lod: 0, triangleBudget: 6e4 } } : null;
35261
+ shared2.ctx.vegInfo = null;
35137
35262
  terrain();
35138
35263
  if (r.lot) {
35139
35264
  if (!opts.noPerimeter) {
@@ -35144,7 +35269,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35144
35269
  }
35145
35270
  walls();
35146
35271
  baseboardAndSidewalk();
35147
- shared.ctx.wallColliders = shared.ctx.colliders.length;
35272
+ shared2.ctx.wallColliders = shared2.ctx.colliders.length;
35148
35273
  doors();
35149
35274
  windows();
35150
35275
  floorsAndSlabs();
@@ -35152,14 +35277,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35152
35277
  buildStairs();
35153
35278
  elevator();
35154
35279
  const water = createWater(r, h.state);
35155
- shared.ctx.iv = null;
35280
+ shared2.ctx.iv = null;
35156
35281
  h.IV = null;
35157
35282
  if (IVK) {
35158
35283
  try {
35159
- h.IV = shared.ctx.iv = ivBuild(h, water);
35284
+ h.IV = shared2.ctx.iv = ivBuild(h, water);
35160
35285
  } catch (e) {
35161
35286
  console.warn("interactables", e);
35162
- shared.ctx.iv = h.IV = null;
35287
+ shared2.ctx.iv = h.IV = null;
35163
35288
  }
35164
35289
  }
35165
35290
  const noModel = houseItems();
@@ -35168,14 +35293,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35168
35293
  electricalStructure();
35169
35294
  roofs();
35170
35295
  solar();
35171
- if (shared.ctx.showBuilding) building();
35296
+ if (shared2.ctx.showBuilding) building();
35172
35297
  for (const c of r.rooms) {
35173
35298
  if (c.type === "void") continue;
35174
35299
  const [a, b, c2, d] = rectsOf2(c)[0];
35175
- shared.ctx.labels.push({ pos: new THREE.Vector3((a + c2) / 2, Y0(c.floor) + 1.1, (b + d) / 2), text: c.name, group: "f" + c.floor, type: "room", floor: c.floor });
35300
+ shared2.ctx.labels.push({ pos: new THREE.Vector3((a + c2) / 2, Y0(c.floor) + 1.1, (b + d) / 2), text: c.name, group: "f" + c.floor, type: "room", floor: c.floor });
35176
35301
  }
35177
- const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared.mats);
35178
- for (const fo of shared.ctx.leaves) {
35302
+ const mirrorsCopy = MIRRORS.map((E, i) => Object.assign({ i }, E)), gs = closeScene(shared2.mats);
35303
+ for (const fo of shared2.ctx.leaves) {
35179
35304
  const parent = gs["f" + fo.floor] || (gs["f" + fo.floor] = new THREE.Group());
35180
35305
  fo.gs = [];
35181
35306
  for (const gd of fo.groups) {
@@ -35188,22 +35313,22 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35188
35313
  }
35189
35314
  applyLeaf(fo);
35190
35315
  }
35191
- if (shared.ctx.iv) ivAssemble(shared.ctx.iv, gs);
35316
+ if (shared2.ctx.iv) ivAssemble(shared2.ctx.iv, gs);
35192
35317
  assembleInteractive(gs);
35193
35318
  linkDoorLeaves();
35194
35319
  mailboxInteractive();
35195
35320
  const root = markKitOrigin(new THREE.Group(), { owner: "game-floorplan-three", kind: "structure", id: r.template }), house = new THREE.Group();
35196
35321
  root.name = "house3d";
35197
35322
  root.add(house);
35198
- shared.mirrors.house = house;
35199
- if (shared.ctx.apartment) {
35200
- const u = r.building.units[Math.min(shared.ctx.pu, r.building.units.length - 1)];
35201
- house.position.set(u.u, shared.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
35323
+ shared2.mirrors.house = house;
35324
+ if (shared2.ctx.apartment) {
35325
+ const u = r.building.units[Math.min(shared2.ctx.pu, r.building.units.length - 1)];
35326
+ house.position.set(u.u, shared2.ctx.showBuilding ? 0 : -r.floors[0].y0, u.v);
35202
35327
  house.rotation.y = u.ry;
35203
- shared.ctx.unitRy = u.ry;
35328
+ shared2.ctx.unitRy = u.ry;
35204
35329
  }
35205
35330
  house.updateMatrixWorld(true);
35206
- shared.ctx.unitInverse = house.matrixWorld.clone().invert();
35331
+ shared2.ctx.unitInverse = house.matrixWorld.clone().invert();
35207
35332
  for (const [k, g] of Object.entries(gs)) {
35208
35333
  g.name = k;
35209
35334
  (k === "floor" || k === "building" ? root : house).add(g);
@@ -35212,31 +35337,31 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35212
35337
  h.root = root;
35213
35338
  h.house = house;
35214
35339
  h.houseGroup = house;
35215
- shared.ctx.noModel = noModel;
35216
- shared.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared.ctx.night).map((l) => ({ ...l }));
35217
- shared.ctx.animateDoorsOn = shared.ctx.animateDoorsOn || false;
35218
- for (const c of shared.ctx.colliders) {
35340
+ shared2.ctx.noModel = noModel;
35341
+ shared2.ctx.lights = LIGHTS.filter((l) => l.type !== "lantern" && l.type !== "candles" || shared2.ctx.night).map((l) => ({ ...l }));
35342
+ shared2.ctx.animateDoorsOn = shared2.ctx.animateDoorsOn || false;
35343
+ for (const c of shared2.ctx.colliders) {
35219
35344
  c.aabb = [c.x0, c.z0, c.x1, c.z1];
35220
35345
  if (c.type === "wall") c.damageable = tagDamage("masonry");
35221
35346
  }
35222
- const colliders = shared.ctx.colliders.concat(shared.inter.objs.map((o) => ({ type: "furniture", f: o.f, obb: { cx: o.cx, cz: o.cz, hw: o.hw, hd: o.hd, c: o.c, s: o.s }, item: o.type, off: false })));
35347
+ const colliders = shared2.ctx.colliders.concat(shared2.inter.objs.map((o) => ({ type: "furniture", f: o.f, obb: { cx: o.cx, cz: o.cz, hw: o.hw, hd: o.hd, c: o.c, s: o.s }, item: o.type, off: false })));
35223
35348
  const parts = {}, setOpen = (def, t) => {
35224
35349
  def.target = t;
35225
35350
  def.t = t;
35226
- shared.partState.set(def.name, t);
35351
+ shared2.partState.set(def.name, t);
35227
35352
  if (def.col) {
35228
35353
  def.col.off = t > 0.5;
35229
35354
  colliderChanged(def.col);
35230
35355
  }
35231
35356
  applyPiece(def);
35232
- shared.inter.anim.delete(def);
35357
+ shared2.inter.anim.delete(def);
35233
35358
  invalidateShadow();
35234
35359
  };
35235
35360
  const mark = (o, id) => {
35236
35361
  if (o) o.userData.partId = id;
35237
35362
  };
35238
35363
  const PART_DAMAGE = { water_tank: "water", shower_door: "glass", gate_leaf: "metal", mailbox_door: "metal", mirror: "glass", cooking_gas_cylinder: "gas" };
35239
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) {
35364
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) {
35240
35365
  const tp = g.userData.part, dn = PART_DAMAGE[tp];
35241
35366
  if (dn) g.userData.damageable = tagDamage(dn);
35242
35367
  mark(g, id);
@@ -35256,7 +35381,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35256
35381
  return g.userData.t || 0;
35257
35382
  }, meta: g.userData };
35258
35383
  }
35259
- for (const fo of shared.ctx.leaves) {
35384
+ for (const fo of shared2.ctx.leaves) {
35260
35385
  const id = "door:" + fo.id, dn = tagDamage(fo.type === "steel" ? "metal" : "wood");
35261
35386
  fo.damageable = dn;
35262
35387
  for (const g of fo.gs) mark(g, id);
@@ -35268,14 +35393,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35268
35393
  fo.col.off = fo.open;
35269
35394
  colliderChanged(fo.col);
35270
35395
  }
35271
- shared.doorState.set(fo.id, fo.open);
35396
+ shared2.doorState.set(fo.id, fo.open);
35272
35397
  applyLeaf(fo);
35273
35398
  invalidateShadow();
35274
35399
  }, get t() {
35275
35400
  return fo.t;
35276
35401
  }, leaf: fo };
35277
35402
  }
35278
- for (const def of shared.inter.defs.values()) {
35403
+ for (const def of shared2.inter.defs.values()) {
35279
35404
  if (!def.outer) continue;
35280
35405
  const cab = def.kind === "swing" || def.kind === "drawer", gate = /^gate/.test(def.kind);
35281
35406
  const dn = cab ? tagDamage("wood") : gate ? tagDamage("metal") : null;
@@ -35285,7 +35410,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35285
35410
  return def.t;
35286
35411
  }, def };
35287
35412
  }
35288
- if (shared.ctx.iv) ivParts(shared.ctx.iv, parts, tagDamage);
35413
+ if (shared2.ctx.iv) ivParts(shared2.ctx.iv, parts, tagDamage);
35289
35414
  const cars = [];
35290
35415
  CARS.forEach((C, i) => {
35291
35416
  const mod2 = carModel(C.k, C.seed);
@@ -35325,18 +35450,18 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35325
35450
  const actOn = (e, a) => {
35326
35451
  enter(h);
35327
35452
  if (cfg.onInteract && cfg.onInteract(e, a) === false) return false;
35328
- shared.inter.target = a || { target: e.ref, text: e.label, action: e._action };
35453
+ shared2.inter.target = a || { target: e.ref, text: e.label, action: e._action };
35329
35454
  e._action();
35330
35455
  return true;
35331
35456
  };
35332
- for (const fo of shared.ctx.leaves) {
35457
+ for (const fo of shared2.ctx.leaves) {
35333
35458
  const e = { id: "door:" + fo.id, type: fo.type === "steel" ? "garage_door" : "door", floor: fo.floor, pos: [fo.cx, Y0(fo.floor) + 1, fo.cz], radius: 1.7, get label() {
35334
35459
  return doorText(fo);
35335
35460
  }, ref: fo, _action: () => toggleDoor(fo) };
35336
35461
  e.act = () => actOn(e);
35337
35462
  interactables.push(e);
35338
35463
  }
35339
- for (const it of shared.inter.items) {
35464
+ for (const it of shared2.inter.items) {
35340
35465
  const k = it.type + ":" + it.id, n = usedMap.get(k) || 0;
35341
35466
  usedMap.set(k, n + 1);
35342
35467
  const e = { id: n ? k + "#" + n : k, type: it.type, floor: it.floor, pos: it.anchor.slice(), radius: it.range, angle: it.angle, get label() {
@@ -35346,12 +35471,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35346
35471
  interactables.push(e);
35347
35472
  it.pub = e;
35348
35473
  }
35349
- for (const fo of shared.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
35474
+ for (const fo of shared2.ctx.leaves) fo.pub = interactables.find((e) => e.ref === fo);
35350
35475
  const lodObjects = [];
35351
- for (const def of shared.inter.defs.values()) if (def.outer && /^(light|drawer|swing|curtain|light_switch|handle)$/.test(def.kind)) lodObjects.push(def.outer);
35352
- for (const [id, g] of Object.entries(shared.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
35353
- if (shared.ctx.iv) {
35354
- for (const E of shared.ctx.iv.roots) lodObjects.push(E.root);
35476
+ for (const def of shared2.inter.defs.values()) if (def.outer && /^(light|drawer|swing|curtain|light_switch|handle)$/.test(def.kind)) lodObjects.push(def.outer);
35477
+ for (const [id, g] of Object.entries(shared2.ctx.parts || {})) if (/^(handle|shower_door)$/.test(g.userData.part) && g.visible !== false) lodObjects.push(g);
35478
+ if (shared2.ctx.iv) {
35479
+ for (const E of shared2.ctx.iv.roots) lodObjects.push(E.root);
35355
35480
  }
35356
35481
  const countDraw = () => {
35357
35482
  let n = 0, t = 0;
@@ -35369,7 +35494,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35369
35494
  for (const o of lodObjects) o.visible = true;
35370
35495
  const budget = opts.drawCallBudget != null ? opts.drawCallBudget : cfg.drawCallBudget;
35371
35496
  const stats2 = { quality: h.quality, drawCalls: s0.n, drawCallsLOD1: s1.n, triangles: s0.t, trianglesLod1: s1.t, budget: budget || null, overBudget: !!budget && s0.n > budget, tBuild: performance.now() - t0 };
35372
- shared.ctx.tBuild = stats2.tBuild;
35497
+ shared2.ctx.tBuild = stats2.tBuild;
35373
35498
  const applyLod = (n) => {
35374
35499
  n = Math.max(0, Math.min(2, n | 0));
35375
35500
  if (n === h.lodCurrent) return;
@@ -35435,39 +35560,39 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35435
35560
  building: gs.building || null,
35436
35561
  waterTank: r.waterTank ? (() => {
35437
35562
  const pt = Object.values(parts).find((p) => p.type === "water_tank") || null;
35438
- return { part: pt, group: pt ? pt.group : null, pos: shared.ctx.waterTankPos || null, plant: r.waterTank };
35563
+ return { part: pt, group: pt ? pt.group : null, pos: shared2.ctx.waterTankPos || null, plant: r.waterTank };
35439
35564
  })() : null,
35440
35565
  colliders,
35441
35566
  parts,
35442
35567
  cars,
35443
35568
  interactables,
35444
- doors: shared.ctx.leaves,
35445
- stairs: shared.ctx.stairs,
35446
- labels: shared.ctx.labels,
35569
+ doors: shared2.ctx.leaves,
35570
+ stairs: shared2.ctx.stairs,
35571
+ labels: shared2.ctx.labels,
35447
35572
  noModel,
35448
35573
  lights: (() => {
35449
35574
  const by = {};
35450
- for (const l of shared.ctx.lights) {
35575
+ for (const l of shared2.ctx.lights) {
35451
35576
  const k = l.roomId != null ? l.roomId : l.room;
35452
35577
  (by[k] || (by[k] = [])).push(l);
35453
35578
  }
35454
- return { list: shared.ctx.lights, byRoom: by };
35579
+ return { list: shared2.ctx.lights, byRoom: by };
35455
35580
  })(),
35456
- limits: shared.ctx.limits,
35457
- apartment: shared.ctx.apartment,
35458
- showBuilding: shared.ctx.showBuilding,
35459
- buildingConfig: { floors: shared.ctx.pa, floor: shared.ctx.pf, unit: shared.ctx.pu },
35460
- unitRy: shared.ctx.unitRy || 0,
35461
- night: shared.ctx.night,
35462
- cut: shared.ctx.cut,
35581
+ limits: shared2.ctx.limits,
35582
+ apartment: shared2.ctx.apartment,
35583
+ showBuilding: shared2.ctx.showBuilding,
35584
+ buildingConfig: { floors: shared2.ctx.pa, floor: shared2.ctx.pf, unit: shared2.ctx.pu },
35585
+ unitRy: shared2.ctx.unitRy || 0,
35586
+ night: shared2.ctx.night,
35587
+ cut: shared2.ctx.cut,
35463
35588
  interactives: h.IV ? ivPublish(h) : null,
35464
35589
  state: h.state,
35465
35590
  stats: stats2,
35466
- vegetation: shared.ctx.vegInfo || null,
35467
- solar: shared.ctx.solarInfo || null,
35591
+ vegetation: shared2.ctx.vegInfo || null,
35592
+ solar: shared2.ctx.solarInfo || null,
35468
35593
  water,
35469
- electrical: shared.ctx.electricalInfo || null,
35470
- gutters: shared.ctx.gutterInfo || null,
35594
+ electrical: shared2.ctx.electricalInfo || null,
35595
+ gutters: shared2.ctx.gutterInfo || null,
35471
35596
  // per frame: doors, parts, wind-blown laundry and (with a focus) distance LOD; dt in seconds, time in ms (rAF); focus = {x,y,z} in world coordinates
35472
35597
  update(dt, time, focus) {
35473
35598
  enter(h);
@@ -35477,9 +35602,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35477
35602
  if (destruction.active || destruction.statistics().falling || destruction.statistics().fragments) destruction.animate(dt);
35478
35603
  if (h.IV) ivUpdate(h, dt, time, focus);
35479
35604
  if (time != null) animateClotheslines(time);
35480
- if (shared.vegMaterials) {
35481
- shared.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
35482
- shared.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
35605
+ if (shared2.vegMaterials) {
35606
+ shared2.vegMaterials.update((time != null ? time : performance.now()) / 1e3);
35607
+ shared2.vegMaterials.setActors(focus ? [{ x: focus.x, y: focus.y, z: focus.z, radius: 0.9 }] : []);
35483
35608
  }
35484
35609
  if (focus && cfg.lod !== false) {
35485
35610
  const L = Object.assign({ interior: 45, hide: 220 }, cfg.lod), d = distance3(focus), at3 = h.lodCurrent;
@@ -35491,12 +35616,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35491
35616
  show(o) {
35492
35617
  enter(h);
35493
35618
  o = o || {};
35494
- const rr = shared.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
35619
+ const rr = shared2.ctx.r, nA = rr.floors.length, a = o.floor == null ? -1 : o.floor, sel = a >= nA ? -1 : a, cut = !!o.cut;
35495
35620
  for (const [k, g] of Object.entries(gs)) {
35496
35621
  let v = true;
35497
35622
  if (k[0] === "f") v = sel < 0 || +k.slice(1) <= sel;
35498
35623
  else if (k[0] === "t") v = !cut && (sel < 0 || +k.slice(1) < sel);
35499
- else if (k === "roof") v = !cut && sel < 0 && (!shared.ctx.apartment || !shared.ctx.showBuilding || shared.ctx.pf === shared.ctx.pa);
35624
+ else if (k === "roof") v = !cut && sel < 0 && (!shared2.ctx.apartment || !shared2.ctx.showBuilding || shared2.ctx.pf === shared2.ctx.pa);
35500
35625
  else if (k === "attic_tank") v = (cut || sel >= 0) && (sel < 0 || nA - 1 <= sel);
35501
35626
  else if (k === "lot") v = o.lot == null ? true : !!o.lot;
35502
35627
  g.visible = v;
@@ -35513,11 +35638,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35513
35638
  return actOn(a.target && a.target.pub ? a.target.pub : { id: a.target && a.target.id || a.text, type: a.target && a.target.kit ? a.target.type : "door", label: a.text, ref: a.target, _action: a.action }, a);
35514
35639
  },
35515
35640
  message() {
35516
- return shared.inter.msg && performance.now() < shared.inter.msg.until ? shared.inter.msg.text : null;
35641
+ return shared2.inter.msg && performance.now() < shared2.inter.msg.until ? shared2.inter.msg.text : null;
35517
35642
  },
35518
35643
  toggleDoor(fo) {
35519
35644
  enter(h);
35520
- toggleDoor(typeof fo === "string" ? shared.ctx.leaves.find((f) => f.id === fo) : fo);
35645
+ toggleDoor(typeof fo === "string" ? shared2.ctx.leaves.find((f) => f.id === fo) : fo);
35521
35646
  },
35522
35647
  lightOn(roomId) {
35523
35648
  enter(h);
@@ -35589,13 +35714,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35589
35714
  });
35590
35715
  root.removeFromParent();
35591
35716
  },
35592
- internal: { h, ctx: shared.ctx, inter: shared.inter, partState: shared.partState, doorState: shared.doorState, mirrors: shared.mirrors }
35717
+ internal: { h, ctx: shared2.ctx, inter: shared2.inter, partState: shared2.partState, doorState: shared2.doorState, mirrors: shared2.mirrors }
35593
35718
  };
35594
35719
  return res;
35595
35720
  }
35596
35721
  Object.assign(K, { build });
35597
35722
  }
35598
- function buildApi(K, shared) {
35723
+ function buildApi(K, shared2) {
35599
35724
  const { cfg, VERSION: VERSION2, ATLAS, TEX, applyPart, carGroup, carModel, props, TYPES, roomLightMask, lighting, newState, build } = K;
35600
35725
  return {
35601
35726
  version: VERSION2,
@@ -35605,26 +35730,26 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35605
35730
  mv: props,
35606
35731
  applyPart,
35607
35732
  // the kernel and the shared state, for recorders that run the team's builders into something else than the house (`furnitureSpec`, `tapSpec`): not a stable api
35608
- internals: { K, shared },
35733
+ internals: { K, shared: shared2 },
35609
35734
  get materials() {
35610
- return shared.mats;
35735
+ return shared2.mats;
35611
35736
  },
35612
35737
  roomLightMask,
35613
35738
  lighting,
35614
35739
  setNight(n) {
35615
- shared.mats.glass.emissive.set(n ? 9067040 : 0);
35616
- shared.mats.glass.opacity = n ? 0.4 : 0.24;
35740
+ shared2.mats.glass.emissive.set(n ? 9067040 : 0);
35741
+ shared2.mats.glass.opacity = n ? 0.4 : 0.24;
35617
35742
  },
35618
35743
  cars: { model: carModel, group: carGroup, info: (k, seed) => {
35619
35744
  const m = carModel(k, seed);
35620
35745
  return m && { parts: m.parts.length, tris: m.tris, L: m.L, W: m.W, H: m.H };
35621
35746
  } },
35622
35747
  dispose() {
35623
- if (shared.vegMaterials) {
35624
- shared.vegMaterials.dispose();
35625
- shared.vegMaterials = null;
35748
+ if (shared2.vegMaterials) {
35749
+ shared2.vegMaterials.dispose();
35750
+ shared2.vegMaterials = null;
35626
35751
  }
35627
- for (const m of Object.values(shared.mats)) {
35752
+ for (const m of Object.values(shared2.mats)) {
35628
35753
  if (m && m.dispose) m.dispose();
35629
35754
  }
35630
35755
  for (const [k, t] of Object.entries(TEX)) if (t && t.dispose && !(cfg.textures && cfg.textures[k])) t.dispose();
@@ -35649,7 +35774,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35649
35774
  const colliderChanged = (c) => {
35650
35775
  if (c && cfg.onCollider) cfg.onCollider(c);
35651
35776
  };
35652
- const shared = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
35777
+ const shared2 = { mats: null, quality: cfg.quality === "game" ? "game" : "high" };
35653
35778
  const seedKey = (id) => {
35654
35779
  if (cfg.seedKey && id != null) {
35655
35780
  const k = cfg.seedKey(String(id));
@@ -35658,61 +35783,61 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35658
35783
  return id;
35659
35784
  };
35660
35785
  const K = { t: createTranslator2(cfg.locale), seedKey, THREE: shapeGeometries(THREE), cfg, DOC, PROPS, Reflector, FLEET, HP, invalidate, invalidateShadow, colliderChanged, VERSION, rectsOf, isOpenArea, OPEN_ROOM_TYPES: OPEN_ROOM_TYPES2 };
35661
- installKernelGeometry(K, shared);
35662
- installKernelNoise(K, shared);
35663
- installMaterialsTextures(K, shared);
35664
- installMaterialsMaterials(K, shared);
35665
- installKernelCloseScene(K, shared);
35666
- installHouseHelpers(K, shared);
35667
- installHouseWalls(K, shared);
35668
- installHouseDoors(K, shared);
35669
- installHouseWindows(K, shared);
35670
- installHouseFloors(K, shared);
35671
- installHouseStairs(K, shared);
35672
- installLightsFixtures(K, shared);
35673
- installLightsDecor(K, shared);
35674
- installLotTerrain(K, shared);
35675
- installLotPerimeter(K, shared);
35676
- installLotGates(K, shared);
35677
- installRoofRoofs(K, shared);
35678
- installRoofGutters(K, shared);
35679
- installRoofSlabs(K, shared);
35680
- installRoofTiles(K, shared);
35681
- installRoofRect(K, shared);
35682
- installMirrors(K, shared);
35683
- installCars(K, shared);
35684
- installHouseBuilding(K, shared);
35685
- installUtilitiesWater(K, shared);
35686
- installUtilitiesElectrical(K, shared);
35687
- installHouseBaseboard(K, shared);
35688
- installUtilitiesSolar(K, shared);
35689
- installHouseOutbuildings(K, shared);
35690
- installFurnitureApi(K, shared);
35691
- installFurnitureBuilders(K, shared);
35692
- installFurnitureTypeTable(K, shared);
35693
- installFurnitureTaps(K, shared);
35694
- installFurnitureFixtures(K, shared);
35695
- installFurniturePlants(K, shared);
35696
- installFurnitureYard(K, shared);
35697
- installFurnitureExtraTypes(K, shared);
35698
- installFurniturePlaceItems(K, shared);
35699
- installVegetationBridge(K, shared);
35700
- installInteractionState(K, shared);
35701
- installInteractionCollision(K, shared);
35702
- installInteractionItems(K, shared);
35703
- installInteractionFittings(K, shared);
35704
- installInteractionDoors(K, shared);
35705
- installInteractionTarget(K, shared);
35706
- installInteractablesBridge(K, shared);
35707
- installAnimationClotheslines(K, shared);
35708
- installBuildInstance(K, shared);
35709
- installInteractablesKit(K, shared);
35710
- installLightsRoomLight(K, shared);
35711
- installDestructionPieces(K, shared);
35712
- installDestructionBreach(K, shared);
35713
- installDestructionWorld(K, shared);
35714
- installBuildBuild(K, shared);
35715
- return buildApi(K, shared);
35786
+ installKernelGeometry(K, shared2);
35787
+ installKernelNoise(K, shared2);
35788
+ installMaterialsTextures(K, shared2);
35789
+ installMaterialsMaterials(K, shared2);
35790
+ installKernelCloseScene(K, shared2);
35791
+ installHouseHelpers(K, shared2);
35792
+ installHouseWalls(K, shared2);
35793
+ installHouseDoors(K, shared2);
35794
+ installHouseWindows(K, shared2);
35795
+ installHouseFloors(K, shared2);
35796
+ installHouseStairs(K, shared2);
35797
+ installLightsFixtures(K, shared2);
35798
+ installLightsDecor(K, shared2);
35799
+ installLotTerrain(K, shared2);
35800
+ installLotPerimeter(K, shared2);
35801
+ installLotGates(K, shared2);
35802
+ installRoofRoofs(K, shared2);
35803
+ installRoofGutters(K, shared2);
35804
+ installRoofSlabs(K, shared2);
35805
+ installRoofTiles(K, shared2);
35806
+ installRoofRect(K, shared2);
35807
+ installMirrors(K, shared2);
35808
+ installCars(K, shared2);
35809
+ installHouseBuilding(K, shared2);
35810
+ installUtilitiesWater(K, shared2);
35811
+ installUtilitiesElectrical(K, shared2);
35812
+ installHouseBaseboard(K, shared2);
35813
+ installUtilitiesSolar(K, shared2);
35814
+ installHouseOutbuildings(K, shared2);
35815
+ installFurnitureApi(K, shared2);
35816
+ installFurnitureBuilders(K, shared2);
35817
+ installFurnitureTypeTable(K, shared2);
35818
+ installFurnitureTaps(K, shared2);
35819
+ installFurnitureFixtures(K, shared2);
35820
+ installFurniturePlants(K, shared2);
35821
+ installFurnitureYard(K, shared2);
35822
+ installFurnitureExtraTypes(K, shared2);
35823
+ installFurniturePlaceItems(K, shared2);
35824
+ installVegetationBridge(K, shared2);
35825
+ installInteractionState(K, shared2);
35826
+ installInteractionCollision(K, shared2);
35827
+ installInteractionItems(K, shared2);
35828
+ installInteractionFittings(K, shared2);
35829
+ installInteractionDoors(K, shared2);
35830
+ installInteractionTarget(K, shared2);
35831
+ installInteractablesBridge(K, shared2);
35832
+ installAnimationClotheslines(K, shared2);
35833
+ installBuildInstance(K, shared2);
35834
+ installInteractablesKit(K, shared2);
35835
+ installLightsRoomLight(K, shared2);
35836
+ installDestructionPieces(K, shared2);
35837
+ installDestructionBreach(K, shared2);
35838
+ installDestructionWorld(K, shared2);
35839
+ installBuildBuild(K, shared2);
35840
+ return buildApi(K, shared2);
35716
35841
  }
35717
35842
  var WOOD_THIN = 0.035;
35718
35843
  var BOARD_TOP_THICK = 0.07;
@@ -35817,12 +35942,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35817
35942
  }
35818
35943
  const n = counters.get(key2) ?? 0;
35819
35944
  counters.set(key2, n + 1);
35820
- let rotation = null;
35945
+ let rotation2 = null;
35821
35946
  if (turned) {
35822
35947
  xyz.setFromQuaternion(q, "XYZ");
35823
- rotation = [xyz.x, xyz.y, xyz.z];
35948
+ rotation2 = [xyz.x, xyz.y, xyz.z];
35824
35949
  }
35825
- drawn.push({ id: `${key2}_${n}`, key: key2, shape, position: [px - root.x, py, pz - root.z], rotation, color: color2, min: min2, max: max2 });
35950
+ drawn.push({ id: `${key2}_${n}`, key: key2, shape, position: [px - root.x, py, pz - root.z], rotation: rotation2, color: color2, min: min2, max: max2 });
35826
35951
  };
35827
35952
  const A = {
35828
35953
  box(M, mat, x, y, z, bw, bh, bd, color2, ry = 0, rx = 0, rz = 0) {
@@ -35935,21 +36060,21 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
35935
36060
  const seed = Math.round(opts.seed ?? 1);
35936
36061
  const plain2 = SHELVING.test(type) ? "paper" : "plastic";
35937
36062
  const root = { x: seed, z: 0, ry: 0, w, d, h, y: 0, base: 0, palette: o.palette, seed: `furniture_${type}_${seed}` };
35938
- const { K, shared } = renderer.internals;
36063
+ const { K, shared: shared2 } = renderer.internals;
35939
36064
  const before = K.PARTS.length;
35940
36065
  const made = recordSpec(
35941
36066
  THREE,
35942
36067
  type,
35943
36068
  root,
35944
36069
  (A) => {
35945
- const saved = { api0: shared.api0, ctx: shared.ctx };
35946
- shared.api0 = A;
35947
- shared.ctx = shared.ctx ?? {};
36070
+ const saved = { api0: shared2.api0, ctx: shared2.ctx };
36071
+ shared2.api0 = A;
36072
+ shared2.ctx = shared2.ctx ?? {};
35948
36073
  try {
35949
36074
  ent.f(root, A);
35950
36075
  } finally {
35951
- shared.api0 = saved.api0;
35952
- shared.ctx = saved.ctx;
36076
+ shared2.api0 = saved.api0;
36077
+ shared2.ctx = saved.ctx;
35953
36078
  }
35954
36079
  },
35955
36080
  { materials: { plain: plain2, ...o.materials }, chairs: o.chairs, carcass: SHELVING.test(type) }
@@ -37466,7 +37591,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37466
37591
  const registry = createSoundRegistry(options.banks);
37467
37592
  const voices = createVoiceManager({ ...options.groups ? { groups: options.groups } : {}, ...options.maxVoices === void 0 ? {} : { maxVoices: options.maxVoices } });
37468
37593
  const engineRandom = createRng3(seed);
37469
- const shared = createNoiseStore(engineRandom);
37594
+ const shared2 = createNoiseStore(engineRandom);
37470
37595
  const busSettings = /* @__PURE__ */ new Map();
37471
37596
  const busNodes = /* @__PURE__ */ new Map();
37472
37597
  const meters = /* @__PURE__ */ new Map();
@@ -37505,7 +37630,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37505
37630
  if (!created) return null;
37506
37631
  context = created;
37507
37632
  chain = buildChain(created, mix3, engineRandom);
37508
- if (mix3.noise.create === "eager") noiseBuffer(shared, created, mix3.noise.seconds);
37633
+ if (mix3.noise.create === "eager") noiseBuffer(shared2, created, mix3.noise.seconds);
37509
37634
  for (const [bus, setting] of Object.entries(mix3.buses ?? {})) {
37510
37635
  busSettings.set(bus, { ...setting, ...busSettings.get(bus) });
37511
37636
  }
@@ -37624,8 +37749,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37624
37749
  const loopHost = {
37625
37750
  ready,
37626
37751
  output: outputFor,
37627
- prepareNoise: () => context && prepareNoise(shared, context, mix3.noise.seconds),
37628
- noise: () => noiseBuffer(shared, context, mix3.noise.seconds),
37752
+ prepareNoise: () => context && prepareNoise(shared2, context, mix3.noise.seconds),
37753
+ noise: () => noiseBuffer(shared2, context, mix3.noise.seconds),
37629
37754
  register: (loop) => void loops.add(loop),
37630
37755
  unregister: (loop) => void loops.delete(loop)
37631
37756
  };
@@ -37633,7 +37758,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37633
37758
  registry,
37634
37759
  register: (bank) => registry.register(bank),
37635
37760
  plan: (id, playOptions = {}) => planWith(id, playOptions, createRng3(playOptions.seed ?? seed)),
37636
- play: (id, playOptions = {}) => playWith(id, playOptions, randomFor(playOptions), shared),
37761
+ play: (id, playOptions = {}) => playWith(id, playOptions, randomFor(playOptions), shared2),
37637
37762
  playPlan(plan, playOptions = {}) {
37638
37763
  const audio = ready();
37639
37764
  if (!audio) return null;
@@ -37641,13 +37766,13 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37641
37766
  const recipe = { id: plan.id, bus: plan.bus, layers: [], sources: [], priority: plan.priority, ...plan.group ? { group: plan.group } : {} };
37642
37767
  const voiceId = plan.silent ? void 0 : admit(recipe, plan.level, plan.distance);
37643
37768
  if (voiceId === null) return null;
37644
- if (planUsesNoise(plan)) prepareNoise(shared, audio, mix3.noise.seconds);
37645
- return start(plan, shared, voiceId, playOptions.delay);
37769
+ if (planUsesNoise(plan)) prepareNoise(shared2, audio, mix3.noise.seconds);
37770
+ return start(plan, shared2, voiceId, playOptions.delay);
37646
37771
  },
37647
37772
  loop: (id, loopOptions = {}) => createLoopHandle(registry.loop(id), loopHost, loopOptions.volume),
37648
37773
  channel(channelOptions) {
37649
37774
  const random = channelOptions.random ?? (channelOptions.seed === void 0 ? engineRandom : createRng3(channelOptions.seed));
37650
- const store = channelOptions.ownNoise ? createNoiseStore(random) : shared;
37775
+ const store = channelOptions.ownNoise ? createNoiseStore(random) : shared2;
37651
37776
  return {
37652
37777
  random,
37653
37778
  play: (id, playOptions = {}) => playWith(id, playOptions, random, store),
@@ -37669,7 +37794,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37669
37794
  if (!context || !chain) return;
37670
37795
  const old = chain;
37671
37796
  chain = buildChain(context, mix3, engineRandom);
37672
- if (mix3.noise.seconds !== previous.noise.seconds) shared.reset();
37797
+ if (mix3.noise.seconds !== previous.noise.seconds) shared2.reset();
37673
37798
  for (const node of busNodes.values()) {
37674
37799
  node.disconnect();
37675
37800
  node.connect(chain.master);
@@ -37688,7 +37813,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37688
37813
  warmUp() {
37689
37814
  const audio = ready();
37690
37815
  if (!audio) return false;
37691
- noiseBuffer(shared, audio, mix3.noise.seconds);
37816
+ noiseBuffer(shared2, audio, mix3.noise.seconds);
37692
37817
  return true;
37693
37818
  },
37694
37819
  level(bus) {
@@ -37723,7 +37848,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
37723
37848
  chain = null;
37724
37849
  busNodes.clear();
37725
37850
  meters.clear();
37726
- shared.reset();
37851
+ shared2.reset();
37727
37852
  }
37728
37853
  };
37729
37854
  }
@@ -38809,14 +38934,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
38809
38934
  const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance };
38810
38935
  const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical };
38811
38936
  const cueTable = { ...RELOAD_CUES, ...options.reloadCues };
38812
- const shared = options.engine;
38813
- const engine = shared ?? createAudioEngine({
38937
+ const shared2 = options.engine;
38938
+ const engine = shared2 ?? createAudioEngine({
38814
38939
  seed,
38815
38940
  mix: { ...MIX_PROFILES.game, master: volume, noise: { seconds: NOISE_SECONDS, create: "eager" } },
38816
38941
  maxVoices: Number.POSITIVE_INFINITY,
38817
38942
  ...options.createContext ? { createContext: options.createContext } : {}
38818
38943
  });
38819
- const channel = shared && options.seed !== void 0 ? shared.channel({ seed }) : engine.channel({});
38944
+ const channel = shared2 && options.seed !== void 0 ? shared2.channel({ seed }) : engine.channel({});
38820
38945
  engine.register({ id: `weapons_three@${classBurstId(distanceCurve)}`, sounds: weaponRecipes(distanceCurve) });
38821
38946
  const classBurst = classBurstId(distanceCurve);
38822
38947
  const burst2 = (config) => {
@@ -38903,11 +39028,11 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
38903
39028
  },
38904
39029
  setVolume(next) {
38905
39030
  const level = Math.max(0, Math.min(1, next));
38906
- if (shared) shared.setBus("weapons", { gain: level });
39031
+ if (shared2) shared2.setBus("weapons", { gain: level });
38907
39032
  else engine.setMaster(level);
38908
39033
  },
38909
39034
  dispose() {
38910
- if (!shared) engine.dispose();
39035
+ if (!shared2) engine.dispose();
38911
39036
  }
38912
39037
  };
38913
39038
  }
@@ -39789,10 +39914,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
39789
39914
  materials.push(material);
39790
39915
  return material;
39791
39916
  };
39792
- const mesh3 = (geometry, material, position = [0, 0, 0], rotation = [0, 0, 0], scale) => {
39917
+ const mesh3 = (geometry, material, position = [0, 0, 0], rotation2 = [0, 0, 0], scale) => {
39793
39918
  const object2 = new T2.Mesh(geometry, material);
39794
39919
  object2.position.set(...position);
39795
- object2.rotation.set(...rotation);
39920
+ object2.rotation.set(...rotation2);
39796
39921
  if (scale) object2.scale.set(...scale);
39797
39922
  return object2;
39798
39923
  };
@@ -44069,8 +44194,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44069
44194
  return G(
44070
44195
  mesh3(bx(0.9, 1.3, 0.46), wood(4861979), [0, 0.35, 0]),
44071
44196
  mesh3(bx(0.92, 0.5, 0.5), cloth2(2829099), [0, 0.1, 0]),
44072
- ...limbs.map(([geometry, position, rotation]) => mesh3(geometry, limbMaterial, [...position], [...rotation])),
44073
- ...strings.map(([geometry, position, rotation]) => mesh3(geometry, stringMaterial, [...position], [...rotation]))
44197
+ ...limbs.map(([geometry, position, rotation2]) => mesh3(geometry, limbMaterial, [...position], [...rotation2])),
44198
+ ...strings.map(([geometry, position, rotation2]) => mesh3(geometry, stringMaterial, [...position], [...rotation2]))
44074
44199
  );
44075
44200
  };
44076
44201
  var crossbow = ({ mesh: mesh3, bx, G, wood, metal: metal2, cloth: cloth2 }) => {
@@ -44127,8 +44252,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
44127
44252
  return G(
44128
44253
  mesh3(cyl(0.12, 0.1, 0.65, 8), frame2, [0, -0.425, 0]),
44129
44254
  mesh3(cyl(0.126, 0.126, 0.3, 8), cloth2(8007455), [0, -0.5, 0]),
44130
- ...arms.map(([geometry, position, rotation]) => mesh3(geometry, frame2, [...position], [...rotation])),
44131
- ...bands.map(([geometry, position, rotation]) => mesh3(geometry, band, [...position], [...rotation])),
44255
+ ...arms.map(([geometry, position, rotation2]) => mesh3(geometry, frame2, [...position], [...rotation2])),
44256
+ ...bands.map(([geometry, position, rotation2]) => mesh3(geometry, band, [...position], [...rotation2])),
44132
44257
  mesh3(bx(0.26, 0.2, 0.05), cloth2(9067061), [0, 0.2, 0])
44133
44258
  );
44134
44259
  };
@@ -47728,7 +47853,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
47728
47853
  const standard = (color2, roughness = 0.7, metalness = 0.2, extra = {}) => new THREE.MeshStandardMaterial({ color: color2, roughness, metalness, ...extra });
47729
47854
  const basic = (color2, extra = {}) => new THREE.MeshBasicMaterial({ color: color2, ...extra });
47730
47855
  const additive = { transparent: true, opacity: 0.95, blending: THREE.AdditiveBlending, depthWrite: false };
47731
- return {
47856
+ const materials = {
47732
47857
  metal: standard(3422010, 0.42, 0.75),
47733
47858
  steel: standard(7106418, 0.32, 0.85),
47734
47859
  steelL: standard(9080208, 0.28, 0.9),
@@ -47767,6 +47892,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
47767
47892
  bakelite: standard(6958620, 0.6, 0),
47768
47893
  polyMag: standard(2763302, 0.85, 0)
47769
47894
  };
47895
+ markShared(...Object.values(materials));
47896
+ return materials;
47770
47897
  };
47771
47898
  var kits = /* @__PURE__ */ new WeakMap();
47772
47899
  function modelKit(host) {
@@ -47795,6 +47922,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
47795
47922
  let geometry = geometries.get(key2);
47796
47923
  if (!geometry) {
47797
47924
  geometry = radius > 25e-5 ? createRoundedBoxGeometry(THREE, w, h, d, 2, radius) : new THREE.BoxGeometry(w, h, d);
47925
+ markShared(geometry);
47798
47926
  geometries.set(key2, geometry);
47799
47927
  }
47800
47928
  const mesh3 = place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z);
@@ -51916,11 +52044,231 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
51916
52044
  glow.outIntensity = glow.i * Math.pow(1 - age, glow.curve) * flicker;
51917
52045
  }
51918
52046
  }
52047
+ var LEHMER_MULTIPLIER = 16807;
52048
+ var LEHMER_MODULUS = 2147483647;
52049
+ var HASH_MIX = 2654435761;
52050
+ function normalizeLehmerSeed(seed) {
52051
+ const whole = Math.floor(Math.abs(seed)) % (LEHMER_MODULUS - 1);
52052
+ return whole === 0 ? 1 : whole;
52053
+ }
52054
+ function lehmer(seed) {
52055
+ let state = normalizeLehmerSeed(seed);
52056
+ const next = () => {
52057
+ state = state * LEHMER_MULTIPLIER % LEHMER_MODULUS;
52058
+ return (state - 1) / (LEHMER_MODULUS - 1);
52059
+ };
52060
+ return {
52061
+ next,
52062
+ between: (min2, max2) => min2 + (max2 - min2) * next(),
52063
+ direction(out) {
52064
+ const up = next() * 2 - 1;
52065
+ const angle = next() * Math.PI * 2;
52066
+ const ring22 = Math.sqrt(1 - up * up);
52067
+ out.x = ring22 * Math.cos(angle);
52068
+ out.y = up;
52069
+ out.z = ring22 * Math.sin(angle);
52070
+ return out;
52071
+ },
52072
+ get state() {
52073
+ return state;
52074
+ }
52075
+ };
52076
+ }
52077
+ function mixEventSeed(eventSeed) {
52078
+ let mixed = Math.imul((eventSeed | 0) ^ HASH_MIX, 2246822507);
52079
+ mixed ^= mixed >>> 13;
52080
+ mixed = Math.imul(mixed, 3266489909);
52081
+ mixed ^= mixed >>> 16;
52082
+ return (mixed >>> 0) % (LEHMER_MODULUS - 1) + 1;
52083
+ }
52084
+ function streamFor3(eventSeed) {
52085
+ return lehmer(mixEventSeed(eventSeed));
52086
+ }
52087
+ var SKIN = 5e-3;
52088
+ var MAX_PAD = 0.45;
52089
+ function rotation(q) {
52090
+ const [x, y, z, w] = q ?? [0, 0, 0, 1];
52091
+ const n = Math.hypot(x, y, z, w) || 1;
52092
+ const qx = x / n;
52093
+ const qy = y / n;
52094
+ const qz = z / n;
52095
+ const qw = w / n;
52096
+ return new Float64Array([
52097
+ 1 - 2 * (qy * qy + qz * qz),
52098
+ 2 * (qx * qy - qz * qw),
52099
+ 2 * (qx * qz + qy * qw),
52100
+ 2 * (qx * qy + qz * qw),
52101
+ 1 - 2 * (qx * qx + qz * qz),
52102
+ 2 * (qy * qz - qx * qw),
52103
+ 2 * (qx * qz - qy * qw),
52104
+ 2 * (qy * qz + qx * qw),
52105
+ 1 - 2 * (qx * qx + qy * qy)
52106
+ ]);
52107
+ }
52108
+ var Enclosures = class {
52109
+ constructor(seed = 20973) {
52110
+ __publicField2(this, "spaces", /* @__PURE__ */ new Map());
52111
+ __publicField2(this, "list", []);
52112
+ __publicField2(this, "random");
52113
+ __publicField2(this, "out", { x: 0, y: 0, z: 0, nx: 0, ny: 0, nz: 0 });
52114
+ __publicField2(this, "l0", new Float64Array(3));
52115
+ __publicField2(this, "l1", new Float64Array(3));
52116
+ __publicField2(this, "q", new Float64Array(3));
52117
+ this.random = lehmer(seed);
52118
+ }
52119
+ get empty() {
52120
+ return this.list.length === 0;
52121
+ }
52122
+ get size() {
52123
+ return this.list.length;
52124
+ }
52125
+ /** Declares, moves or (with `null`) ends the space `id`. */
52126
+ set(id, enclosure) {
52127
+ if (!enclosure) {
52128
+ if (this.spaces.delete(id)) this.list = [...this.spaces.values()];
52129
+ return;
52130
+ }
52131
+ const [hx, hy, hz] = enclosure.halfSize;
52132
+ const space = {
52133
+ cx: enclosure.center[0],
52134
+ cy: enclosure.center[1],
52135
+ cz: enclosure.center[2],
52136
+ hx: Math.abs(hx),
52137
+ hy: Math.abs(hy),
52138
+ hz: Math.abs(hz),
52139
+ r: rotation(enclosure.orientation),
52140
+ radius: Math.hypot(hx, hy, hz),
52141
+ openings: enclosure.openings ?? [],
52142
+ leak: Math.max(0, enclosure.leak ?? 0)
52143
+ };
52144
+ const old = this.spaces.get(id);
52145
+ this.spaces.set(id, space);
52146
+ const at3 = old ? this.list.indexOf(old) : -1;
52147
+ if (at3 >= 0) this.list[at3] = space;
52148
+ else this.list.push(space);
52149
+ }
52150
+ get(id) {
52151
+ const s = this.spaces.get(id);
52152
+ if (!s) return void 0;
52153
+ return { center: [s.cx, s.cy, s.cz], halfSize: [s.hx, s.hy, s.hz], openings: s.openings, leak: s.leak };
52154
+ }
52155
+ ids() {
52156
+ return [...this.spaces.keys()];
52157
+ }
52158
+ clear() {
52159
+ this.spaces.clear();
52160
+ this.list = [];
52161
+ }
52162
+ /** Whether a point is inside any space (on the inside of its walls). */
52163
+ inside(x, y, z) {
52164
+ for (const s of this.list) {
52165
+ this.toLocal(s, x, y, z, this.l0);
52166
+ if (Math.abs(this.l0[0]) <= s.hx && Math.abs(this.l0[1]) <= s.hy && Math.abs(this.l0[2]) <= s.hz) return true;
52167
+ }
52168
+ return false;
52169
+ }
52170
+ toLocal(s, x, y, z, out) {
52171
+ const dx = x - s.cx;
52172
+ const dy = y - s.cy;
52173
+ const dz = z - s.cz;
52174
+ const r = s.r;
52175
+ out[0] = r[0] * dx + r[3] * dy + r[6] * dz;
52176
+ out[1] = r[1] * dx + r[4] * dy + r[7] * dz;
52177
+ out[2] = r[2] * dx + r[5] * dy + r[8] * dz;
52178
+ }
52179
+ /** Passes at `rate` per second. */
52180
+ chance(rate, dt) {
52181
+ return rate > 0 && this.random.next() < 1 - Math.exp(-rate * dt);
52182
+ }
52183
+ /** The opening the wall point `q` (local) is in lets it through now. */
52184
+ through(s, q, dt) {
52185
+ for (const o of s.openings) {
52186
+ if (Math.abs(q[0] - o.center[0]) > o.halfSize[0] || Math.abs(q[1] - o.center[1]) > o.halfSize[1] || Math.abs(q[2] - o.center[2]) > o.halfSize[2]) continue;
52187
+ if (o.rate === void 0 || this.chance(o.rate, dt)) return true;
52188
+ }
52189
+ return this.chance(s.leak, dt);
52190
+ }
52191
+ confine(x0, y0, z0, x1, y1, z1, pad, dt) {
52192
+ const list2 = this.list;
52193
+ if (list2.length === 0) return false;
52194
+ const p = Math.min(Math.max(0, pad), MAX_PAD);
52195
+ const l0 = this.l0;
52196
+ const l1 = this.l1;
52197
+ const q = this.q;
52198
+ for (const s of list2) {
52199
+ const reach = s.radius + p + 0.05;
52200
+ const dx = x1 - s.cx;
52201
+ const dy = y1 - s.cy;
52202
+ const dz = z1 - s.cz;
52203
+ if (dx * dx + dy * dy + dz * dz > reach * reach) {
52204
+ const ex = x0 - s.cx;
52205
+ const ey = y0 - s.cy;
52206
+ const ez = z0 - s.cz;
52207
+ if (ex * ex + ey * ey + ez * ez > reach * reach) continue;
52208
+ }
52209
+ this.toLocal(s, x0, y0, z0, l0);
52210
+ this.toLocal(s, x1, y1, z1, l1);
52211
+ const h = [s.hx, s.hy, s.hz];
52212
+ const in0 = Math.abs(l0[0]) <= s.hx && Math.abs(l0[1]) <= s.hy && Math.abs(l0[2]) <= s.hz;
52213
+ let axis2 = 0;
52214
+ let sign2 = 1;
52215
+ if (in0) {
52216
+ if (Math.abs(l1[0]) <= s.hx && Math.abs(l1[1]) <= s.hy && Math.abs(l1[2]) <= s.hz) continue;
52217
+ for (let a = 0; a < 3; a++) q[a] = Math.min(h[a], Math.max(-h[a], l1[a]));
52218
+ if (this.through(s, q, dt)) continue;
52219
+ let worst = -Infinity;
52220
+ for (let a = 0; a < 3; a++) {
52221
+ const over = Math.abs(l1[a]) - h[a];
52222
+ if (over > worst) {
52223
+ worst = over;
52224
+ axis2 = a;
52225
+ }
52226
+ }
52227
+ sign2 = l1[axis2] < 0 ? -1 : 1;
52228
+ for (let a = 0; a < 3; a++) l1[a] = Math.min(h[a] - SKIN, Math.max(-(h[a] - SKIN), l1[a]));
52229
+ sign2 = -sign2;
52230
+ } else {
52231
+ const padded0 = Math.abs(l0[0]) <= s.hx + p && Math.abs(l0[1]) <= s.hy + p && Math.abs(l0[2]) <= s.hz + p;
52232
+ const bound = padded0 ? 0 : p;
52233
+ if (!(Math.abs(l1[0]) <= s.hx + bound && Math.abs(l1[1]) <= s.hy + bound && Math.abs(l1[2]) <= s.hz + bound)) continue;
52234
+ for (let a = 0; a < 3; a++) q[a] = Math.min(h[a], Math.max(-h[a], l1[a]));
52235
+ if (this.through(s, q, dt)) continue;
52236
+ let worst = -Infinity;
52237
+ for (let a = 0; a < 3; a++) {
52238
+ const over = Math.abs(l0[a]) - (h[a] + bound);
52239
+ if (over > worst) {
52240
+ worst = over;
52241
+ axis2 = a;
52242
+ }
52243
+ }
52244
+ sign2 = l0[axis2] < 0 ? -1 : 1;
52245
+ l1[axis2] = sign2 * (h[axis2] + bound + SKIN);
52246
+ }
52247
+ const r = s.r;
52248
+ const out = this.out;
52249
+ out.x = s.cx + r[0] * l1[0] + r[1] * l1[1] + r[2] * l1[2];
52250
+ out.y = s.cy + r[3] * l1[0] + r[4] * l1[1] + r[5] * l1[2];
52251
+ out.z = s.cz + r[6] * l1[0] + r[7] * l1[1] + r[8] * l1[2];
52252
+ out.nx = r[axis2] * sign2;
52253
+ out.ny = r[3 + axis2] * sign2;
52254
+ out.nz = r[6 + axis2] * sign2;
52255
+ return true;
52256
+ }
52257
+ return false;
52258
+ }
52259
+ };
52260
+ function slideAlong(out, vx2, vy2, vz2) {
52261
+ const into = vx2 * out.nx + vy2 * out.ny + vz2 * out.nz;
52262
+ if (into >= 0) return [vx2, vy2, vz2];
52263
+ return [vx2 - into * out.nx, vy2 - into * out.ny, vz2 - into * out.nz];
52264
+ }
51919
52265
  var FLOOR_FRACTION = 0.4;
51920
52266
  var FLOOR_BOUNCE = -0.2;
51921
52267
  var ARRIVAL_FRAME = 30;
51922
52268
  var ARRIVAL_BASE = 0.3;
51923
52269
  var GROWTH_CAP_SECONDS = 3.5;
52270
+ var CARRIED_KINDS = [true, true, false, true, false];
52271
+ var PAD_OF_SIZE = 0.35;
51924
52272
  function createPuffPool(capacity) {
51925
52273
  const placeholder = { next: () => 0, between: (min2) => min2, direction: (out) => out, state: 0 };
51926
52274
  return new OrderedPool(capacity, () => ({
@@ -52015,13 +52363,24 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
52015
52363
  if (puff3.vy < 0) puff3.vy *= FLOOR_BOUNCE;
52016
52364
  }
52017
52365
  }
52018
- function updatePuffs(pool, dt, wind) {
52366
+ function updatePuffs(pool, dt, wind, confiner) {
52019
52367
  pool.compact(ageOrKeep2, dt);
52368
+ const confining = confiner !== void 0 && !confiner.empty;
52020
52369
  for (const puff3 of pool.items) {
52021
52370
  const age = puff3.t / puff3.life;
52022
52371
  const heat = puff3.h0 > 0 ? puff3.h0 * Math.pow(Math.max(0, 1 - puff3.t / puff3.hl), 1.25) : 0;
52372
+ const x0 = puff3.x;
52373
+ const y0 = puff3.y;
52374
+ const z0 = puff3.z;
52023
52375
  if (puff3.ring) moveOnRing(puff3, puff3.ring, wind);
52024
52376
  else moveFree(puff3, dt, age, heat, wind);
52377
+ if (confining && CARRIED_KINDS[puff3.kind] && confiner.confine(x0, y0, z0, puff3.x, puff3.y, puff3.z, puff3.size * PAD_OF_SIZE, dt)) {
52378
+ const out = confiner.out;
52379
+ puff3.x = out.x;
52380
+ puff3.y = out.y;
52381
+ puff3.z = out.z;
52382
+ [puff3.vx, puff3.vy, puff3.vz] = slideAlong(out, puff3.vx, puff3.vy, puff3.vz);
52383
+ }
52025
52384
  const size = puff3.s0 + (puff3.s1 - puff3.s0) * (1 - Math.exp(-puff3.t * puff3.gk)) + puff3.sg * Math.min(puff3.t, GROWTH_CAP_SECONDS);
52026
52385
  puff3.size = size * Math.min(1, puff3.t * ARRIVAL_FRAME + ARRIVAL_BASE);
52027
52386
  puff3.age = age;
@@ -52547,10 +52906,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
52547
52906
  ])
52548
52907
  ]
52549
52908
  };
52550
- function localToWorld(translation, rotation, local2) {
52909
+ function localToWorld(translation, rotation2, local2) {
52551
52910
  const [x, y, z] = local2;
52552
- const [a, c, e] = [Math.cos(rotation[0]), Math.cos(rotation[1]), Math.cos(rotation[2])];
52553
- const [b, d, f] = [Math.sin(rotation[0]), Math.sin(rotation[1]), Math.sin(rotation[2])];
52911
+ const [a, c, e] = [Math.cos(rotation2[0]), Math.cos(rotation2[1]), Math.cos(rotation2[2])];
52912
+ const [b, d, f] = [Math.sin(rotation2[0]), Math.sin(rotation2[1]), Math.sin(rotation2[2])];
52554
52913
  const [ae, af, be, bf] = [a * e, a * f, b * e, b * f];
52555
52914
  return [
52556
52915
  c * e * x + -c * f * y + d * z + translation[0],
@@ -54213,46 +54572,6 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
54213
54572
  var ALL_EFFECTS = [BLOOD_HIT, HEADSHOT, DISMEMBER, BLOATER_CLOUD, SCREAMER_SHRIEK, CORPSE_DECAY, REANIMATION, EYES_IN_FOG, MUZZLE_FLASH, IMPACT_BY_MATERIAL, PENETRATION, CASINGS_AND_MAGAZINE, MOLOTOV, GRENADE, EXPLOSIVE_BARREL, SHOPFRONT_GLASS, DOOR_STAGES, BUILDING_COLLAPSE, BLOCK_WALL, METAL_DOOR_EFFECT, IRON_RAILING, WOODEN_FENCE, HIT_POINT_BREAKAGE, PRESSURE_CYLINDERS, BUILDING_FIRE, RAIN_AND_PUDDLES, FOG_AND_ASH, SCRAPING_SPARKS, ENGINE_SMOKE, FUEL_LEAK, CAR_EXPLOSION, WINDSHIELD, HEADLIGHTS_IN_RAIN, DAMAGE_AND_BITE, INFECTION_PHASES, PANIC, BLOATER_BLINDNESS, CAMPFIRE, COUGH_AND_BREATH];
54214
54573
  var WORKSHOP_EFFECTS = Object.fromEntries(ALL_EFFECTS.map((effect) => [effect.id, effect]));
54215
54574
  var GAME_EFFECTS = { ...WORKSHOP_EFFECTS, ...Object.fromEntries([...EVENT_EFFECTS, ...VIEWMODEL_EFFECTS, ...VEHICLE_EFFECTS].map((effect) => [effect.id, effect])) };
54216
- var LEHMER_MULTIPLIER = 16807;
54217
- var LEHMER_MODULUS = 2147483647;
54218
- var HASH_MIX = 2654435761;
54219
- function normalizeLehmerSeed(seed) {
54220
- const whole = Math.floor(Math.abs(seed)) % (LEHMER_MODULUS - 1);
54221
- return whole === 0 ? 1 : whole;
54222
- }
54223
- function lehmer(seed) {
54224
- let state = normalizeLehmerSeed(seed);
54225
- const next = () => {
54226
- state = state * LEHMER_MULTIPLIER % LEHMER_MODULUS;
54227
- return (state - 1) / (LEHMER_MODULUS - 1);
54228
- };
54229
- return {
54230
- next,
54231
- between: (min2, max2) => min2 + (max2 - min2) * next(),
54232
- direction(out) {
54233
- const up = next() * 2 - 1;
54234
- const angle = next() * Math.PI * 2;
54235
- const ring22 = Math.sqrt(1 - up * up);
54236
- out.x = ring22 * Math.cos(angle);
54237
- out.y = up;
54238
- out.z = ring22 * Math.sin(angle);
54239
- return out;
54240
- },
54241
- get state() {
54242
- return state;
54243
- }
54244
- };
54245
- }
54246
- function mixEventSeed(eventSeed) {
54247
- let mixed = Math.imul((eventSeed | 0) ^ HASH_MIX, 2246822507);
54248
- mixed ^= mixed >>> 13;
54249
- mixed = Math.imul(mixed, 3266489909);
54250
- mixed ^= mixed >>> 16;
54251
- return (mixed >>> 0) % (LEHMER_MODULUS - 1) + 1;
54252
- }
54253
- function streamFor3(eventSeed) {
54254
- return lehmer(mixEventSeed(eventSeed));
54255
- }
54256
54575
  var TABLE = {
54257
54576
  concrete: { dust: 9078138, chip: 7236195, spark: 2 },
54258
54577
  metal: { dust: 0, chip: 0, spark: 18 },
@@ -55355,12 +55674,12 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
55355
55674
  }
55356
55675
  function drawing(entry2, action) {
55357
55676
  const context = engine.context;
55358
- const shared = context.random;
55677
+ const shared2 = context.random;
55359
55678
  if (entry2.random) context.random = entry2.random;
55360
55679
  try {
55361
55680
  action();
55362
55681
  } finally {
55363
- context.random = shared;
55682
+ context.random = shared2;
55364
55683
  }
55365
55684
  }
55366
55685
  return {
@@ -55556,8 +55875,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
55556
55875
  function addScorch(store, random, x, z, radius) {
55557
55876
  const variant = Math.floor(random.next() * SCORCH_VARIANTS);
55558
55877
  const lift = 0.03 + nextLift(store) * 1e-3;
55559
- const rotation = random.next() * 6;
55560
- store.add({ kind: "scorch", x, z, radius, variant, lift, rotation });
55878
+ const rotation2 = random.next() * 6;
55879
+ store.add({ kind: "scorch", x, z, radius, variant, lift, rotation: rotation2 });
55561
55880
  }
55562
55881
  function addRimRocks(store, ground, random, x, z, radius) {
55563
55882
  const count = Math.round(6 + radius * 7);
@@ -55586,8 +55905,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
55586
55905
  function addCrater(store, ground, random, spec) {
55587
55906
  ground?.dent(random, spec.x, spec.z, spec.radius, spec.depth);
55588
55907
  if (!spec.marks) return;
55589
- const rotation = random.next() * 6;
55590
- store.add({ kind: "dirt", x: spec.x, z: spec.z, radius: spec.radius * 1.02, lift: 0.045, rotation });
55908
+ const rotation2 = random.next() * 6;
55909
+ store.add({ kind: "dirt", x: spec.x, z: spec.z, radius: spec.radius * 1.02, lift: 0.045, rotation: rotation2 });
55591
55910
  addRimRocks(store, ground, random, spec.x, spec.z, spec.radius);
55592
55911
  }
55593
55912
  function addBloodSplat(store, ground, random, spec) {
@@ -56143,6 +56462,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56143
56462
  state.gas = Math.max(0, state.gas - dt / DECAY.gasSeconds);
56144
56463
  state.beat *= Math.exp(-DECAY.beat * dt);
56145
56464
  }
56465
+ var PAD_OF_SIZE2 = 0.35;
56146
56466
  var clamp4 = (v, lo, hi) => v < lo ? lo : v > hi ? hi : v;
56147
56467
  var lerp4 = (a, b, t) => a + (b - a) * t;
56148
56468
  function rgb(hex2) {
@@ -56302,9 +56622,20 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56302
56622
  vy2 *= k;
56303
56623
  vz2 *= k;
56304
56624
  }
56305
- const x = this.position[i3] + vx2 * dt;
56625
+ let x = this.position[i3] + vx2 * dt;
56306
56626
  let y = this.position[i3 + 1] + vy2 * dt;
56307
- const z = this.position[i3 + 2] + vz2 * dt;
56627
+ let z = this.position[i3 + 2] + vz2 * dt;
56628
+ const confiner = host.confiner;
56629
+ if (def.carried && confiner && !confiner.empty) {
56630
+ const pad = this.size0[i] * lerp4(1, def.grow, t) * PAD_OF_SIZE2;
56631
+ if (confiner.confine(this.position[i3], this.position[i3 + 1], this.position[i3 + 2], x, y, z, pad, dt)) {
56632
+ const out = confiner.out;
56633
+ x = out.x;
56634
+ y = out.y;
56635
+ z = out.z;
56636
+ [vx2, vy2, vz2] = slideAlong(out, vx2, vy2, vz2);
56637
+ }
56638
+ }
56308
56639
  if (def.ground !== "none") {
56309
56640
  const own = this.floor[i];
56310
56641
  const gy = Number.isNaN(own) ? host.groundAt(x, z) + 5e-3 : own;
@@ -56390,7 +56721,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56390
56721
  alpha: 0.35,
56391
56722
  fadeIn: 0.15,
56392
56723
  cone: 0.6,
56393
- ground: "none"
56724
+ ground: "none",
56725
+ carried: true
56394
56726
  },
56395
56727
  sparks: {
56396
56728
  id: "sparks",
@@ -56434,7 +56766,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56434
56766
  alpha: 0.4,
56435
56767
  fadeIn: 0.1,
56436
56768
  cone: 0.4,
56437
- ground: "none"
56769
+ ground: "none",
56770
+ carried: true
56438
56771
  },
56439
56772
  shards: {
56440
56773
  id: "shards",
@@ -56592,7 +56925,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56592
56925
  fadeIn: 0.1,
56593
56926
  cone: 0.5,
56594
56927
  ground: "stop",
56595
- flutter: 0.6
56928
+ flutter: 0.6,
56929
+ carried: true
56596
56930
  },
56597
56931
  steam: {
56598
56932
  id: "steam",
@@ -56614,7 +56948,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56614
56948
  alpha: 0.35,
56615
56949
  fadeIn: 0.15,
56616
56950
  cone: 0.6,
56617
- ground: "none"
56951
+ ground: "none",
56952
+ carried: true
56618
56953
  },
56619
56954
  flash: {
56620
56955
  id: "flash",
@@ -56747,7 +57082,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56747
57082
  const host = {
56748
57083
  groundAt: this.options.groundAt,
56749
57084
  gravity: this.options.gravity,
56750
- land: (owner, x, y, z, color2, tag) => this.listeners.get(owner)?.(x, y, z, color2, tag)
57085
+ land: (owner, x, y, z, color2, tag) => this.listeners.get(owner)?.(x, y, z, color2, tag),
57086
+ ...this.options.confiner ? { confiner: this.options.confiner } : {}
56751
57087
  };
56752
57088
  if (this.additive.live > 0 || this.additive.drawCount > 0) this.additive.update(dt, host);
56753
57089
  if (this.normal.live > 0 || this.normal.drawCount > 0) this.normal.update(dt, host);
@@ -56953,8 +57289,8 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
56953
57289
  * Takes away the marks inside a box: world `center`, `half` extents along the axes of the world `rotation` (a quaternion, x y z w; none means the
56954
57290
  * world axes). The surface they were on is gone (a brick came out of a wall with its bullet holes). Returns how many went.
56955
57291
  */
56956
- clearInside(center, half, rotation = [0, 0, 0, 1]) {
56957
- const qx = -rotation[0], qy = -rotation[1], qz = -rotation[2], qw = rotation[3];
57292
+ clearInside(center, half, rotation2 = [0, 0, 0, 1]) {
57293
+ const qx = -rotation2[0], qy = -rotation2[1], qz = -rotation2[2], qw = rotation2[3];
56958
57294
  let gone = 0;
56959
57295
  for (const decal2 of this.decals) {
56960
57296
  if (!decal2.on) continue;
@@ -57075,10 +57411,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57075
57411
  var DEFAULT_FADE_IN = 0.1;
57076
57412
  var FLOATS_PER_VECTOR = 3;
57077
57413
  var BYTE_MAX2 = 255;
57414
+ var CARRIED_GRAVITY = 3;
57415
+ var PAD_OF_SIZE3 = 0.35;
57078
57416
  var SpritePool = class {
57079
- constructor(capacity, context) {
57417
+ /** `carried`: the normal-blend pool (smoke, dust, steam), whose light sprites go round the closed spaces; the additive one (flames, sparks) does not. */
57418
+ constructor(capacity, context, carried = false) {
57080
57419
  __publicField2(this, "capacity", capacity);
57081
57420
  __publicField2(this, "context", context);
57421
+ __publicField2(this, "carried", carried);
57082
57422
  __publicField2(this, "count", 0);
57083
57423
  __publicField2(this, "position");
57084
57424
  __publicField2(this, "velocity");
@@ -57178,6 +57518,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57178
57518
  }
57179
57519
  update(dt, leaveDecal) {
57180
57520
  const { position, velocity } = this;
57521
+ const confiner = this.context.confiner;
57181
57522
  for (let index = this.count - 1; index >= 0; index--) {
57182
57523
  this.life[index] -= dt;
57183
57524
  if (this.life[index] <= 0) {
@@ -57191,9 +57532,25 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57191
57532
  velocity[offset] *= factor;
57192
57533
  velocity[offset + 1] *= factor;
57193
57534
  velocity[offset + 2] *= factor;
57535
+ const x0 = position[offset];
57536
+ const y0 = position[offset + 1];
57537
+ const z0 = position[offset + 2];
57194
57538
  position[offset] += velocity[offset] * dt;
57195
57539
  position[offset + 1] += velocity[offset + 1] * dt;
57196
57540
  position[offset + 2] += velocity[offset + 2] * dt;
57541
+ if (this.carried && confiner && !confiner.empty && Math.abs(this.gravity[index]) < CARRIED_GRAVITY) {
57542
+ const size = this.startSize[index] * (1 + (this.growth[index] - 1) * age);
57543
+ if (confiner.confine(x0, y0, z0, position[offset], position[offset + 1], position[offset + 2], size * PAD_OF_SIZE3, dt)) {
57544
+ const out = confiner.out;
57545
+ position[offset] = out.x;
57546
+ position[offset + 1] = out.y;
57547
+ position[offset + 2] = out.z;
57548
+ const [vx2, vy2, vz2] = slideAlong(out, velocity[offset], velocity[offset + 1], velocity[offset + 2]);
57549
+ velocity[offset] = vx2;
57550
+ velocity[offset + 1] = vy2;
57551
+ velocity[offset + 2] = vz2;
57552
+ }
57553
+ }
57197
57554
  const mode = this.groundMode[index];
57198
57555
  if (mode) {
57199
57556
  const groundHeight = this.context.groundAt(position[offset], position[offset + 2]);
@@ -57470,9 +57827,9 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57470
57827
  __publicField2(this, "placement");
57471
57828
  __publicField2(this, "accumulators", /* @__PURE__ */ new Map());
57472
57829
  const profile = options.profile ?? PROFILES.high;
57473
- this.context = { random: options.random, groundAt: options.groundAt ?? workshopGround, quality: { level: 0, mult: 1 }, trace: options.trace };
57830
+ this.context = { random: options.random, groundAt: options.groundAt ?? workshopGround, quality: { level: 0, mult: 1 }, trace: options.trace, ...options.confiner ? { confiner: options.confiner } : {} };
57474
57831
  this.add = new SpritePool(profile.sprites.add, this.context);
57475
- this.normal = new SpritePool(profile.sprites.normal, this.context);
57832
+ this.normal = new SpritePool(profile.sprites.normal, this.context, true);
57476
57833
  this.streaks = new StreakPool(profile.streaks, this.context);
57477
57834
  this.debris = new DebrisPool(this.context);
57478
57835
  this.decals = new DecalPool(this.context);
@@ -57660,12 +58017,14 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57660
58017
  const groundAt = options.groundAt ?? (ground ? (x, z) => ground.heightAt(x, z) : () => 0);
57661
58018
  const handles = { next: 0, events: 0 };
57662
58019
  const low = options.profile === "low";
58020
+ const enclosures = new Enclosures(20973 + (options.seed ?? 0));
57663
58021
  const spriteSystem = new SpriteKindSystem({
57664
58022
  capacity: options.sprites?.capacity ?? (low ? 1250 : 2500),
57665
58023
  density: options.sprites?.density ?? (low ? 0.6 : 1),
57666
58024
  seed: 2654435761 + (options.seed ?? 0),
57667
58025
  groundAt,
57668
58026
  gravity: options.gravity ?? DEFAULT_GRAVITY,
58027
+ confiner: enclosures,
57669
58028
  ...options.sprites?.kinds ? { kinds: options.sprites.kinds } : {}
57670
58029
  });
57671
58030
  const core = {
@@ -57715,7 +58074,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57715
58074
  return [camera2.x, camera2.y, camera2.z];
57716
58075
  }, forward: (local2) => [local2[0] ?? 0, local2[1] ?? 0, local2[2] ?? 0] };
57717
58076
  function workshop() {
57718
- return engine ?? (engine = new WorkshopEngine({ random: sharedRandom, profile, groundAt }));
58077
+ return engine ?? (engine = new WorkshopEngine({ random: sharedRandom, profile, groundAt, confiner: enclosures }));
57719
58078
  }
57720
58079
  function effectPlayer() {
57721
58080
  return player ?? (player = createEffectPlayer({ engine: workshop(), effects, view }));
@@ -57774,6 +58133,10 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57774
58133
  puff3.vz += dz * strength;
57775
58134
  }
57776
58135
  },
58136
+ enclose(id, enclosure) {
58137
+ enclosures.set(id, enclosure);
58138
+ },
58139
+ enclosures: () => enclosures,
57777
58140
  stop(handle) {
57778
58141
  player?.stop(handle);
57779
58142
  const fires = core.fires;
@@ -57801,7 +58164,7 @@ uniform mat4 uNodes[${nodes.length}]; attribute float aNodeIndex; attribute vec3
57801
58164
  core.clock.time += dt;
57802
58165
  core.schedule.update(core.clock.time);
57803
58166
  updateRings(core.rings, dt);
57804
- updatePuffs(core.puffs, dt, wind);
58167
+ updatePuffs(core.puffs, dt, wind, enclosures);
57805
58168
  updateSparks(core.sparks, { dt, groundAt });
57806
58169
  updateGlows(core.glows, dt);
57807
58170
  updateShocks(core.shocks, core.puffs.items, dt);
@@ -59185,6 +59548,8 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
59185
59548
  });
59186
59549
  },
59187
59550
  stop: (handle) => world.stop(handle),
59551
+ // a module's closed space (a shut car's cabin): the world's smoke, dust and steam go round it
59552
+ enclose: (id, enclosure) => world.enclose(id, enclosure),
59188
59553
  configure(settings) {
59189
59554
  const band = settings.lod_band;
59190
59555
  if (typeof band === "string" && band in LOD_BANDS) world.forceLod(LOD_BANDS[band] ?? null);
@@ -59331,7 +59696,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
59331
59696
  if (random() < 0.9) context.effects.smoke(rocket.position.clone().addScaledVector(forward, -0.12), new THREE.Vector3((random() - 0.5) * 0.1, 0.05, (random() - 0.5) * 0.1), 0.02 + random() * 0.015, 2.2, 0.5);
59332
59697
  },
59333
59698
  () => {
59334
- rocket.removeFromParent();
59699
+ discardObject3D(rocket);
59335
59700
  exhaust.geometry.dispose();
59336
59701
  exhaust.material.dispose();
59337
59702
  const remaining = (rocketsInFlight.get(light) ?? 1) - 1;
@@ -59668,7 +60033,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
59668
60033
  session.model.inner.add(shell);
59669
60034
  shell.position.set(-0.25, 0, 0);
59670
60035
  world.schedule(0.02, 0.4, (eased) => shell.position.x = -0.25 + 0.6 * eased, () => {
59671
- shell.removeFromParent();
60036
+ discardObject3D(shell);
59672
60037
  });
59673
60038
  }
59674
60039
  }
@@ -60226,7 +60591,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
60226
60591
  const release = () => {
60227
60592
  if (!session) return;
60228
60593
  session.attachments?.dispose();
60229
- session.model.root.removeFromParent();
60594
+ discardObject3D(session.model.root);
60230
60595
  player = null;
60231
60596
  session = null;
60232
60597
  tasks = [];
@@ -62137,7 +62502,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
62137
62502
  vessel.rings = group;
62138
62503
  };
62139
62504
  const clearRings = (vessel) => {
62140
- vessel.rings?.removeFromParent();
62505
+ if (vessel.rings) discardObject3D(vessel.rings);
62141
62506
  vessel.rings = void 0;
62142
62507
  };
62143
62508
  const phaseOf = (vessel) => {
@@ -62226,7 +62591,7 @@ void main(){vec2 d=gl_PointCoord-.5;float r=length(d)*2.;if(r>1.)discard;float a
62226
62591
  }
62227
62592
  };
62228
62593
  const clearShells = () => {
62229
- for (const shell of shells) shell.mesh.removeFromParent();
62594
+ discardObject3D(shells.map((shell) => shell.mesh));
62230
62595
  shells.length = 0;
62231
62596
  };
62232
62597
  const fullVitality = /* @__PURE__ */ new Map();