viral-viewer-2 7.2.7 → 7.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -125,7 +125,7 @@ class D {
125
125
  const Yi = D.hexToRGB(y.secondary), Xi = 0.99;
126
126
  class ee extends x {
127
127
  constructor(e, t, i) {
128
- super(e, t), this.globalMaterialIndex = -1, this.workerPool = null, this._depthPrePassMesh = null, this._bufferElements = [], this._colors = null, this._originalColor = null, this._elementMap = /* @__PURE__ */ new Map(), this._isBatching = !1, this._batchQueue = [], this._isProcessingQueue = !1, this._edgeLines = null, this._edgeRanges = /* @__PURE__ */ new Map(), this._edgeThreshold = 60, this._edgeMaterial = null, this._selectedElements = [], this._hidingElements = [], this._isolatingElements = [], this._hiddenSet = /* @__PURE__ */ new Set(), this._isolatedSet = /* @__PURE__ */ new Set(), this._elementOpacityMap = /* @__PURE__ */ new Map(), this._isRGBAMode = !1, this._elementOriginalColors = /* @__PURE__ */ new Map(), this._temporaryColors = /* @__PURE__ */ new Map(), this._isGeneratedLights = !1, this._pointLight = null, this.workerPool = i || null;
128
+ super(e, t), this.globalMaterialIndex = -1, this.workerPool = null, this._depthPrePassMesh = null, this._bufferElements = [], this._colors = null, this._originalColor = null, this._elementMap = /* @__PURE__ */ new Map(), this._isBatching = !1, this._batchQueue = [], this._isProcessingQueue = !1, this._edgeLines = null, this._edgeRanges = /* @__PURE__ */ new Map(), this._edgeThreshold = 60, this._edgeMaterial = null, this._selectedElements = [], this._hidingElements = [], this._isolatingElements = [], this._hiddenSet = /* @__PURE__ */ new Set(), this._isolatedSet = /* @__PURE__ */ new Set(), this._elementOpacityMap = /* @__PURE__ */ new Map(), this._isRGBAMode = !1, this._elementOriginalColors = /* @__PURE__ */ new Map(), this._temporaryColors = /* @__PURE__ */ new Map(), this._ghostColors = /* @__PURE__ */ new Map(), this._isGeneratedLights = !1, this._pointLight = null, this.workerPool = i || null;
129
129
  }
130
130
  addBufferElements(e, t) {
131
131
  this._bufferElements = e, this._originalColor = t, this.rebuildGeometry(e);
@@ -144,14 +144,14 @@ class ee extends x {
144
144
  continue;
145
145
  const p = u.length / 3, m = [];
146
146
  this._elementMap.has(d.modelId.toString()) || this._elementMap.set(d.modelId.toString(), /* @__PURE__ */ new Map());
147
- const f = o;
147
+ const g = o;
148
148
  for (let b = 0; b < p; b++)
149
149
  s[a++] = u[b * 3], s[a++] = u[b * 3 + 1], s[a++] = u[b * 3 + 2], this._originalColor && (r[l++] = this._originalColor.r, r[l++] = this._originalColor.g, r[l++] = this._originalColor.b, r[l++] = 1);
150
150
  for (let b = 0; b < p - 2; b += 3)
151
151
  n[c++] = o + b, n[c++] = o + b + 1, n[c++] = o + b + 2, m.push(o + b, o + b + 1, o + b + 2);
152
152
  const v = this._elementMap.get(d.modelId.toString());
153
153
  v.has(d.elementId) || v.set(d.elementId, []), v.get(d.elementId).push({
154
- start: f,
154
+ start: g,
155
155
  count: p,
156
156
  indices: m
157
157
  }), o += p;
@@ -183,7 +183,7 @@ class ee extends x {
183
183
  else
184
184
  for (let v = 0; v < n; v++)
185
185
  h[v * 4] = i.array[v * 3], h[v * 4 + 1] = i.array[v * 3 + 1], h[v * 4 + 2] = i.array[v * 3 + 2], h[v * 4 + 3] = 1;
186
- let u = n * 3, p = n * 4, m = n, f = r;
186
+ let u = n * 3, p = n * 4, m = n, g = r;
187
187
  e.forEach((v) => {
188
188
  if (!v.buffer)
189
189
  return;
@@ -193,7 +193,7 @@ class ee extends x {
193
193
  for (let C = 0; C < b; C++)
194
194
  c[u++] = v.buffer[C * 3], c[u++] = v.buffer[C * 3 + 1], c[u++] = v.buffer[C * 3 + 2], this._originalColor && (h[p++] = this._originalColor.r, h[p++] = this._originalColor.g, h[p++] = this._originalColor.b, h[p++] = 1);
195
195
  for (let C = 0; C < b - 2; C += 3)
196
- d[f++] = m + C, d[f++] = m + C + 1, d[f++] = m + C + 2, w.push(m + C, m + C + 1, m + C + 2);
196
+ d[g++] = m + C, d[g++] = m + C + 1, d[g++] = m + C + 2, w.push(m + C, m + C + 1, m + C + 2);
197
197
  const A = this._elementMap.get(v.modelId.toString());
198
198
  A.has(v.elementId) || A.set(v.elementId, []), A.get(v.elementId).push({
199
199
  start: S,
@@ -361,10 +361,10 @@ class ee extends x {
361
361
  const d = new Mt(l, this._edgeThreshold), u = d.getAttribute("position");
362
362
  i.set(u.array, s * 3);
363
363
  const p = s, m = u.count;
364
- let f = this._edgeRanges.get(o.modelId.toString());
365
- f || (f = /* @__PURE__ */ new Map(), this._edgeRanges.set(o.modelId.toString(), f));
366
- const v = f.get(o.elementId) ?? [];
367
- v.push({ start: p, count: m }), f.set(o.elementId, v), s += m, d.dispose(), l.dispose();
364
+ let g = this._edgeRanges.get(o.modelId.toString());
365
+ g || (g = /* @__PURE__ */ new Map(), this._edgeRanges.set(o.modelId.toString(), g));
366
+ const v = g.get(o.elementId) ?? [];
367
+ v.push({ start: p, count: m }), g.set(o.elementId, v), s += m, d.dispose(), l.dispose();
368
368
  }
369
369
  const n = new Uint32Array(e);
370
370
  for (let o = 0; o < e; o++)
@@ -583,33 +583,45 @@ class ee extends x {
583
583
  return this._elementOpacityMap.get(i) ?? 1;
584
584
  }
585
585
  /**
586
- * Ghost mode - semi-transparent with optional desaturation
586
+ * Ghost mode - semi-transparent with optional desaturation or custom color
587
587
  * Perfect for showing context while highlighting other elements
588
588
  *
589
589
  * @param elements - Elements to ghost
590
590
  * @param ghostOpacity - Opacity for ghost mode (default: 0.15)
591
- * @param desaturate - Whether to desaturate color (default: true)
591
+ * @param desaturate - Whether to desaturate color (default: true) - ignored if ghostColor is provided
592
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
592
593
  */
593
- setElementGhost(e, t = 0.15, i = !0) {
594
+ setElementGhost(e, t = 0.15, i = !0, s) {
594
595
  if (!this._colors)
595
596
  return;
596
- e.forEach(({ modelId: n, elementId: r }) => {
597
- var l;
598
- const o = `${n}:${r}`;
599
- this._elementOpacityMap.set(o, t);
600
- const a = (l = this._elementMap.get(n)) == null ? void 0 : l.get(r);
601
- if (a)
602
- for (const c of a)
603
- for (let h = 0; h < c.count; h++) {
604
- const d = (c.start + h) * 4;
605
- if (this._colors[d + 3] = t, i) {
606
- const u = (this._colors[d] + this._colors[d + 1] + this._colors[d + 2]) / 3, p = 0.7;
607
- this._colors[d] = this._colors[d] * (1 - p) + u * p, this._colors[d + 1] = this._colors[d + 1] * (1 - p) + u * p, this._colors[d + 2] = this._colors[d + 2] * (1 - p) + u * p;
608
- }
609
- }
597
+ e.forEach(({ modelId: r, elementId: o }) => {
598
+ var h;
599
+ const a = `${r}:${o}`;
600
+ this._elementOpacityMap.set(a, t);
601
+ const l = (h = this._elementMap.get(r)) == null ? void 0 : h.get(o);
602
+ if (!l)
603
+ return;
604
+ let c;
605
+ if (s)
606
+ c = s;
607
+ else if (i && this._originalColor) {
608
+ const d = (this._originalColor.r + this._originalColor.g + this._originalColor.b) / 3, u = 0.7;
609
+ c = {
610
+ r: this._originalColor.r * (1 - u) + d * u,
611
+ g: this._originalColor.g * (1 - u) + d * u,
612
+ b: this._originalColor.b * (1 - u) + d * u
613
+ };
614
+ } else
615
+ c = this._originalColor || { r: 0.5, g: 0.5, b: 0.5 };
616
+ this._ghostColors.set(a, c);
617
+ for (const d of l)
618
+ for (let u = 0; u < d.count; u++) {
619
+ const p = (d.start + u) * 4;
620
+ this._colors[p + 3] = t, this._colors[p] = c.r, this._colors[p + 1] = c.g, this._colors[p + 2] = c.b;
621
+ }
610
622
  });
611
- const s = this.geometry.getAttribute("color");
612
- s.needsUpdate = !0, this._updateDepthWriteForTransparency();
623
+ const n = this.geometry.getAttribute("color");
624
+ n.needsUpdate = !0, this._updateDepthWriteForTransparency();
613
625
  }
614
626
  /**
615
627
  * Ghost all elements EXCEPT the specified ones
@@ -617,29 +629,48 @@ class ee extends x {
617
629
  *
618
630
  * @param focusElements - Elements to keep fully visible
619
631
  * @param ghostOpacity - Opacity for non-focused elements (default: 0.1)
632
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
620
633
  */
621
- ghostExcept(e, t = 0.1) {
634
+ ghostExcept(e, t = 0.1, i) {
622
635
  if (!this._colors)
623
636
  return;
624
- const i = new Set(e.map((r) => `${r.modelId}:${r.elementId}`));
625
- this._elementMap.forEach((r, o) => {
626
- r.forEach((a, l) => {
627
- const c = `${o}:${l}`, h = i.has(c), d = h ? 1 : t;
628
- this._elementOpacityMap.set(c, d);
629
- for (const u of a)
630
- for (let p = 0; p < u.count; p++) {
631
- const m = (u.start + p) * 4;
632
- if (this._colors[m + 3] = d, !h) {
633
- const f = (this._colors[m] + this._colors[m + 1] + this._colors[m + 2]) / 3, v = 0.6;
634
- this._colors[m] = this._colors[m] * (1 - v) + f * v, this._colors[m + 1] = this._colors[m + 1] * (1 - v) + f * v, this._colors[m + 2] = this._colors[m + 2] * (1 - v) + f * v;
637
+ const s = new Set(e.map((o) => `${o.modelId}:${o.elementId}`));
638
+ this._elementMap.forEach((o, a) => {
639
+ o.forEach((l, c) => {
640
+ const h = `${a}:${c}`, d = s.has(h), u = d ? 1 : t;
641
+ if (this._elementOpacityMap.set(h, u), d)
642
+ this._ghostColors.delete(h);
643
+ else {
644
+ let p;
645
+ if (i)
646
+ p = i;
647
+ else if (this._originalColor) {
648
+ const m = (this._originalColor.r + this._originalColor.g + this._originalColor.b) / 3, g = 0.6;
649
+ p = {
650
+ r: this._originalColor.r * (1 - g) + m * g,
651
+ g: this._originalColor.g * (1 - g) + m * g,
652
+ b: this._originalColor.b * (1 - g) + m * g
653
+ };
654
+ } else
655
+ p = { r: 0.5, g: 0.5, b: 0.5 };
656
+ this._ghostColors.set(h, p);
657
+ }
658
+ for (const p of l)
659
+ for (let m = 0; m < p.count; m++) {
660
+ const g = (p.start + m) * 4;
661
+ if (this._colors[g + 3] = u, d)
662
+ this._originalColor && (this._colors[g] = this._originalColor.r, this._colors[g + 1] = this._originalColor.g, this._colors[g + 2] = this._originalColor.b);
663
+ else {
664
+ const v = this._ghostColors.get(h);
665
+ this._colors[g] = v.r, this._colors[g + 1] = v.g, this._colors[g + 2] = v.b;
635
666
  }
636
667
  }
637
668
  });
638
669
  });
639
- const s = this.geometry.getAttribute("color");
640
- s.needsUpdate = !0;
641
- const n = this.material;
642
- n && (n.depthWrite = !1, n.needsUpdate = !0), this.renderOrder = 1, this._createDepthPrePass();
670
+ const n = this.geometry.getAttribute("color");
671
+ n.needsUpdate = !0;
672
+ const r = this.material;
673
+ r && (r.depthWrite = !1, r.needsUpdate = !0), this.renderOrder = 1, this._createDepthPrePass();
643
674
  }
644
675
  /**
645
676
  * Create a depth-only pre-pass mesh that writes depth for focused elements.
@@ -669,7 +700,7 @@ class ee extends x {
669
700
  resetElementOpacity() {
670
701
  if (!this._colors)
671
702
  return;
672
- this._elementOpacityMap.clear(), this._elementMap.forEach((t) => {
703
+ this._elementOpacityMap.clear(), this._ghostColors.clear(), this._elementMap.forEach((t) => {
673
704
  t.forEach((i) => {
674
705
  for (const s of i)
675
706
  for (let n = 0; n < s.count; n++) {
@@ -865,8 +896,8 @@ class ee extends x {
865
896
  return l.color;
866
897
  return null;
867
898
  }, r = (o, a) => {
868
- const l = `${o}:${a}`;
869
- return this._temporaryColors.get(l) || this._originalColor;
899
+ const l = `${o}:${a}`, c = this._ghostColors.get(l);
900
+ return c && this._elementOpacityMap.has(l) && this._elementOpacityMap.get(l) < 1 ? c : this._temporaryColors.get(l) || this._originalColor;
870
901
  };
871
902
  if (e === null)
872
903
  this._elementMap.forEach((o, a) => {
@@ -875,8 +906,8 @@ class ee extends x {
875
906
  for (const d of l) {
876
907
  const { start: u, count: p } = d;
877
908
  for (let m = 0; m < p; m++) {
878
- const f = (u + m) * s;
879
- this._colors[f] = h.r, this._colors[f + 1] = h.g, this._colors[f + 2] = h.b;
909
+ const g = (u + m) * s;
910
+ this._colors[g] = h.r, this._colors[g + 1] = h.g, this._colors[g + 2] = h.b;
880
911
  }
881
912
  }
882
913
  });
@@ -893,8 +924,8 @@ class ee extends x {
893
924
  if (m)
894
925
  this._colors[p] = m.r, this._colors[p + 1] = m.g, this._colors[p + 2] = m.b;
895
926
  else {
896
- const f = r(o, a);
897
- this._colors[p] = f.r, this._colors[p + 1] = f.g, this._colors[p + 2] = f.b;
927
+ const g = r(o, a);
928
+ this._colors[p] = g.r, this._colors[p + 1] = g.g, this._colors[p + 2] = g.b;
898
929
  }
899
930
  }
900
931
  }
@@ -1182,7 +1213,7 @@ class oe {
1182
1213
  }
1183
1214
  const Ji = D.hexToRGB(y.secondary), qe = class qe extends Wt {
1184
1215
  constructor(e) {
1185
- super(), this.material = e, this.globalMaterialIndex = -1, this._depthPrePassMeshes = [], this._instancedMeshes = /* @__PURE__ */ new Map(), this._bufferElements = [], this._originalColor = null, this._elementMap = /* @__PURE__ */ new Map(), this._originalTransforms = /* @__PURE__ */ new Map(), this._elementOpacity = /* @__PURE__ */ new Map(), this._temporaryColors = /* @__PURE__ */ new Map(), this._selectedElements = [], this._hidingElements = [], this._isolatingElements = [], this._edgeLines = /* @__PURE__ */ new Map(), this._edgeRanges = /* @__PURE__ */ new Map(), this._edgeThreshold = 60, this._edgeMaterial = null, this._isGeneratedLights = !1, this._pointLight = null, this._hiddenSet = /* @__PURE__ */ new Set(), this._isolatedSet = /* @__PURE__ */ new Set(), this.material && "vertexColors" in this.material && (this.material.vertexColors = !0, this.material.needsUpdate = !0);
1216
+ super(), this.material = e, this.globalMaterialIndex = -1, this._depthPrePassMeshes = [], this._instancedMeshes = /* @__PURE__ */ new Map(), this._bufferElements = [], this._originalColor = null, this._elementMap = /* @__PURE__ */ new Map(), this._originalTransforms = /* @__PURE__ */ new Map(), this._elementOpacity = /* @__PURE__ */ new Map(), this._temporaryColors = /* @__PURE__ */ new Map(), this._ghostColors = /* @__PURE__ */ new Map(), this._selectedElements = [], this._hidingElements = [], this._isolatingElements = [], this._edgeLines = /* @__PURE__ */ new Map(), this._edgeRanges = /* @__PURE__ */ new Map(), this._edgeThreshold = 60, this._edgeMaterial = null, this._isGeneratedLights = !1, this._pointLight = null, this._hiddenSet = /* @__PURE__ */ new Set(), this._isolatedSet = /* @__PURE__ */ new Set(), this.material && "vertexColors" in this.material && (this.material.vertexColors = !0, this.material.needsUpdate = !0);
1186
1217
  }
1187
1218
  addBufferElements(e, t) {
1188
1219
  this._bufferElements = e, this._originalColor = t, this.rebuildInstances(e), this.enableRaycasting();
@@ -1229,8 +1260,8 @@ const Ji = D.hexToRGB(y.secondary), qe = class qe extends Wt {
1229
1260
  this._originalTransforms.has(u) || this._originalTransforms.set(u, /* @__PURE__ */ new Map()), this._originalTransforms.get(u).set(p, d.clone());
1230
1261
  const m = this._originalColor || new N(1, 1, 1);
1231
1262
  r[h * 3] = m.r, r[h * 3 + 1] = m.g, r[h * 3 + 2] = m.b, this._elementMap.has(u) || this._elementMap.set(u, /* @__PURE__ */ new Map());
1232
- const f = this._elementMap.get(u);
1233
- f.has(p) || f.set(p, []), f.get(p).push({
1263
+ const g = this._elementMap.get(u);
1264
+ g.has(p) || g.set(p, []), g.get(p).push({
1234
1265
  geometryKey: i,
1235
1266
  instanceIndex: h,
1236
1267
  instancedMesh: n
@@ -1391,8 +1422,8 @@ const Ji = D.hexToRGB(y.secondary), qe = class qe extends Wt {
1391
1422
  return a.color;
1392
1423
  return null;
1393
1424
  }, s = (r, o) => {
1394
- const a = `${r}:${o}`;
1395
- return this._temporaryColors.get(a) || this._originalColor;
1425
+ const a = `${r}:${o}`, l = this._ghostColors.get(a);
1426
+ return l && this._elementOpacity.has(a) && this._elementOpacity.get(a) < 1 ? l : this._temporaryColors.get(a) || this._originalColor;
1396
1427
  };
1397
1428
  if (e === null)
1398
1429
  this._elementMap.forEach((r, o) => {
@@ -1641,31 +1672,49 @@ if (gl_FragColor.a < 0.01) discard;`
1641
1672
  * Set elements to "ghost" mode (semi-transparent)
1642
1673
  * @param elements - Elements to ghost
1643
1674
  * @param ghostOpacity - Opacity for ghosted elements (default 0.1)
1675
+ * @param desaturate - Whether to desaturate color (default: true) - ignored if ghostColor is provided
1676
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
1644
1677
  */
1645
- setElementGhost(e, t = 0.1, i = !0) {
1646
- this._ensureOpacityAttributes(), this.injectOpacityShader(), e.forEach(({ modelId: s, elementId: n }) => {
1647
- const r = `${s}:${n}`;
1648
- this._elementOpacity.set(r, t), this._updateInstanceOpacity(s, n, t), i && this._desaturateInstanceColor(s, n, 1);
1678
+ setElementGhost(e, t = 0.1, i = !0, s) {
1679
+ this._ensureOpacityAttributes(), this.injectOpacityShader(), e.forEach(({ modelId: n, elementId: r }) => {
1680
+ const o = `${n}:${r}`;
1681
+ this._elementOpacity.set(o, t), this._updateInstanceOpacity(n, r, t);
1682
+ let a;
1683
+ s ? (a = s, this._setInstanceColor(n, r, s)) : i && this._originalColor ? (a = {
1684
+ r: this._originalColor.r * 0 + 1 * 1,
1685
+ g: this._originalColor.g * 0 + 1 * 1,
1686
+ b: this._originalColor.b * 0 + 1 * 1
1687
+ }, this._desaturateInstanceColor(n, r, 1)) : a = this._originalColor || { r: 0.5, g: 0.5, b: 0.5 }, this._ghostColors.set(o, a);
1649
1688
  }), this._updateDepthWriteForTransparency();
1650
1689
  }
1651
1690
  /**
1652
1691
  * Ghost all elements EXCEPT the specified ones
1653
1692
  * @param elements - Elements to keep fully opaque
1654
1693
  * @param ghostOpacity - Opacity for all other elements (default 0.1)
1694
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
1655
1695
  */
1656
- ghostExcept(e, t = 0.1) {
1696
+ ghostExcept(e, t = 0.1, i) {
1657
1697
  this._ensureOpacityAttributes(), this.injectOpacityShader();
1658
- const i = /* @__PURE__ */ new Set();
1659
- e.forEach(({ modelId: s, elementId: n }) => {
1660
- i.add(`${s}:${n}`);
1661
- }), this._elementMap.forEach((s, n) => {
1662
- s.forEach((r, o) => {
1663
- const a = `${n}:${o}`, l = i.has(a), c = l ? 1 : t;
1664
- this._elementOpacity.set(a, c), this._updateInstanceOpacity(n, o, c), l ? this._restoreInstanceColor(n, o) : this._desaturateInstanceColor(n, o, 0.6);
1698
+ const s = /* @__PURE__ */ new Set();
1699
+ e.forEach(({ modelId: n, elementId: r }) => {
1700
+ s.add(`${n}:${r}`);
1701
+ }), this._elementMap.forEach((n, r) => {
1702
+ n.forEach((o, a) => {
1703
+ const l = `${r}:${a}`, c = s.has(l), h = c ? 1 : t;
1704
+ if (this._elementOpacity.set(l, h), this._updateInstanceOpacity(r, a, h), c)
1705
+ this._ghostColors.delete(l), this._restoreInstanceColor(r, a);
1706
+ else {
1707
+ let d;
1708
+ i ? (d = i, this._setInstanceColor(r, a, i)) : this._originalColor ? (d = {
1709
+ r: this._originalColor.r * (1 - 0.6) + 1 * 0.6,
1710
+ g: this._originalColor.g * (1 - 0.6) + 1 * 0.6,
1711
+ b: this._originalColor.b * (1 - 0.6) + 1 * 0.6
1712
+ }, this._desaturateInstanceColor(r, a, 0.6)) : (d = { r: 0.5, g: 0.5, b: 0.5 }, this._setInstanceColor(r, a, d)), this._ghostColors.set(l, d);
1713
+ }
1665
1714
  });
1666
- }), this._instancedMeshes.forEach((s) => {
1667
- const n = s.material;
1668
- n && (n.depthWrite = !1, n.needsUpdate = !0), s.renderOrder = 1;
1715
+ }), this._instancedMeshes.forEach((n) => {
1716
+ const r = n.material;
1717
+ r && (r.depthWrite = !1, r.needsUpdate = !0), n.renderOrder = 1;
1669
1718
  }), this._createDepthPrePass();
1670
1719
  }
1671
1720
  /**
@@ -1734,6 +1783,24 @@ if (vInstanceOpacity < 0.5) discard;`
1734
1783
  a[l] = c * (1 - i) + 1 * i, a[l + 1] = h * (1 - i) + 1 * i, a[l + 2] = d * (1 - i) + 1 * i, r.instanceColor.needsUpdate = !0;
1735
1784
  });
1736
1785
  }
1786
+ /**
1787
+ * Set instance color to a specific color
1788
+ * @param modelId - Model ID
1789
+ * @param elementId - Element ID
1790
+ * @param color - Target color {r, g, b} with values 0-1
1791
+ */
1792
+ _setInstanceColor(e, t, i) {
1793
+ var n;
1794
+ const s = (n = this._elementMap.get(e)) == null ? void 0 : n.get(t);
1795
+ s && s.forEach(({ instancedMesh: r, instanceIndex: o }) => {
1796
+ var c;
1797
+ const a = (c = r.instanceColor) == null ? void 0 : c.array;
1798
+ if (!a)
1799
+ return;
1800
+ const l = o * 3;
1801
+ a[l] = i.r, a[l + 1] = i.g, a[l + 2] = i.b, r.instanceColor.needsUpdate = !0;
1802
+ });
1803
+ }
1737
1804
  /**
1738
1805
  * Restore instance color to original
1739
1806
  */
@@ -1755,7 +1822,7 @@ if (vInstanceOpacity < 0.5) discard;`
1755
1822
  * Reset all elements to full opacity and restore original colors
1756
1823
  */
1757
1824
  resetElementOpacity() {
1758
- this._elementOpacity.clear(), this._instancedMeshes.forEach((e) => {
1825
+ this._elementOpacity.clear(), this._ghostColors.clear(), this._instancedMeshes.forEach((e) => {
1759
1826
  const t = e.geometry.getAttribute(
1760
1827
  "instanceOpacity"
1761
1828
  );
@@ -2385,24 +2452,26 @@ class ts extends x {
2385
2452
  * Set elements to "ghost" mode (semi-transparent)
2386
2453
  * @param elements - Elements to ghost
2387
2454
  * @param ghostOpacity - Opacity for ghosted elements (default 0.1)
2455
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
2388
2456
  */
2389
- setElementGhost(e, t = 0.1) {
2390
- this._batchedMeshes.forEach((i) => {
2391
- i.setElementGhost(e, t, !0);
2392
- }), this._instancedMeshes.forEach((i) => {
2393
- i.setElementGhost(e, t / 10, !0);
2457
+ setElementGhost(e, t = 0.1, i) {
2458
+ this._batchedMeshes.forEach((s) => {
2459
+ s.setElementGhost(e, t, !0, i);
2460
+ }), this._instancedMeshes.forEach((s) => {
2461
+ s.setElementGhost(e, t / 10, !0, i);
2394
2462
  });
2395
2463
  }
2396
2464
  /**
2397
2465
  * Ghost all elements EXCEPT the specified ones
2398
2466
  * @param elements - Elements to keep fully opaque
2399
2467
  * @param ghostOpacity - Opacity for all other elements (default 0.1)
2468
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
2400
2469
  */
2401
- ghostExcept(e, t = 0.1) {
2402
- this._batchedMeshes.forEach((i) => {
2403
- i.ghostExcept(e, t);
2404
- }), this._instancedMeshes.forEach((i) => {
2405
- i.ghostExcept(e, t / 10);
2470
+ ghostExcept(e, t = 0.1, i) {
2471
+ this._batchedMeshes.forEach((s) => {
2472
+ s.ghostExcept(e, t, i);
2473
+ }), this._instancedMeshes.forEach((s) => {
2474
+ s.ghostExcept(e, t / 10, i);
2406
2475
  });
2407
2476
  }
2408
2477
  /**
@@ -2503,7 +2572,7 @@ const ss = {
2503
2572
  shadowcatcher: !0
2504
2573
  };
2505
2574
  function ns() {
2506
- function g(i) {
2575
+ function f(i) {
2507
2576
  let s = 0;
2508
2577
  for (let n = 0; n < i.length; n++)
2509
2578
  s = (s << 5) - s + i.charCodeAt(n), s |= 0;
@@ -2519,7 +2588,7 @@ function ns() {
2519
2588
  return /* @__PURE__ */ new Map();
2520
2589
  const h = r * o, d = Math.sqrt(h / c), u = /* @__PURE__ */ new Map();
2521
2590
  i.forEach((v) => {
2522
- const b = (n == null ? void 0 : n.seed) ?? g(v.id);
2591
+ const b = (n == null ? void 0 : n.seed) ?? f(v.id);
2523
2592
  u.set(v.id, {
2524
2593
  x: e(b) * r,
2525
2594
  y: e(b * 2) * o,
@@ -2555,10 +2624,10 @@ function ns() {
2555
2624
  } else
2556
2625
  w.x = Math.max(0, Math.min(r, w.x)), w.y = Math.max(0, Math.min(o, w.y));
2557
2626
  }), p -= m;
2558
- const f = /* @__PURE__ */ new Map();
2627
+ const g = /* @__PURE__ */ new Map();
2559
2628
  return u.forEach((v, b) => {
2560
- f.set(b, { x: v.x, y: v.y });
2561
- }), f;
2629
+ g.set(b, { x: v.x, y: v.y });
2630
+ }), g;
2562
2631
  }
2563
2632
  self.onmessage = (i) => {
2564
2633
  try {
@@ -2824,14 +2893,14 @@ class os {
2824
2893
  });
2825
2894
  const s = [];
2826
2895
  this._elementMap.forEach((l, c) => {
2827
- var d, u, p, m, f;
2896
+ var d, u, p, m, g;
2828
2897
  if ((!(l != null && l.Category) || !((d = l.Category) != null && d.value) || l.Category.value == null) && (!(l != null && l.ObjectType) || !((u = l.ObjectType) != null && u.value) || l.ObjectType.value == null) || !i.has(c))
2829
2898
  return;
2830
2899
  const h = ((p = l == null ? void 0 : l.Name) == null ? void 0 : p.value) || c.toString();
2831
2900
  s.push({
2832
2901
  id: String(c),
2833
2902
  label: h,
2834
- group: ((m = l == null ? void 0 : l.Category) == null ? void 0 : m.value) || ((f = l == null ? void 0 : l.ObjectType) == null ? void 0 : f.value)
2903
+ group: ((m = l == null ? void 0 : l.Category) == null ? void 0 : m.value) || ((g = l == null ? void 0 : l.ObjectType) == null ? void 0 : g.value)
2835
2904
  });
2836
2905
  });
2837
2906
  const n = this._computeForceDirectedLayout(s, t, e), r = s.map((l) => l.id), o = this._calculateNodeLevels(t, r);
@@ -2855,9 +2924,9 @@ class os {
2855
2924
  return new Promise((i, s) => {
2856
2925
  const n = this._relationships.length, r = this._elementMap.size, o = n + r + r + 1 + 1;
2857
2926
  let a = 0;
2858
- const l = (f, v, b) => {
2927
+ const l = (g, v, b) => {
2859
2928
  t == null || t({
2860
- phase: f,
2929
+ phase: g,
2861
2930
  percent: Math.round(a / o * 100),
2862
2931
  current: v,
2863
2932
  total: b
@@ -2865,37 +2934,37 @@ class os {
2865
2934
  };
2866
2935
  l("Building edges", 0, n);
2867
2936
  const c = [], h = /* @__PURE__ */ new Set();
2868
- this._relationships.forEach((f, v) => {
2937
+ this._relationships.forEach((g, v) => {
2869
2938
  c.push({
2870
- id: `${f.FromId}-${f.ToId}-${f.Type}-${v}`,
2871
- source: f.FromId,
2872
- target: f.ToId,
2873
- type: f.Type
2874
- }), h.add(Number(f.FromId)), h.add(Number(f.ToId)), a++;
2939
+ id: `${g.FromId}-${g.ToId}-${g.Type}-${v}`,
2940
+ source: g.FromId,
2941
+ target: g.ToId,
2942
+ type: g.Type
2943
+ }), h.add(Number(g.FromId)), h.add(Number(g.ToId)), a++;
2875
2944
  }), l("Building edges", n, n);
2876
2945
  const d = [];
2877
- this._elementMap.forEach((f, v) => {
2946
+ this._elementMap.forEach((g, v) => {
2878
2947
  var w, S, A, C, _;
2879
- if (a++, (!(f != null && f.Category) || !((w = f.Category) != null && w.value) || f.Category.value == null) && (!(f != null && f.ObjectType) || !((S = f.ObjectType) != null && S.value) || f.ObjectType.value == null) || !h.has(v))
2948
+ if (a++, (!(g != null && g.Category) || !((w = g.Category) != null && w.value) || g.Category.value == null) && (!(g != null && g.ObjectType) || !((S = g.ObjectType) != null && S.value) || g.ObjectType.value == null) || !h.has(v))
2880
2949
  return;
2881
- const b = ((A = f == null ? void 0 : f.Name) == null ? void 0 : A.value) || v.toString();
2950
+ const b = ((A = g == null ? void 0 : g.Name) == null ? void 0 : A.value) || v.toString();
2882
2951
  d.push({
2883
2952
  id: String(v),
2884
2953
  label: b,
2885
- group: ((C = f == null ? void 0 : f.Category) == null ? void 0 : C.value) || ((_ = f == null ? void 0 : f.ObjectType) == null ? void 0 : _.value)
2954
+ group: ((C = g == null ? void 0 : g.Category) == null ? void 0 : C.value) || ((_ = g == null ? void 0 : g.ObjectType) == null ? void 0 : _.value)
2886
2955
  });
2887
2956
  }), l("Building nodes", d.length, d.length);
2888
- const u = d.map((f) => f.id), p = this._calculateNodeLevels(c, u);
2957
+ const u = d.map((g) => g.id), p = this._calculateNodeLevels(c, u);
2889
2958
  a += r, l("Calculating levels", d.length, d.length);
2890
2959
  const m = new as();
2891
2960
  l(
2892
2961
  "Computing layout",
2893
2962
  0,
2894
2963
  d.length
2895
- ), m.computeLayout(d, c, e, (f) => {
2964
+ ), m.computeLayout(d, c, e, (g) => {
2896
2965
  a++;
2897
2966
  const v = d.map((b) => {
2898
- const w = f[b.id], S = p.get(b.id);
2967
+ const w = g[b.id], S = p.get(b.id);
2899
2968
  return {
2900
2969
  ...b,
2901
2970
  x: (w == null ? void 0 : w.x) ?? 0,
@@ -2921,9 +2990,9 @@ class os {
2921
2990
  if (a === 0)
2922
2991
  return /* @__PURE__ */ new Map();
2923
2992
  const l = s * n, c = Math.sqrt(l / a), h = /* @__PURE__ */ new Map();
2924
- e.forEach((f) => {
2925
- const v = (i == null ? void 0 : i.seed) ?? this._hashString(f.id);
2926
- h.set(f.id, {
2993
+ e.forEach((g) => {
2994
+ const v = (i == null ? void 0 : i.seed) ?? this._hashString(g.id);
2995
+ h.set(g.id, {
2927
2996
  x: this._seededRandom(v) * s,
2928
2997
  y: this._seededRandom(v * 2) * n,
2929
2998
  vx: 0,
@@ -2931,13 +3000,13 @@ class os {
2931
3000
  });
2932
3001
  });
2933
3002
  const d = /* @__PURE__ */ new Map();
2934
- t.forEach((f) => {
2935
- const v = String(f.source), b = String(f.target);
3003
+ t.forEach((g) => {
3004
+ const v = String(g.source), b = String(g.target);
2936
3005
  d.has(v) || d.set(v, /* @__PURE__ */ new Set()), d.has(b) || d.set(b, /* @__PURE__ */ new Set()), d.get(v).add(b), d.get(b).add(v);
2937
3006
  });
2938
3007
  let u = s / 10;
2939
3008
  const p = u / r;
2940
- for (let f = 0; f < r; f++)
3009
+ for (let g = 0; g < r; g++)
2941
3010
  e.forEach((v) => {
2942
3011
  const b = h.get(v.id);
2943
3012
  b.vx = 0, b.vy = 0, e.forEach((w) => {
@@ -2964,8 +3033,8 @@ class os {
2964
3033
  b.x = Math.max(0, Math.min(s, b.x)), b.y = Math.max(0, Math.min(n, b.y));
2965
3034
  }), u -= p;
2966
3035
  const m = /* @__PURE__ */ new Map();
2967
- return h.forEach((f, v) => {
2968
- m.set(v, { x: f.x, y: f.y });
3036
+ return h.forEach((g, v) => {
3037
+ m.set(v, { x: g.x, y: g.y });
2969
3038
  }), m;
2970
3039
  }
2971
3040
  /**
@@ -2991,7 +3060,7 @@ class Sr {
2991
3060
  this.children = /* @__PURE__ */ new Map(), this.keys = /* @__PURE__ */ new Set();
2992
3061
  }
2993
3062
  }
2994
- var $ = /* @__PURE__ */ ((g) => (g[g.ON_MOUSE_MOVE = 0] = "ON_MOUSE_MOVE", g[g.ON_MOUSE_DOWN_LEFT = 1] = "ON_MOUSE_DOWN_LEFT", g[g.ON_MOUSE_UP_LEFT = 2] = "ON_MOUSE_UP_LEFT", g[g.ON_MOUSE_DOWN_RIGHT = 3] = "ON_MOUSE_DOWN_RIGHT", g[g.ON_MOUSE_UP_RIGHT = 4] = "ON_MOUSE_UP_RIGHT", g[g.ON_MOUSE_DOUBLE_CLICK = 5] = "ON_MOUSE_DOUBLE_CLICK", g))($ || {}), se = /* @__PURE__ */ ((g) => (g[g.ON_WAKE = 0] = "ON_WAKE", g[g.ON_SLEEP = 1] = "ON_SLEEP", g[g.ON_UPDATE = 2] = "ON_UPDATE", g))(se || {}), we = /* @__PURE__ */ ((g) => (g[g.KEYDOWN = 0] = "KEYDOWN", g[g.KEYUP = 1] = "KEYUP", g))(we || {}), k = /* @__PURE__ */ ((g) => (g[g.LOADED_SCENE = 0] = "LOADED_SCENE", g[g.LOADED_MATERIAL_MANAGER = 1] = "LOADED_MATERIAL_MANAGER", g[g.LOADED_RENDERER = 2] = "LOADED_RENDERER", g[g.LOADED_CAMERA = 3] = "LOADED_CAMERA", g[g.LOADED_CUBE = 4] = "LOADED_CUBE", g[g.LOADED_TOOLS = 5] = "LOADED_TOOLS", g[g.LOADED_SEPERATE_MODEL = 6] = "LOADED_SEPERATE_MODEL", g[g.GENERATED_MERGE_MODEL = 7] = "GENERATED_MERGE_MODEL", g[g.LOADED_DATA = 8] = "LOADED_DATA", g[g.SELECT_ELEMENTS = 9] = "SELECT_ELEMENTS", g[g.UNSELECT_ELEMENTS = 10] = "UNSELECT_ELEMENTS", g))(k || {});
3063
+ var $ = /* @__PURE__ */ ((f) => (f[f.ON_MOUSE_MOVE = 0] = "ON_MOUSE_MOVE", f[f.ON_MOUSE_DOWN_LEFT = 1] = "ON_MOUSE_DOWN_LEFT", f[f.ON_MOUSE_UP_LEFT = 2] = "ON_MOUSE_UP_LEFT", f[f.ON_MOUSE_DOWN_RIGHT = 3] = "ON_MOUSE_DOWN_RIGHT", f[f.ON_MOUSE_UP_RIGHT = 4] = "ON_MOUSE_UP_RIGHT", f[f.ON_MOUSE_DOUBLE_CLICK = 5] = "ON_MOUSE_DOUBLE_CLICK", f))($ || {}), se = /* @__PURE__ */ ((f) => (f[f.ON_WAKE = 0] = "ON_WAKE", f[f.ON_SLEEP = 1] = "ON_SLEEP", f[f.ON_UPDATE = 2] = "ON_UPDATE", f))(se || {}), we = /* @__PURE__ */ ((f) => (f[f.KEYDOWN = 0] = "KEYDOWN", f[f.KEYUP = 1] = "KEYUP", f))(we || {}), k = /* @__PURE__ */ ((f) => (f[f.LOADED_SCENE = 0] = "LOADED_SCENE", f[f.LOADED_MATERIAL_MANAGER = 1] = "LOADED_MATERIAL_MANAGER", f[f.LOADED_RENDERER = 2] = "LOADED_RENDERER", f[f.LOADED_CAMERA = 3] = "LOADED_CAMERA", f[f.LOADED_CUBE = 4] = "LOADED_CUBE", f[f.LOADED_TOOLS = 5] = "LOADED_TOOLS", f[f.LOADED_SEPERATE_MODEL = 6] = "LOADED_SEPERATE_MODEL", f[f.GENERATED_MERGE_MODEL = 7] = "GENERATED_MERGE_MODEL", f[f.LOADED_DATA = 8] = "LOADED_DATA", f[f.SELECT_ELEMENTS = 9] = "SELECT_ELEMENTS", f[f.UNSELECT_ELEMENTS = 10] = "UNSELECT_ELEMENTS", f))(k || {});
2995
3064
  class _t {
2996
3065
  constructor() {
2997
3066
  this.items = {};
@@ -3460,8 +3529,8 @@ class us {
3460
3529
  }
3461
3530
  let t = 0, i = 0, s = 0;
3462
3531
  e.forEach((r, o) => {
3463
- var f, v;
3464
- const a = r.getInstancedMeshes(), l = ((f = r.getTotalVertexCount) == null ? void 0 : f.call(r)) || 0, c = ((v = r.getObjectCount) == null ? void 0 : v.call(r)) || 0;
3532
+ var g, v;
3533
+ const a = r.getInstancedMeshes(), l = ((g = r.getTotalVertexCount) == null ? void 0 : g.call(r)) || 0, c = ((v = r.getObjectCount) == null ? void 0 : v.call(r)) || 0;
3465
3534
  i += a.length, s += l;
3466
3535
  let h = 0;
3467
3536
  a.forEach((b) => {
@@ -3629,14 +3698,14 @@ class us {
3629
3698
  const h = l.getInstancedMeshes();
3630
3699
  s += h.length, o += h.length, h.forEach((d, u) => {
3631
3700
  var b;
3632
- const p = d.geometry, m = ((b = p.attributes.position) == null ? void 0 : b.count) || 0, f = p.index ? p.index.count / 3 : m / 3, v = m * d.count;
3701
+ const p = d.geometry, m = ((b = p.attributes.position) == null ? void 0 : b.count) || 0, g = p.index ? p.index.count / 3 : m / 3, v = m * d.count;
3633
3702
  n += d.count, r += v, a.push({
3634
3703
  Wrapper: `#${c + 1}`,
3635
3704
  Material: l.globalMaterialIndex,
3636
3705
  "Internal Mesh": `#${u + 1}`,
3637
3706
  Instances: d.count,
3638
3707
  "Base Verts": m,
3639
- "Base Tris": Math.floor(f),
3708
+ "Base Tris": Math.floor(g),
3640
3709
  "Rendered Verts": v,
3641
3710
  "Mesh ID": d.id
3642
3711
  });
@@ -3950,7 +4019,7 @@ class ps {
3950
4019
  enabled: !0,
3951
4020
  estimatedPasses: 1
3952
4021
  })), e.estimatedTotalPasses = e.renderPasses.reduce(
3953
- (m, f) => m + f.estimatedPasses,
4022
+ (m, g) => m + g.estimatedPasses,
3954
4023
  0
3955
4024
  ), e.singlePassDrawCalls = e.totalDrawCalls, e.expectedTotalDrawCalls = e.singlePassDrawCalls * e.estimatedTotalPasses;
3956
4025
  const n = this.viralViewerApi.viralRenderer.renderer.info, r = n.render.calls, o = n.render.triangles, a = r / Math.max(e.singlePassDrawCalls, 1), l = o / Math.max(e.totalTriangles, 1);
@@ -4719,7 +4788,7 @@ class xs {
4719
4788
  * @param camera
4720
4789
  */
4721
4790
  async focusCameraOnModel(e, t = !1) {
4722
- var u, p, m, f, v;
4791
+ var u, p, m, g, v;
4723
4792
  const i = new E(-e.box.min.X, e.box.min.Z, e.box.min.Y), s = new E(-e.box.max.X, e.box.max.Z, e.box.max.Y), n = D.middlePoint(i, s), r = Math.abs(e.box.max.X - e.box.min.X), o = Math.abs(e.box.max.Y - e.box.min.Y), a = Math.abs(e.box.max.Z - e.box.min.Z), l = Math.max(r, o, a);
4724
4793
  await ((u = this.viralViewerApi.viralCamera.cameraControls) == null ? void 0 : u.setTarget(
4725
4794
  n.x,
@@ -4733,7 +4802,7 @@ class xs {
4733
4802
  const c = new F(i, s);
4734
4803
  await ((m = this.viralViewerApi.viralCamera.cameraControls) == null ? void 0 : m.fitToBox(c, !1));
4735
4804
  const h = new E();
4736
- (f = this.viralViewerApi.viralCamera.cameraControls) == null || f.getPosition(h);
4805
+ (g = this.viralViewerApi.viralCamera.cameraControls) == null || g.getPosition(h);
4737
4806
  var d = h.distanceTo(n);
4738
4807
  await ((v = this.viralViewerApi.viralCamera.cameraControls) == null ? void 0 : v.setPosition(
4739
4808
  h.x,
@@ -4783,8 +4852,8 @@ class P {
4783
4852
  const u = -(P.dotProduct(l, e) + c) / d;
4784
4853
  if (u < -r || u > 1 + r)
4785
4854
  return !1;
4786
- const p = P.add(e, P.scale(h, u)), m = P.distance(p, e), f = P.distance(p, t);
4787
- return m < r || f < r ? !1 : P.isPointInTriangle(p, i, s, n, r);
4855
+ const p = P.add(e, P.scale(h, u)), m = P.distance(p, e), g = P.distance(p, t);
4856
+ return m < r || g < r ? !1 : P.isPointInTriangle(p, i, s, n, r);
4788
4857
  }
4789
4858
  /**
4790
4859
  * Check if a point lies inside a triangle using barycentric coordinates
@@ -4795,7 +4864,7 @@ class P {
4795
4864
  * @returns boolean - Whether the point lies inside the triangle
4796
4865
  */
4797
4866
  static isPointInTriangle(e, t, i, s, n = 1e-7) {
4798
- const r = P.subtract(i, t), o = P.subtract(s, i), a = P.subtract(t, s), l = P.subtract(e, t), c = P.subtract(e, i), h = P.subtract(e, s), d = P.crossProduct(r, l), u = P.crossProduct(o, c), p = P.crossProduct(a, h), m = P.normalize(d), f = P.normalize(u), v = P.normalize(p), b = P.dotProduct(m, f), w = P.dotProduct(f, v);
4867
+ const r = P.subtract(i, t), o = P.subtract(s, i), a = P.subtract(t, s), l = P.subtract(e, t), c = P.subtract(e, i), h = P.subtract(e, s), d = P.crossProduct(r, l), u = P.crossProduct(o, c), p = P.crossProduct(a, h), m = P.normalize(d), g = P.normalize(u), v = P.normalize(p), b = P.dotProduct(m, g), w = P.dotProduct(g, v);
4799
4868
  return b > 1 - n && w > 1 - n;
4800
4869
  }
4801
4870
  // Vector math helper functions
@@ -4849,7 +4918,7 @@ class P {
4849
4918
  }
4850
4919
  }
4851
4920
  function Es() {
4852
- class g {
4921
+ class f {
4853
4922
  constructor(t, i, s) {
4854
4923
  this.X = 0, this.Y = 0, this.Z = 0, this.X = t, this.Y = i, this.Z = s;
4855
4924
  }
@@ -4863,8 +4932,8 @@ function Es() {
4863
4932
  d < s && (s = d), u < n && (n = u), p < r && (r = p), d > o && (o = d), u > a && (a = u), p > l && (l = p);
4864
4933
  }
4865
4934
  return {
4866
- min: new g(s, n, r),
4867
- max: new g(o, a, l)
4935
+ min: new f(s, n, r),
4936
+ max: new f(o, a, l)
4868
4937
  };
4869
4938
  }
4870
4939
  self.postMessage(i());
@@ -4887,8 +4956,8 @@ class Cs {
4887
4956
  }
4888
4957
  }
4889
4958
  function As() {
4890
- self.onmessage = (g) => {
4891
- const e = g.data;
4959
+ self.onmessage = (f) => {
4960
+ const e = f.data;
4892
4961
  function t(s, n, r = 0.1) {
4893
4962
  const o = s.max.X >= n.min.X && s.min.X <= n.max.X, a = s.max.Y >= n.min.Y && s.min.Y <= n.max.Y, l = s.max.Z >= n.min.Z && s.min.Z <= n.max.Z, c = Math.min(s.max.X, n.max.X) - Math.max(s.min.X, n.min.X), h = Math.min(s.max.Y, n.max.Y) - Math.max(s.min.Y, n.min.Y), d = Math.min(s.max.Z, n.max.Z) - Math.max(s.min.Z, n.min.Z);
4894
4963
  return o && a && l ? c > r && h > r && d > r : !1;
@@ -4918,7 +4987,7 @@ class Is {
4918
4987
  }
4919
4988
  }
4920
4989
  function Vs() {
4921
- class g {
4990
+ class f {
4922
4991
  constructor() {
4923
4992
  this.children = /* @__PURE__ */ new Map(), this.keys = /* @__PURE__ */ new Set();
4924
4993
  }
@@ -4942,7 +5011,7 @@ function Vs() {
4942
5011
  let c = n;
4943
5012
  for (let h = l; h < a.length; h++) {
4944
5013
  const d = a[h];
4945
- c.children.has(d) || c.children.set(d, new g()), c = c.children.get(d), c.keys.add(o);
5014
+ c.children.has(d) || c.children.set(d, new f()), c = c.children.get(d), c.keys.add(o);
4946
5015
  }
4947
5016
  }
4948
5017
  }
@@ -4963,8 +5032,8 @@ function Vs() {
4963
5032
  continue;
4964
5033
  const u = Number(d), p = h[d];
4965
5034
  if (p && typeof p == "object") {
4966
- const f = Object.values(p);
4967
- for (const v of f)
5035
+ const g = Object.values(p);
5036
+ for (const v of g)
4968
5037
  if (v && typeof v == "object") {
4969
5038
  const b = Object.values(v);
4970
5039
  for (const w of b)
@@ -5000,7 +5069,7 @@ function Vs() {
5000
5069
  return;
5001
5070
  }
5002
5071
  console.log("[TreeNode Worker] Processing", s.length, "items");
5003
- const n = new g();
5072
+ const n = new f();
5004
5073
  i();
5005
5074
  const r = n.toSerializable();
5006
5075
  console.log("[TreeNode Worker] Trie built, posting result..."), self.postMessage(r);
@@ -5023,7 +5092,7 @@ class Ps {
5023
5092
  }
5024
5093
  }
5025
5094
  function Os() {
5026
- class g {
5095
+ class f {
5027
5096
  constructor(u, p, m) {
5028
5097
  this.x = 0, this.y = 0, this.z = 0, this.x = u, this.y = p, this.z = m;
5029
5098
  }
@@ -5051,42 +5120,42 @@ function Os() {
5051
5120
  const u = Math.sqrt(
5052
5121
  d.x * d.x + d.y * d.y + d.z * d.z
5053
5122
  );
5054
- return u < 1e-7 ? new g(0, 0, 0) : new g(d.x / u, d.y / u, d.z / u);
5123
+ return u < 1e-7 ? new f(0, 0, 0) : new f(d.x / u, d.y / u, d.z / u);
5055
5124
  }
5056
5125
  function o(d, u) {
5057
5126
  return Math.sqrt((d.x - u.x) ** 2 + (d.y - u.y) ** 2 + (d.z - u.z) ** 2);
5058
5127
  }
5059
- function a(d, u, p, m, f = 1e-7) {
5128
+ function a(d, u, p, m, g = 1e-7) {
5060
5129
  const v = e(p, u), b = e(m, p), w = e(u, m), S = e(d, u), A = e(d, p), C = e(d, m), _ = n(v, S), I = n(b, A), T = n(w, C), M = r(_), V = r(I), L = r(T), B = s(M, V), O = s(V, L);
5061
- return B > 1 - f && O > 1 - f;
5130
+ return B > 1 - g && O > 1 - g;
5062
5131
  }
5063
- function l(d, u, p, m, f, v, b = 1e-3) {
5064
- return !!(h(d, u, m, f, v, b) || h(u, p, m, f, v, b) || h(p, d, m, f, v, b));
5132
+ function l(d, u, p, m, g, v, b = 1e-3) {
5133
+ return !!(h(d, u, m, g, v, b) || h(u, p, m, g, v, b) || h(p, d, m, g, v, b));
5065
5134
  }
5066
- function c(d, u, p, m, f, v = 1e-7) {
5067
- const b = e(m, p), w = e(f, p), S = n(b, w), A = -s(S, p), C = s(S, d) + A, _ = s(S, u) + A;
5135
+ function c(d, u, p, m, g, v = 1e-7) {
5136
+ const b = e(m, p), w = e(g, p), S = n(b, w), A = -s(S, p), C = s(S, d) + A, _ = s(S, u) + A;
5068
5137
  if (Math.abs(C) > v || Math.abs(_) > v)
5069
5138
  return !1;
5070
- const I = a(d, p, m, f, v), T = a(u, p, m, f, v);
5139
+ const I = a(d, p, m, g, v), T = a(u, p, m, g, v);
5071
5140
  return !(!I || !T);
5072
5141
  }
5073
- function h(d, u, p, m, f, v = 5) {
5074
- const b = e(m, p), w = e(f, p), S = n(b, w), A = -s(S, p), C = e(u, d), _ = s(S, C);
5142
+ function h(d, u, p, m, g, v = 5) {
5143
+ const b = e(m, p), w = e(g, p), S = n(b, w), A = -s(S, p), C = e(u, d), _ = s(S, C);
5075
5144
  if (Math.abs(_) < 1e-7)
5076
5145
  return !1;
5077
5146
  const I = -(s(S, d) + A) / _;
5078
5147
  if (I < -v || I > 1 + v)
5079
5148
  return !1;
5080
5149
  const T = t(d, i(C, I)), M = o(T, d), V = o(T, u);
5081
- return M < v || V < v ? !1 : a(T, p, m, f, v);
5150
+ return M < v || V < v ? !1 : a(T, p, m, g, v);
5082
5151
  }
5083
5152
  self.onmessage = (d) => {
5084
- const u = d.data, p = u.buffer1, m = u.buffer2, f = 1e-3;
5153
+ const u = d.data, p = u.buffer1, m = u.buffer2, g = 1e-3;
5085
5154
  for (let v = 0; v < p.length; v += 9) {
5086
- const b = new g(p[v], p[v + 1], p[v + 2]), w = new g(p[v + 3], p[v + 4], p[v + 5]), S = new g(p[v + 6], p[v + 7], p[v + 8]);
5155
+ const b = new f(p[v], p[v + 1], p[v + 2]), w = new f(p[v + 3], p[v + 4], p[v + 5]), S = new f(p[v + 6], p[v + 7], p[v + 8]);
5087
5156
  for (let A = 0; A < m.length; A += 9) {
5088
- const C = new g(m[A], m[A + 1], m[A + 2]), _ = new g(m[A + 3], m[A + 4], m[A + 5]), I = new g(m[A + 6], m[A + 7], m[A + 8]);
5089
- c(b, w, C, _, I, f) && c(w, S, C, _, I, f) && (console.log("belong to face"), self.postMessage(!1)), l(b, w, S, C, _, I, f) && self.postMessage(!0);
5157
+ const C = new f(m[A], m[A + 1], m[A + 2]), _ = new f(m[A + 3], m[A + 4], m[A + 5]), I = new f(m[A + 6], m[A + 7], m[A + 8]);
5158
+ c(b, w, C, _, I, g) && c(w, S, C, _, I, g) && (console.log("belong to face"), self.postMessage(!1)), l(b, w, S, C, _, I, g) && self.postMessage(!0);
5090
5159
  }
5091
5160
  }
5092
5161
  self.postMessage(!1);
@@ -5108,8 +5177,8 @@ class Rs {
5108
5177
  function Ls() {
5109
5178
  self.addEventListener(
5110
5179
  "message",
5111
- (g) => {
5112
- const t = g.data.url, i = g.data.byteRangeStart, s = g.data.byteRangeEnd;
5180
+ (f) => {
5181
+ const t = f.data.url, i = f.data.byteRangeStart, s = f.data.byteRangeEnd;
5113
5182
  i && i > 0 && s && s > 0 ? fetch(t, {
5114
5183
  headers: {
5115
5184
  Range: `bytes=${i}-${s}`
@@ -5432,10 +5501,10 @@ class Ns {
5432
5501
  elements: l
5433
5502
  };
5434
5503
  await new Promise((m) => {
5435
- this._boundingBoxIntersectWorker.checkIntersect(u, async (f) => {
5436
- e === t && (f = f.filter((w) => w !== Number.parseInt(d.elementId)));
5504
+ this._boundingBoxIntersectWorker.checkIntersect(u, async (g) => {
5505
+ e === t && (g = g.filter((w) => w !== Number.parseInt(d.elementId)));
5437
5506
  const v = n.filter(
5438
- (w) => f.includes(Number.parseInt(w.elementId))
5507
+ (w) => g.includes(Number.parseInt(w.elementId))
5439
5508
  ), b = [];
5440
5509
  for (let w = 0; w < v.length; w++) {
5441
5510
  const S = v[w];
@@ -5780,11 +5849,11 @@ class Hs {
5780
5849
  //#endregion
5781
5850
  }
5782
5851
  const We = {
5783
- showAll: (g, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${g || 24} viewBox="0 -960 960 960" width="24"><path d="M240-160q-33 0-56.5-23.5T160-240q0-33 23.5-56.5T240-320q33 0 56.5 23.5T320-240q0 33-23.5 56.5T240-160Zm240 0q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm240 0q-33 0-56.5-23.5T640-240q0-33 23.5-56.5T720-320q33 0 56.5 23.5T800-240q0 33-23.5 56.5T720-160ZM240-400q-33 0-56.5-23.5T160-480q0-33 23.5-56.5T240-560q33 0 56.5 23.5T320-480q0 33-23.5 56.5T240-400Zm240 0q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm240 0q-33 0-56.5-23.5T640-480q0-33 23.5-56.5T720-560q33 0 56.5 23.5T800-480q0 33-23.5 56.5T720-400ZM240-640q-33 0-56.5-23.5T160-720q0-33 23.5-56.5T240-800q33 0 56.5 23.5T320-720q0 33-23.5 56.5T240-640Zm240 0q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Zm240 0q-33 0-56.5-23.5T640-720q0-33 23.5-56.5T720-800q33 0 56.5 23.5T800-720q0 33-23.5 56.5T720-640Z"/></svg>`,
5784
- isolate: (g, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${g || 24} viewBox="0 -960 960 960" width="24"><path d="M440-760v-80h80v80h-80Zm0 640v-80h80v80h-80ZM280-760v-80h80v80h-80Zm0 640v-80h80v80h-80ZM120-760v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm480 0v-80h80v-560h-80v-80h240v80h-80v560h80v80H600Z"/></svg>`,
5785
- hide: (g, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${g || 24} viewBox="0 -960 960 960" width="24"><path d="M200-120q-33 0-56.5-23.5T120-200h80v80Zm-80-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160q0-33 23.5-56.5T200-840v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 0v-80h80v80h-80Zm60 640-56-56 142-142-142-142 56-56 142 142 142-142 56 56-142 142 142 142-56 56-142-142-142 142Zm100-640v-80h80v80h-80Zm160 160v-80h80v80h-80Zm0-160v-80q33 0 56.5 23.5T840-760h-80Z"/></svg>`,
5786
- focus: (g, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${g || 24} viewBox="0 -960 960 960" width="24"><path d="M120-120v-200h80v120h120v80H120Zm520 0v-80h120v-120h80v200H640ZM120-640v-200h200v80H200v120h-80Zm640 0v-120H640v-80h200v200h-80Z"/></svg>`,
5787
- properties: (g, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${g || 24} viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>`
5852
+ showAll: (f, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${f || 24} viewBox="0 -960 960 960" width="24"><path d="M240-160q-33 0-56.5-23.5T160-240q0-33 23.5-56.5T240-320q33 0 56.5 23.5T320-240q0 33-23.5 56.5T240-160Zm240 0q-33 0-56.5-23.5T400-240q0-33 23.5-56.5T480-320q33 0 56.5 23.5T560-240q0 33-23.5 56.5T480-160Zm240 0q-33 0-56.5-23.5T640-240q0-33 23.5-56.5T720-320q33 0 56.5 23.5T800-240q0 33-23.5 56.5T720-160ZM240-400q-33 0-56.5-23.5T160-480q0-33 23.5-56.5T240-560q33 0 56.5 23.5T320-480q0 33-23.5 56.5T240-400Zm240 0q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm240 0q-33 0-56.5-23.5T640-480q0-33 23.5-56.5T720-560q33 0 56.5 23.5T800-480q0 33-23.5 56.5T720-400ZM240-640q-33 0-56.5-23.5T160-720q0-33 23.5-56.5T240-800q33 0 56.5 23.5T320-720q0 33-23.5 56.5T240-640Zm240 0q-33 0-56.5-23.5T400-720q0-33 23.5-56.5T480-800q33 0 56.5 23.5T560-720q0 33-23.5 56.5T480-640Zm240 0q-33 0-56.5-23.5T640-720q0-33 23.5-56.5T720-800q33 0 56.5 23.5T800-720q0 33-23.5 56.5T720-640Z"/></svg>`,
5853
+ isolate: (f, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${f || 24} viewBox="0 -960 960 960" width="24"><path d="M440-760v-80h80v80h-80Zm0 640v-80h80v80h-80ZM280-760v-80h80v80h-80Zm0 640v-80h80v80h-80ZM120-760v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm0 160v-80h80v80h-80Zm480 0v-80h80v-560h-80v-80h240v80h-80v560h80v80H600Z"/></svg>`,
5854
+ hide: (f, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${f || 24} viewBox="0 -960 960 960" width="24"><path d="M200-120q-33 0-56.5-23.5T120-200h80v80Zm-80-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160q0-33 23.5-56.5T200-840v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 0v-80h80v80h-80Zm60 640-56-56 142-142-142-142 56-56 142 142 142-142 56 56-142 142 142 142-56 56-142-142-142 142Zm100-640v-80h80v80h-80Zm160 160v-80h80v80h-80Zm0-160v-80q33 0 56.5 23.5T840-760h-80Z"/></svg>`,
5855
+ focus: (f, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${f || 24} viewBox="0 -960 960 960" width="24"><path d="M120-120v-200h80v120h120v80H120Zm520 0v-80h120v-120h80v200H640ZM120-640v-200h200v80H200v120h-80Zm640 0v-120H640v-80h200v200h-80Z"/></svg>`,
5856
+ properties: (f, e) => `<svg xmlns="http://www.w3.org/2000/svg" fill=${e || ""} height=${f || 24} viewBox="0 -960 960 960" width="24"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>`
5788
5857
  };
5789
5858
  class Fs {
5790
5859
  constructor(e) {
@@ -5922,14 +5991,14 @@ class Fs {
5922
5991
  );
5923
5992
  if (!p || m < 0.3)
5924
5993
  continue;
5925
- const f = {
5994
+ const g = {
5926
5995
  elementId: u.elementId,
5927
5996
  modelId: u.modelId
5928
5997
  };
5929
5998
  this.isShiftPressed ? this.viralViewerApi.viralVisibilityManager.addToSelection(
5930
- [f]
5999
+ [g]
5931
6000
  ) : this.viralViewerApi.viralVisibilityManager.selectElements(
5932
- [f]
6001
+ [g]
5933
6002
  ), this.viralViewerApi.viralDraggableModal.updateModalContent(
5934
6003
  Number.parseInt(u.modelId),
5935
6004
  Number.parseInt(u.elementId)
@@ -5946,14 +6015,14 @@ class Fs {
5946
6015
  );
5947
6016
  if (!p || m < 0.3)
5948
6017
  continue;
5949
- const f = {
6018
+ const g = {
5950
6019
  elementId: d.elementId,
5951
6020
  modelId: d.modelId
5952
6021
  };
5953
6022
  this.isShiftPressed ? this.viralViewerApi.viralVisibilityManager.addToSelection(
5954
- [f]
6023
+ [g]
5955
6024
  ) : this.viralViewerApi.viralVisibilityManager.selectElements(
5956
- [f]
6025
+ [g]
5957
6026
  ), this.viralViewerApi.viralDraggableModal.updateModalContent(
5958
6027
  Number.parseInt(d.modelId),
5959
6028
  Number.parseInt(d.elementId)
@@ -6411,7 +6480,7 @@ class Zs {
6411
6480
  }
6412
6481
  const Ys = new Zs();
6413
6482
  function Xs() {
6414
- class g {
6483
+ class f {
6415
6484
  constructor() {
6416
6485
  this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
6417
6486
  }
@@ -6430,12 +6499,12 @@ function Xs() {
6430
6499
  const o = i.length, a = new Float32Array(o * 3), l = r ? -r.x : 0, c = r ? -r.y : 0, h = r ? -r.z : 0;
6431
6500
  if (n == null) {
6432
6501
  for (let p = 0; p < o; p++) {
6433
- const m = s[i[p]], f = p * 3;
6434
- a[f] = -m.X + l, a[f + 1] = m.Z + c, a[f + 2] = m.Y + h;
6502
+ const m = s[i[p]], g = p * 3;
6503
+ a[g] = -m.X + l, a[g + 1] = m.Z + c, a[g + 2] = m.Y + h;
6435
6504
  }
6436
6505
  return a;
6437
6506
  }
6438
- const d = new g();
6507
+ const d = new f();
6439
6508
  d.fromArray([
6440
6509
  n.BasisX.X,
6441
6510
  -n.BasisX.Z,
@@ -6457,8 +6526,8 @@ function Xs() {
6457
6526
  ]);
6458
6527
  const u = d.elements;
6459
6528
  for (let p = 0; p < o; p++) {
6460
- const m = s[i[p]], f = -m.X, v = m.Z, b = m.Y, w = 1 / (u[3] * f + u[7] * v + u[11] * b + u[15]), S = p * 3;
6461
- a[S] = (u[0] * f + u[4] * v + u[8] * b + u[12]) * w, a[S + 1] = (u[1] * f + u[5] * v + u[9] * b + u[13]) * w, a[S + 2] = (u[2] * f + u[6] * v + u[10] * b + u[14]) * w;
6529
+ const m = s[i[p]], g = -m.X, v = m.Z, b = m.Y, w = 1 / (u[3] * g + u[7] * v + u[11] * b + u[15]), S = p * 3;
6530
+ a[S] = (u[0] * g + u[4] * v + u[8] * b + u[12]) * w, a[S + 1] = (u[1] * g + u[5] * v + u[9] * b + u[13]) * w, a[S + 2] = (u[2] * g + u[6] * v + u[10] * b + u[14]) * w;
6462
6531
  }
6463
6532
  return a;
6464
6533
  }
@@ -6497,7 +6566,7 @@ function Xs() {
6497
6566
  }
6498
6567
  const Ks = Xs;
6499
6568
  function Js() {
6500
- class g {
6569
+ class f {
6501
6570
  constructor() {
6502
6571
  this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
6503
6572
  }
@@ -6516,12 +6585,12 @@ function Js() {
6516
6585
  const o = i.length, a = new Float32Array(o * 3), l = r ? -r.x : 0, c = r ? -r.y : 0, h = r ? -r.z : 0;
6517
6586
  if (n == null) {
6518
6587
  for (let p = 0; p < o; p++) {
6519
- const m = s[i[p]], f = p * 3;
6520
- a[f] = -m.X + l, a[f + 1] = m.Z + c, a[f + 2] = m.Y + h;
6588
+ const m = s[i[p]], g = p * 3;
6589
+ a[g] = -m.X + l, a[g + 1] = m.Z + c, a[g + 2] = m.Y + h;
6521
6590
  }
6522
6591
  return a;
6523
6592
  }
6524
- const d = new g();
6593
+ const d = new f();
6525
6594
  d.fromArray([
6526
6595
  n.BasisX.X,
6527
6596
  -n.BasisX.Z,
@@ -6543,8 +6612,8 @@ function Js() {
6543
6612
  ]);
6544
6613
  const u = d.elements;
6545
6614
  for (let p = 0; p < o; p++) {
6546
- const m = s[i[p]], f = -m.X, v = m.Z, b = m.Y, w = 1 / (u[3] * f + u[7] * v + u[11] * b + u[15]), S = p * 3;
6547
- a[S] = (u[0] * f + u[4] * v + u[8] * b + u[12]) * w, a[S + 1] = (u[1] * f + u[5] * v + u[9] * b + u[13]) * w, a[S + 2] = (u[2] * f + u[6] * v + u[10] * b + u[14]) * w;
6615
+ const m = s[i[p]], g = -m.X, v = m.Z, b = m.Y, w = 1 / (u[3] * g + u[7] * v + u[11] * b + u[15]), S = p * 3;
6616
+ a[S] = (u[0] * g + u[4] * v + u[8] * b + u[12]) * w, a[S + 1] = (u[1] * g + u[5] * v + u[9] * b + u[13]) * w, a[S + 2] = (u[2] * g + u[6] * v + u[10] * b + u[14]) * w;
6548
6617
  }
6549
6618
  return a;
6550
6619
  }
@@ -6896,8 +6965,8 @@ class tn {
6896
6965
  const c = [], h = [];
6897
6966
  let d = a, u = l;
6898
6967
  for (const p of n) {
6899
- const m = p.buffer ? p.buffer.length / 3 : 0, f = 1;
6900
- d + m <= s.maxVertices && u + f <= s.maxObjects ? (c.push(p), d += m, u += f) : h.push(p);
6968
+ const m = p.buffer ? p.buffer.length / 3 : 0, g = 1;
6969
+ d + m <= s.maxVertices && u + g <= s.maxObjects ? (c.push(p), d += m, u += g) : h.push(p);
6901
6970
  }
6902
6971
  if (c.length > 0 && (console.log(
6903
6972
  `✅ Batching ${c.length} elements in ONE call for material ${e}`
@@ -7273,10 +7342,10 @@ class cn extends Ot {
7273
7342
  }
7274
7343
  }
7275
7344
  function hn() {
7276
- const g = new di({
7345
+ const f = new di({
7277
7346
  side: ae
7278
7347
  });
7279
- return g.onBeforeCompile = (e) => {
7348
+ return f.onBeforeCompile = (e) => {
7280
7349
  e.vertexShader = `attribute vec4 color;
7281
7350
  varying float vAlpha;
7282
7351
  ` + e.vertexShader, e.vertexShader = e.vertexShader.replace(
@@ -7292,14 +7361,14 @@ function hn() {
7292
7361
  if (vAlpha < 0.01) discard;
7293
7362
  `
7294
7363
  );
7295
- }, g;
7364
+ }, f;
7296
7365
  }
7297
7366
  function dn() {
7298
- const g = new Y({
7367
+ const f = new Y({
7299
7368
  colorWrite: !1,
7300
7369
  side: ae
7301
7370
  });
7302
- return g.onBeforeCompile = (e) => {
7371
+ return f.onBeforeCompile = (e) => {
7303
7372
  e.vertexShader = `attribute vec4 color;
7304
7373
  varying float vAlpha;
7305
7374
  ` + e.vertexShader, e.vertexShader = e.vertexShader.replace(
@@ -7315,7 +7384,7 @@ function dn() {
7315
7384
  if (vAlpha < 0.01) discard;
7316
7385
  `
7317
7386
  );
7318
- }, g;
7387
+ }, f;
7319
7388
  }
7320
7389
  const un = {
7321
7390
  edgeColor: new N(0),
@@ -8916,11 +8985,11 @@ const Ht = new Float32Array([
8916
8985
  Qe.VISUAL_INSET = 2e-3;
8917
8986
  let It = Qe;
8918
8987
  var Ue = () => {
8919
- var g = 0, e = document.createElement("div");
8988
+ var f = 0, e = document.createElement("div");
8920
8989
  e.style.cssText = "position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000", e.addEventListener(
8921
8990
  "click",
8922
8991
  (c) => {
8923
- c.preventDefault(), i(++g % e.children.length);
8992
+ c.preventDefault(), i(++f % e.children.length);
8924
8993
  },
8925
8994
  !1
8926
8995
  );
@@ -8930,7 +8999,7 @@ var Ue = () => {
8930
8999
  function i(c) {
8931
9000
  for (var h = 0; h < e.children.length; h++)
8932
9001
  e.children[h].style.display = h === c ? "block" : "none";
8933
- g = c;
9002
+ f = c;
8934
9003
  }
8935
9004
  var s = (performance || Date).now(), n = s, r = 0, o = t(Ue.Panel("FPS", "#0ff", "#002")), a = t(Ue.Panel("MS", "#0f0", "#020"));
8936
9005
  if (self.performance && self.performance.memory)
@@ -8963,18 +9032,18 @@ var Ue = () => {
8963
9032
  setMode: i
8964
9033
  };
8965
9034
  };
8966
- Ue.Panel = (g, e, t) => {
9035
+ Ue.Panel = (f, e, t) => {
8967
9036
  var i = 1 / 0, s = 0, n = Math.round, r = n(window.devicePixelRatio || 1), o = 80 * r, a = 48 * r, l = 3 * r, c = 2 * r, h = 3 * r, d = 15 * r, u = 74 * r, p = 30 * r, m = document.createElement("canvas");
8968
9037
  m.width = o, m.height = a, m.style.cssText = "width:80px;height:48px";
8969
- var f = m.getContext("2d");
8970
- return f.font = "bold " + 9 * r + "px Helvetica,Arial,sans-serif", f.textBaseline = "top", f.fillStyle = t, f.fillRect(0, 0, o, a), f.fillStyle = e, f.fillText(g, l, c), f.fillRect(h, d, u, p), f.fillStyle = t, f.globalAlpha = 0.9, f.fillRect(h, d, u, p), {
9038
+ var g = m.getContext("2d");
9039
+ return g.font = "bold " + 9 * r + "px Helvetica,Arial,sans-serif", g.textBaseline = "top", g.fillStyle = t, g.fillRect(0, 0, o, a), g.fillStyle = e, g.fillText(f, l, c), g.fillRect(h, d, u, p), g.fillStyle = t, g.globalAlpha = 0.9, g.fillRect(h, d, u, p), {
8971
9040
  dom: m,
8972
9041
  update: (v, b) => {
8973
- i = Math.min(i, v), s = Math.max(s, v), f.fillStyle = t, f.globalAlpha = 1, f.fillRect(0, 0, o, d), f.fillStyle = e, f.fillText(
8974
- n(v) + " " + g + " (" + n(i) + "-" + n(s) + ")",
9042
+ i = Math.min(i, v), s = Math.max(s, v), g.fillStyle = t, g.globalAlpha = 1, g.fillRect(0, 0, o, d), g.fillStyle = e, g.fillText(
9043
+ n(v) + " " + f + " (" + n(i) + "-" + n(s) + ")",
8975
9044
  l,
8976
9045
  c
8977
- ), f.drawImage(
9046
+ ), g.drawImage(
8978
9047
  m,
8979
9048
  h + r,
8980
9049
  d,
@@ -8984,7 +9053,7 @@ Ue.Panel = (g, e, t) => {
8984
9053
  d,
8985
9054
  u - r,
8986
9055
  p
8987
- ), f.fillRect(h + u - r, d, r, p), f.fillStyle = t, f.globalAlpha = 0.9, f.fillRect(
9056
+ ), g.fillRect(h + u - r, d, r, p), g.fillStyle = t, g.globalAlpha = 0.9, g.fillRect(
8988
9057
  h + u - r,
8989
9058
  d,
8990
9059
  r,
@@ -9000,7 +9069,7 @@ class _n {
9000
9069
  }
9001
9070
  class In {
9002
9071
  constructor(e) {
9003
- this.viralViewerApi = e, this._selectionOutlineEnabled = !0, this.exceptElements = [], this.isolateModelId = "0", this.sunConfiguration = ss, this._ground = null, this._alphaSelectionOutlineEnabled = !1, this.opacity = 1, this._fog = new wi(13421772, 1, 1e3), this.rainGeometry = new he(), this.rain = null, this._isGeneratedRain = !1, this.ghostMode = !0, this._batchColors = /* @__PURE__ */ new Map(), this._originalBatchMaterials = /* @__PURE__ */ new Map(), this._batchVisualizationEnabled = !1, this.showHidePercentage = 100, this.randomColor = 100;
9072
+ this.viralViewerApi = e, this._selectionOutlineEnabled = !0, this.exceptElements = [], this.isolateModelId = "0", this.sunConfiguration = ss, this._ground = null, this._alphaSelectionOutlineEnabled = !1, this.opacity = 1, this._fog = new wi(13421772, 1, 1e3), this.rainGeometry = new he(), this.rain = null, this._isGeneratedRain = !1, this.ghostMode = !0, this._ghostColor = D.hexToRGB(y.edge), this._batchColors = /* @__PURE__ */ new Map(), this._originalBatchMaterials = /* @__PURE__ */ new Map(), this._batchVisualizationEnabled = !1, this.showHidePercentage = 100, this.randomColor = 100;
9004
9073
  }
9005
9074
  /**
9006
9075
  * show all elements and reset back to normal visualization
@@ -9040,12 +9109,14 @@ class In {
9040
9109
  /**
9041
9110
  *
9042
9111
  * @param elements default will get selected elements or we can input specific elements
9112
+ * @param ghostColor optional ghost color to use for this isolate operation
9043
9113
  */
9044
- isolate2(e) {
9114
+ isolate2(e, t) {
9045
9115
  if (this.ghostMode) {
9046
9116
  this.ghostExcept(
9047
9117
  e || this.viralViewerApi.viralScene.bimWorld.getSelectedElements(),
9048
- 0.101
9118
+ 0.101,
9119
+ t ?? this._ghostColor
9049
9120
  );
9050
9121
  return;
9051
9122
  }
@@ -9579,6 +9650,20 @@ class In {
9579
9650
  setGhostMode(e) {
9580
9651
  this.ghostMode = e;
9581
9652
  }
9653
+ /**
9654
+ * Set the default ghost color used by isolate2 and other ghost operations
9655
+ * @param color - Color {r, g, b} with values 0-1 (e.g., {r: 1, g: 1, b: 1} for white)
9656
+ * Pass undefined to use default desaturation
9657
+ */
9658
+ setGhostColor(e) {
9659
+ this._ghostColor = e;
9660
+ }
9661
+ /**
9662
+ * Get the current ghost color
9663
+ */
9664
+ getGhostColor() {
9665
+ return this._ghostColor;
9666
+ }
9582
9667
  /**
9583
9668
  * Set opacity for specific elements
9584
9669
  * @param elements - Elements to set opacity for
@@ -9591,17 +9676,19 @@ class In {
9591
9676
  * Set elements to "ghost" mode (semi-transparent)
9592
9677
  * @param elements - Elements to ghost
9593
9678
  * @param ghostOpacity - Opacity for ghosted elements (default 0.1)
9679
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
9594
9680
  */
9595
- setElementGhost(e, t = 0.1) {
9596
- this.viralViewerApi.viralScene.bimWorld.setElementGhost(e, t), this.viralViewerApi.viralRenderer.render();
9681
+ setElementGhost(e, t = 0.1, i) {
9682
+ this.viralViewerApi.viralScene.bimWorld.setElementGhost(e, t, i), this.viralViewerApi.viralRenderer.render();
9597
9683
  }
9598
9684
  /**
9599
9685
  * Ghost all elements EXCEPT the specified ones (highlight effect)
9600
9686
  * @param elements - Elements to keep fully opaque
9601
9687
  * @param ghostOpacity - Opacity for all other elements (default 0.1)
9688
+ * @param ghostColor - Optional custom color for ghosted elements (e.g., {r: 1, g: 1, b: 1} for white)
9602
9689
  */
9603
- ghostExcept(e, t = 0.1) {
9604
- e.length > 0 && (this.viralViewerApi.viralScene.bimWorld.ghostExcept(e, t), this.viralViewerApi.viralRenderer.render());
9690
+ ghostExcept(e, t = 0.1, i) {
9691
+ e.length > 0 && (this.viralViewerApi.viralScene.bimWorld.ghostExcept(e, t, i), this.viralViewerApi.viralRenderer.render());
9605
9692
  }
9606
9693
  /**
9607
9694
  * Reset all elements to full opacity
@@ -9922,11 +10009,11 @@ class Tn {
9922
10009
  const h = this.viralViewerApi.targetElement.getBoundingClientRect(), d = this.modal.getBoundingClientRect();
9923
10010
  let u = c.clientX - d.left, p = c.clientY - d.top;
9924
10011
  u = Math.max(this.minWidth, u), p = Math.max(this.minHeight, p);
9925
- const m = h.width - (d.left - h.left), f = Math.min(
10012
+ const m = h.width - (d.left - h.left), g = Math.min(
9926
10013
  h.height - (d.top - h.top),
9927
10014
  h.height - 20
9928
10015
  );
9929
- u = Math.min(u, m), p = Math.min(p, f), this.modal.style.width = u + "px", this.modal.style.height = p + "px";
10016
+ u = Math.min(u, m), p = Math.min(p, g), this.modal.style.width = u + "px", this.modal.style.height = p + "px";
9930
10017
  }
9931
10018
  if (this.isResizingColumns && this.modalBody) {
9932
10019
  const h = this.modalBody.getBoundingClientRect(), d = c.clientX - h.left, u = h.width, p = Math.max(
@@ -9983,17 +10070,17 @@ const ei = {
9983
10070
  importLink: "https://fonts.googleapis.com/css2?family=Quicksand:wght@300&display=swap",
9984
10071
  fontFamily: "Quicksand, sans-serif"
9985
10072
  }
9986
- }, Pn = (g) => {
10073
+ }, Pn = (f) => {
9987
10074
  const e = document.createElement("style");
9988
- e.innerHTML = `@import url(${ei[g]});`, document.head.appendChild(e);
9989
- }, On = (g, e) => {
10075
+ e.innerHTML = `@import url(${ei[f]});`, document.head.appendChild(e);
10076
+ }, On = (f, e) => {
9990
10077
  const t = ei[e];
9991
- g && t && (g.style.fontFamily = t.fontFamily);
10078
+ f && t && (f.style.fontFamily = t.fontFamily);
9992
10079
  };
9993
10080
  class Dn {
9994
10081
  constructor(e) {
9995
10082
  this.viralNavigationCube = e, this._mouseDownTime = null, this.clickThreshold = 250, this._handleClick = async (t) => {
9996
- var c, h, d, u, p, m, f, v, b, w, S, A, C, _, I, T, M, V, L, B, O, R, U, j, q, Q;
10083
+ var c, h, d, u, p, m, g, v, b, w, S, A, C, _, I, T, M, V, L, B, O, R, U, j, q, Q;
9997
10084
  if (!((c = this.viralNavigationCube.cubeScene) != null && c.activePlane) || (h = this.viralNavigationCube.cubeCamera) != null && h.cameraControlHasMoved)
9998
10085
  return console.log("false"), !1;
9999
10086
  let i = new E(
@@ -10003,7 +10090,7 @@ class Dn {
10003
10090
  );
10004
10091
  if (((m = this.viralNavigationCube.cubeScene) == null ? void 0 : m.activePlane.children.length) > 0) {
10005
10092
  let X = 0, W = 0, K = 0;
10006
- for (let Z = 0; Z < ((f = this.viralNavigationCube.cubeScene) == null ? void 0 : f.activePlane.children.length); Z++) {
10093
+ for (let Z = 0; Z < ((g = this.viralNavigationCube.cubeScene) == null ? void 0 : g.activePlane.children.length); Z++) {
10007
10094
  const G = (v = this.viralNavigationCube.cubeScene) == null ? void 0 : v.activePlane.children[Z];
10008
10095
  X += G.position.x, W += G.position.y, K += G.position.z;
10009
10096
  }
@@ -10042,7 +10129,7 @@ class Dn {
10042
10129
  !0
10043
10130
  );
10044
10131
  }, this._handleMouseUp = async (t) => {
10045
- var i, s, n, r, o, a, l, c, h, d, u, p, m, f, v, b, w, S, A, C, _, I, T, M, V, L;
10132
+ var i, s, n, r, o, a, l, c, h, d, u, p, m, g, v, b, w, S, A, C, _, I, T, M, V, L;
10046
10133
  if (console.log(this._mouseDownTime), this._mouseDownTime !== null && performance.now() - this._mouseDownTime < this.clickThreshold) {
10047
10134
  if (!((i = this.viralNavigationCube.cubeScene) != null && i.activePlane) || (s = this.viralNavigationCube.cubeCamera) != null && s.cameraControlHasMoved)
10048
10135
  return console.log("false"), !1;
@@ -10068,7 +10155,7 @@ class Dn {
10068
10155
  U
10069
10156
  );
10070
10157
  const j = R.clone().sub(U).normalize();
10071
- (w = (f = this.viralNavigationCube.cubeCamera) == null ? void 0 : f.cameraControlOldPosition) == null || w.copy(
10158
+ (w = (g = this.viralNavigationCube.cubeCamera) == null ? void 0 : g.cameraControlOldPosition) == null || w.copy(
10072
10159
  (b = (v = this.viralNavigationCube.cubeCamera) == null ? void 0 : v.camera) == null ? void 0 : b.position
10073
10160
  );
10074
10161
  const q = new E();
@@ -10102,7 +10189,7 @@ class Dn {
10102
10189
  }
10103
10190
  this._mouseDownTime = null;
10104
10191
  }, this.handleMove = async (t) => {
10105
- var c, h, d, u, p, m, f;
10192
+ var c, h, d, u, p, m, g;
10106
10193
  if ((c = this.viralNavigationCube.cubeScene) != null && c.activePlane) {
10107
10194
  this.viralNavigationCube.cubeScene.activePlane.material.opacity = 0, this.viralNavigationCube.cubeScene.activePlane.material.needsUpdate = !0;
10108
10195
  for (let v = 0; v < this.viralNavigationCube.cubeScene.activePlane.children.length; v++) {
@@ -10126,7 +10213,7 @@ class Dn {
10126
10213
  }
10127
10214
  } else
10128
10215
  this.viralNavigationCube.cubeScene.activePlane = l[0].object, this.viralNavigationCube.cubeScene.activePlane.material.opacity = 0.2, this.viralNavigationCube.cubeScene.activePlane.material.needsUpdate = !0;
10129
- (f = this.viralNavigationCube.cubeRenderer) == null || f.render();
10216
+ (g = this.viralNavigationCube.cubeRenderer) == null || g.render();
10130
10217
  }
10131
10218
  }, this.viralNavigationCube.cubeRenderer && (this._setupMouseClick(this.viralNavigationCube.cubeRenderer.renderer.domElement), this.setupMouseMove(this.viralNavigationCube.cubeRenderer.renderer.domElement));
10132
10219
  }
@@ -10253,8 +10340,8 @@ class kn {
10253
10340
  p.position.z = l, p.rotation.z = Math.PI / 2, p.position.y = -(i / 2 + n / 2);
10254
10341
  const m = new x(a, t.clone());
10255
10342
  m.position.z = l, m.position.x = -(i / 2 + n / 2), m.position.y = i / 2 + n / 2;
10256
- const f = new x(a, t.clone());
10257
- f.position.z = l, f.position.x = i / 2 + n / 2, f.position.y = i / 2 + n / 2;
10343
+ const g = new x(a, t.clone());
10344
+ g.position.z = l, g.position.x = i / 2 + n / 2, g.position.y = i / 2 + n / 2;
10258
10345
  const v = new x(a, t.clone());
10259
10346
  v.position.z = l, v.position.x = i / 2 + n / 2, v.position.y = -(i / 2 + n / 2);
10260
10347
  const b = new x(a, t.clone());
@@ -10380,7 +10467,7 @@ class kn {
10380
10467
  const Le = new x();
10381
10468
  Le.name = "corner1", Le.add(m), Le.add(Ie), Le.add(ye), this.addObject(Le);
10382
10469
  const ke = new x();
10383
- ke.name = "corner2", ke.add(f), ke.add(j), ke.add(_e), this.addObject(ke);
10470
+ ke.name = "corner2", ke.add(g), ke.add(j), ke.add(_e), this.addObject(ke);
10384
10471
  const Be = new x();
10385
10472
  Be.name = "corner3", Be.add(v), Be.add(X), Be.add(Oe), this.addObject(Be);
10386
10473
  const ze = new x();
@@ -11103,8 +11190,8 @@ class Ar extends $s {
11103
11190
  }
11104
11191
  };
11105
11192
  p.add(m, "ghostOpacity", 0, 1, 0.01).name("Ghost Opacity"), p.add(m, "elementOpacity", 0, 1, 0.01).name("Element Opacity"), p.add(m, "ghostSelected").name("Ghost Selected"), p.add(m, "ghostExceptSelected").name("Ghost Except Selected"), p.add(m, "setSelectedOpacity").name("Set Selected Opacity"), p.add(m, "resetOpacity").name("Reset All Opacity"), r.close();
11106
- const f = s.addFolder("Camera");
11107
- f.add(this.viralCamera, "enableOrthographicCamera"), f.add(this.viralCamera, "enablePerspectiveCamera"), f.add(this.viralCamera, "modelId"), f.add(this.viralCamera, "elementId"), f.add(this.viralCamera, "zoomTo");
11193
+ const g = s.addFolder("Camera");
11194
+ g.add(this.viralCamera, "enableOrthographicCamera"), g.add(this.viralCamera, "enablePerspectiveCamera"), g.add(this.viralCamera, "modelId"), g.add(this.viralCamera, "elementId"), g.add(this.viralCamera, "zoomTo");
11108
11195
  const v = s.addFolder("Data");
11109
11196
  v.add(this.viralDataManager, "searchValue"), v.add(this.viralDataManager, "searchElementData"), v.add(this.viralDataManager, "compareModels"), v.add(this.viralDataManager, "uncompareModels"), v.add(this.viralDataManager, "firstElementId"), v.add(this.viralDataManager, "secondElementId"), v.add(this.viralDataManager, "checkClash"), v.add(this.viralDataManager, "checkClashModels"), v.add(this.viralDataManager, "groupByKeyword"), v.add(this.viralDataManager, "groupBy");
11110
11197
  const b = s.addFolder("Section Box");